Contents

BNNSComputeNorm(_:_:_:_:)

Computes the specified norm over an entire tensor or the specified axes.

Declaration

func BNNSComputeNorm(_ dest: UnsafeMutablePointer<BNNSNDArrayDescriptor>, _ src: UnsafePointer<BNNSNDArrayDescriptor>, _ norm_type: BNNSNormType, _ axis_flags: UInt32) -> Int32

Parameters

  • dest:

    The descriptor of the output.

  • src:

    The descriptor of the input.

  • norm_type:

    The type of the norm. This function supports only Bnnsl2norm.

  • axis_flags:

    The dimensions that the function uses to compute the norm. Set to 0 to specify that the function computes the norm over all dimensions.

Discussion

Use this function to compute the norm of either an entire tensor or the axis or axes of a tensor.

For example, the following code defines a 3D tensor:

let inputData = UnsafeMutableBufferPointer<Float>.allocate(capacity: 24)
_ = inputData.initialize(from: [1, 2, 3,
                                4, 5, 6,
                                
                                10, 20, 30,
                                40, 50, 60,
                                
                                100, 200, 300,
                                400, 500, 600,
                                
                                1000, 2000, 3000,
                                4000, 5000, 6000])
var inputDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
                                            layout: BNNSDataLayoutImageCHW,
                                            size: (3, 2, 4, 0, 0, 0, 0, 0),
                                            stride: (0, 0, 0, 0, 0, 0, 0, 0),
                                            data: inputData.baseAddress!,
                                            data_type: BNNSDataType.float,
                                            table_data: nil,
                                            table_data_type: BNNSDataType.float,
                                            data_scale: 1, data_bias: 0)

Define the axis_flags parameter as either 0b111 or 0 to specify that the operation computes the norm of the entire tensor. In this case, the norm is a scalar value, and the destination’s data layout must be a BNNSDataLayoutVector with a size of 1.

let outputData = UnsafeMutableBufferPointer<Float>.allocate(capacity: 1)
var outputDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
                                             layout: BNNSDataLayoutVector,
                                             size: (1, 0, 0, 0, 0, 0, 0, 0),
                                             stride: (0, 0, 0, 0, 0, 0, 0, 0),
                                             data: outputData.baseAddress!,
                                             data_type: BNNSDataType.float,
                                             table_data: nil,
                                             table_data_type: BNNSDataType.float,
                                             data_scale: 1, data_bias: 0)

BNNSComputeNorm(&outputDescriptor,
                 &inputDescriptor,
                 BNNSL2Norm,
                 0b111)

// Prints `[9587.45]`
print(Array(outputData))

On return, the output descriptor contains a single value that is the square root of the sum of squares of each element in the tensor:

[Image]

Specify an axis_flags of 0b100 to compute the norm along the second axis. In this case, the destination should be a matrix with a size that matches the zeroth and first dimensions of the source tensor:

let outputData = UnsafeMutableBufferPointer<Float>.allocate(capacity: 6)
var outputDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
                                             layout: BNNSDataLayoutColumnMajorMatrix,
                                             size: (3, 2, 0, 0, 0, 0, 0, 0),
                                             stride: (0, 0, 0, 0, 0, 0, 0, 0),
                                             data: outputData.baseAddress!,
                                             data_type: BNNSDataType.float,
                                             table_data: nil,
                                             table_data_type: BNNSDataType.float,
                                             data_scale: 1, data_bias: 0)

BNNSComputeNorm(&outputDescriptor,
                 &inputDescriptor,
                 BNNSL2Norm,
                 0b100)

// Prints
//      [1005.0378, 2010.075, 3015.113,
//       4020.1511, 5025.189, 6030.227]
print(Array(outputData))

On return, the output descriptor contains six values that are the norms of the slices along the second axis of the input tensor:

[Image]

To compute the norm along more that one dimension, define the destination tensor with a size of the dimensions you’re not calculating over. For example, the following code defines an axis_flags with a value of 0b101 to compute the norm of dimensions zero and two:

let outputData = UnsafeMutableBufferPointer<Float>.allocate(capacity: 2)
var outputDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
                                             layout: BNNSDataLayoutVector,
                                             size: (2, 0, 0, 0, 0, 0, 0, 0),
                                             stride: (0, 0, 0, 0, 0, 0, 0, 0),
                                             data: outputData.baseAddress!,
                                             data_type: BNNSDataType.float,
                                             table_data: nil,
                                             table_data_type: BNNSDataType.float,
                                             data_scale: 1, data_bias: 0)

BNNSComputeNorm(&outputDescriptor,
                 &inputDescriptor,
                 BNNSL2Norm,
                 0b101)

// Prints `[3760.507, 8819.171]`
print(Array(outputData))

On return, the output descriptor contains two values that are the norms of the top and bottom slices of the input tensor:

[Image]

See Also

Compute norm functions