ScatterElementsUpdate¶
Versioned name: ScatterElementsUpdate-12
Category: Data movement
Short description: Creates a copy of the first input tensor with elements from updates
input applied according to the logic specified by reduction attribute and indices
along the axis
.
Detailed description: Creates copy of the first input tensor, and applies the elements of updates
according to the logic specified by reduction attribute. For each element of updates
, at the same index there is corresponding value of indices
, which is an index along dimension specified by axis
. The index for dimension pointed by axis
is provided by values of indices
input, otherwise, the index is the same as the index of the entry itself.
The dimensions of updates
tensor are allowed to be less or equal to the corresponding dimensions of data
tensor, but the dimension pointed by axis
can be also greater (especially if the indices
input contains duplicated values).
The operation to perform between the corresponding elements is specified by reduction attribute,
by default the elements of data
tensor are simply overwritten by the values from updates
input.
Additionally, use_init_val attribute can be used to control whether the elements from the data
input tensor are used as initial value (enabled by default).
General logic of output values calculations is presented below for 1D tensor case, the element corresponding to the [i]
is performed as:
output[indices[i]] = reduction(updates[i], output[indices[i]]), axis = 0
Overwrite without additional operation, reduction = “none”
output[indices[i]] = updates[i], axis = 0
Update by adding corresponding elements, reduction = “sum”
output[indices[i]] += updates[i], axis = 0
Update by multiplication of the corresponding elements, reduction = “prod”
output[indices[i]] *= updates[i], axis = 0
Update with minimum value of the corresponding elements, reduction = “min”
output[indices[i]] = min(updates[i], output[indices[i]]) axis = 0
Update with maximum value of the corresponding elements, reduction = “max”
output[indices[i]] = max(updates[i], output[indices[i]]) axis = 0
Update with mean value of the corresponding elements, reduction = “mean”. For integer types the calculated mean is rounded down (towards negative infinity). This reduction type is not supported for the boolean data type.
output[indices[i]] = mean(updates[i], output[indices[i]]) axis = 0
For 2D tensor case, the update of the element corresponding to the [i][j]
is performed as:
output[indices[i][j]][j] = reduction(updates[i][j], output[indices[i][j]][j]) if axis = 0
output[i][indices[i][j]] = reduction(updates[i][j], output[indices[i][j]][j]) if axis = 1
Accordingly for 3D tensor case, the update of the element corresponding to the [i][j][k]
is performed as:
output[indices[i][j][k]][j][k] = reduction(updates[i][j][k], output[indices[i][j][k]][j][k]) if axis = 0
output[i][indices[i][j][k]][k] = reduction(updates[i][j][k], output[i][indices[i][j][k]][k]) if axis = 1
output[i][j][indices[i][j][k]] = reduction(updates[i][j][k], output[i][j][indices[i][j][k]]) if axis = 2
Attributes:
reduction
Description: The type of operation to perform on the inputs.
Range of values: one of
none
,sum
,prod
,min
,max
,mean
Type: string
Default value:
none
Required: no
use_init_val
Description: Controls whether the elements in the data input tensor are used as init value for reduce operations.
Range of values: * true - data input elements are used * false - data input elements are not used
Type: boolean
Default value: true
Required: no
Note: The attribute has no effect for reduction == “none”
Inputs:
1:
data
tensor of arbitrary rankr
and of type T. Required.2:
indices
tensor with indices of type T_IND. The rank of the tensor is equal to the rank ofdata
tensor. All index values are expected to be within bounds[-d, d - 1]
along dimensiond
pointed byaxis
. If multiple indices point to the same output location then the order of updating the values is undefined. Negative value of index means reverse indexing and will be normalized to valuelen(data.shape[axis] + index)
. If an index points to non-existing element then exception is raised. Required.3:
updates
tensor of shape equal to the shape ofindices
tensor and of type T. Required.4:
axis
tensor with scalar or 1D tensor with one element of type T_AXIS specifying axis for scatter. Negativeaxis
means reverse indexing and will be normalized to valueaxis = data.rank + axis
. The value can be in range[-r, r - 1]
wherer
is the rank ofdata
. Required.
Outputs:
1: Tensor with shape equal to
data
tensor of the type T.
Types
T: any supported type.
T_IND: any integer numeric type.
T_AXIS: any integer numeric type.
For
boolean
type ofdata
input, reductionsum
,prod
behaves like logicalOR
,AND
accordingly, but there is no implementation forboolean
data type and reductionmean
.
Example
Example 1
<layer ... use_init_val="true" reduction="sum" type="ScatterElementsUpdate">
<input>
<port id="0">> <!-- data -->
<dim>4</dim> <!-- values: [2, 3, 4, 6] -->
</port>
<port id="1"> <!-- indices (negative values allowed) -->
<dim>6</dim> <!-- values: [1, 0, 0, -2, -1, 2] -->
</port>
<port id="2">> <!-- updates -->
<dim>6</dim> <!-- values: [10, 20, 30, 40, 70, 60] -->
</port>
<port id="3"> <!-- values: [0] -->
<dim>1</dim>
</port>
</input>
<output>
<port id="4" precision="FP32">
<dim>4</dim> <!-- values: [52, 13, 104, 76] -->
</port>
</output>
</layer>
Example 2
<layer ... use_init_val="false" reduction="sum" type="ScatterElementsUpdate">
<input>
<port id="0">> <!-- data -->
<dim>4</dim> <!-- values: [2, 3, 4, 6] -->
</port>
<port id="1"> <!-- indices -->
<dim>6</dim> <!-- values: [1, 0, 0, 2, 3, 2] -->
</port>
<port id="2">> <!-- updates -->
<dim>6</dim> <!-- values: [10, 20, 30, 40, 70, 60] -->
</port>
<port id="3"> <!-- values: [0] -->
<dim>1</dim>
</port>
</input>
<output>
<port id="4" precision="FP32">
<dim>4</dim> <!-- values: [50, 10, 100, 70] -->
</port>
</output>
</layer>
Example 3
<layer ... use_init_val="true" reduction="none" type="ScatterElementsUpdate">
<input>
<port id="0">> <!-- data -->
<dim>3</dim>
<dim>4</dim> <!-- values: [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]] -->
</port>
<port id="1"> <!-- indices -->
<dim>2</dim>
<dim>2</dim> <!-- values: [[1, 2],
[0, 3]] -->
</port>
<port id="2">> <!-- updates -->
<dim>2</dim>
<dim>2</dim> <!-- values: [[11, 12],
[13, 14]]) -->
</port>
<port id="3"> <!-- values: [1] -->
<dim>1</dim>
</port>
</input>
<output>
<port id="4" precision="I32">
<dim>3</dim>
<dim>4</dim> <!-- values: [[ 0, 11, 12, 0],
[13, 0, 0, 14],
[ 0, 0, 0, 0]] -->
</port>
</output>
</layer>
Example 4
<layer ... use_init_val="true" reduction="sum" type="ScatterElementsUpdate">
<input>
<port id="0">> <!-- data -->
<dim>3</dim>
<dim>4</dim> <!-- values: [[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]] -->
</port>
<port id="1"> <!-- indices -->
<dim>2</dim>
<dim>2</dim> <!-- values: [[1, 1],
[0, 3]] -->
</port>
<port id="2">> <!-- updates -->
<dim>2</dim>
<dim>2</dim> <!-- values: [[11, 12],
[13, 14]]) -->
</port>
<port id="3"> <!-- values: [1] -->
<dim>1</dim>
</port>
</input>
<output>
<port id="4" precision="I32">
<dim>3</dim>
<dim>4</dim> <!-- values: [[ 1, 24, 1, 1],
[14, 1, 1, 15],
[ 1, 1, 1, 1]] -->
</port>
</output>
</layer>
Example 5
<layer ... use_init_val="true" reduction="prod" type="ScatterElementsUpdate">
<input>
<port id="0">> <!-- data -->
<dim>3</dim>
<dim>4</dim> <!-- values: [[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2]] -->
</port>
<port id="1"> <!-- indices -->
<dim>2</dim>
<dim>2</dim> <!-- values: [[1, 1],
[0, 3]] -->
</port>
<port id="2">> <!-- updates -->
<dim>2</dim>
<dim>2</dim> <!-- values: [[11, 12],
[13, 14]]) -->
</port>
<port id="3"> <!-- values: [1] -->
<dim>1</dim>
</port>
</input>
<output>
<port id="4" precision="I32">
<dim>3</dim>
<dim>4</dim> <!-- values: [[ 2, 264, 2, 2],
[ 26, 2, 2, 28],
[ 2, 2, 2, 2]] -->
</port>
</output>
</layer>
Example 6
<layer ... type="ScatterElementsUpdate">
<input>
<port id="0">
<dim>1000</dim>
<dim>256</dim>
<dim>7</dim>
<dim>7</dim>
</port>
<port id="1">
<dim>125</dim>
<dim>20</dim>
<dim>7</dim>
<dim>6</dim>
</port>
<port id="2">
<dim>125</dim>
<dim>20</dim>
<dim>7</dim>
<dim>6</dim>
</port>
<port id="3"> <!-- values: [0] -->
<dim>1</dim>
</port>
</input>
<output>
<port id="4" precision="FP32">
<dim>1000</dim>
<dim>256</dim>
<dim>7</dim>
<dim>7</dim>
</port>
</output>
</layer>