Contents

BNNSScatterND(_:_:_:_:_:)

Scatters the slices of a tensor.

Declaration

func BNNSScatterND(_ op: BNNSReduceFunction, _ input: UnsafePointer<BNNSNDArrayDescriptor>, _ indices: UnsafePointer<BNNSNDArrayDescriptor>, _ output: UnsafeMutablePointer<BNNSNDArrayDescriptor>, _ filter_params: UnsafePointer<BNNSFilterParameters>?) -> Int32

Parameters

  • op:

    The reduction operation that defines how the function combines scattered values with existing output values.

  • input:

    A pointer to the input descriptor.

  • indices:

    A pointer to the indices descriptor.

  • output:

    A pointer to the output descriptor.

  • filter_params:

    The filter runtime parameters.

Discussion

Use BNNSScatterND(_:_:_:_:_:) to scatter slices — that you specify by index — into an output tensor.

The function interprets the indices array as a k - 1 dimensional set of lookup vectors, therefore, the indices tensor must have (k - 1) + 1 or k dimensions.

If the lookup vectors don’t define a full set of indices, the function treats the undefined indices as a slice.

BNNSScatterND(_:_:_:_:_:) is the inverse of BNNSGatherND(_:_:_:_:). The code samples below are based on the gathered values from the BNNSGatherND(_:_:_:_:) page.

The following code shows that a scalar index scatters a 2D slice:

let indices: [Int32] = [1] 
var indicesDescriptor = BNNSNDArrayDescriptor.allocate(
    initializingFrom: indices,
    shape: .vector(1))
    
let gathereredValues: [Float] = [20.0, 21.0, 22.0, 23.0]
var gatheredDescriptor = BNNSNDArrayDescriptor.allocate(
    initializingFrom: gathereredValues,
    shape: .matrixFirstMajor(2, 2))

var scatteredDescriptor = BNNSNDArrayDescriptor.allocate(
    repeating: Float(),
    shape: inputDescriptor.shape)

BNNSScatterND(BNNSReduceFunctionNone,
              &gatheredDescriptor,
              &indicesDescriptor,
              &scatteredDescriptor,
              nil)

On return, scatteredDescriptor contains the following values:

[ 0.0,  0.0,
  0.0,  0.0,

 20.0, 21.0,
 22.0, 23.0,

  0.0,  0.0,
  0.0,  0.0 ]

The following code shows that a 2D index scatters a 1D slice:

let indices: [Int32] = [1, 0] 
var indicesDescriptor = BNNSNDArrayDescriptor.allocate(
    initializingFrom: indices,
    shape: .matrixFirstMajor(1, 2))
    
let gathereredValues: [Float] = [20.0, 21.0]
var gatheredDescriptor = BNNSNDArrayDescriptor.allocate(
    initializingFrom: gathereredValues,
    shape: .matrixFirstMajor(1, 2))

var scatteredDescriptor = BNNSNDArrayDescriptor.allocate(
    repeating: Float(),
    shape: inputDescriptor.shape)

BNNSScatterND(BNNSReduceFunctionNone,
              &gatheredDescriptor,
              &indicesDescriptor,
              &scatteredDescriptor,
              nil)  

On return, scatteredDescriptor contains the following values:

[ 0.0,  0.0,
  0.0,  0.0,

 20.0, 21.0,
  0.0,  0.0,

  0.0,  0.0,
  0.0,  0.0 ]

The following code shows that a 3D index scatters a single element:

let indices: [Int32] = [
    1, 1, 1 
]
var indicesDescriptor = BNNSNDArrayDescriptor.allocate(
    initializingFrom: indices,
    shape: .tensor3DFirstMajor(1, 1, 3))

let gathereredValues: [Float] = [23]
var gatheredDescriptor = BNNSNDArrayDescriptor.allocate(
    initializingFrom: gathereredValues,
    shape: .matrixFirstMajor(1, 1))

var scatteredDescriptor = BNNSNDArrayDescriptor.allocate(
    repeating: Float(),
    shape: inputDescriptor.shape)

BNNSScatterND(BNNSReduceFunctionNone,
              &gatheredDescriptor,
              &indicesDescriptor,
              &scatteredDescriptor,
              nil)

On return, scatteredDescriptor contains the following values:

[ 0.0,  0.0,
  0.0,  0.0,

  0.0,  0.0,
  0.0, 23.0,

  0.0,  0.0,
  0.0,  0.0 ]

If multiple input values update the same output element, the function doesn’t define the order of update operations.

In particular, if you define the reduction as BNNSReduceFunctionNone the function doesn’t guarantee any particular value in the result.

See Also

Gather and scatter operations