# GatherElements#

## GatherElements - 13#

Version

• domain: main

• since_version: 13

• function: False

• support_level: SupportType.COMMON

• shape inference: True

This version of the operator has been available since version 13.

Summary

GatherElements takes two inputs data and indices of the same rank r >= 1 and an optional attribute axis that identifies an axis of data (by default, the outer-most axis, that is axis 0). It is an indexing operation that produces its output by indexing into the input data tensor at index positions determined by elements of the indices tensor. Its output shape is the same as the shape of indices and consists of one value (gathered from the data) for each element in indices.

For instance, in the 3-D case (r = 3), the output produced is determined by the following equations:

```out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,
out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,
out[i][j][k] = input[i][j][index[i][j][k]] if axis = 2,
```

This operator is also the inverse of ScatterElements. It is similar to Torch’s gather operation.

Example 1:

```data = [
[1, 2],
[3, 4],
]
indices = [
[0, 0],
[1, 0],
]
axis = 1
output = [
[1, 1],
[4, 3],
]
```

Example 2:

```data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
indices = [
[1, 2, 0],
[2, 0, 0],
]
axis = 0
output = [
[4, 8, 3],
[7, 2, 3],
]
```

Attributes

• axis: Which axis to gather on. Negative value means counting dimensions from the back. Accepted range is [-r, r-1] where r = rank(data). Default value is `0`.

Inputs

• data (heterogeneous) - T: Tensor of rank r >= 1.

• indices (heterogeneous) - Tind: Tensor of int32/int64 indices, with the same rank r as the input. All index values are expected to be within bounds [-s, s-1] along axis of size s. It is an error if any of the index values are out of bounds.

Outputs

• output (heterogeneous) - T: Tensor of the same shape as indices.

Type Constraints

• T in ( tensor(bfloat16), tensor(bool), tensor(complex128), tensor(complex64), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input and output types to any tensor type.

• Tind in ( tensor(int32), tensor(int64) ): Constrain indices to integer types

Examples

_gather_elements_0

```axis = 1
node = onnx.helper.make_node(
"GatherElements",
inputs=["data", "indices"],
outputs=["y"],
axis=axis,
)
data = np.array([[1, 2], [3, 4]], dtype=np.float32)
indices = np.array([[0, 0], [1, 0]], dtype=np.int32)

y = gather_elements(data, indices, axis)
# print(y) produces
# [[1, 1],
#  [4, 3]]

expect(
node,
inputs=[data, indices.astype(np.int64)],
outputs=[y],
name="test_gather_elements_0",
)
```

_gather_elements_1

```axis = 0
node = onnx.helper.make_node(
"GatherElements",
inputs=["data", "indices"],
outputs=["y"],
axis=axis,
)
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32)
indices = np.array([[1, 2, 0], [2, 0, 0]], dtype=np.int32)

y = gather_elements(data, indices, axis)
# print(y) produces
# [[4, 8, 3],
#  [7, 2, 3]]

expect(
node,
inputs=[data, indices.astype(np.int64)],
outputs=[y],
name="test_gather_elements_1",
)
```

_gather_elements_negative_indices

```axis = 0
node = onnx.helper.make_node(
"GatherElements",
inputs=["data", "indices"],
outputs=["y"],
axis=axis,
)
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32)
indices = np.array([[-1, -2, 0], [-2, 0, 0]], dtype=np.int32)

y = gather_elements(data, indices, axis)
# print(y) produces
# [[7, 5, 3],
#  [4, 2, 3]]

expect(
node,
inputs=[data, indices.astype(np.int64)],
outputs=[y],
name="test_gather_elements_negative_indices",
)
```

Differences

 `0` `0` `GatherElements takes two inputs data and indices of the same rank r >= 1` `GatherElements takes two inputs data and indices of the same rank r >= 1` `1` `1` `and an optional attribute axis that identifies an axis of data` `and an optional attribute axis that identifies an axis of data` `2` `2` `(by default, the outer-most axis, that is axis 0). It is an indexing operation` `(by default, the outer-most axis, that is axis 0). It is an indexing operation` `3` `3` `that produces its output by indexing into the input data tensor at index` `that produces its output by indexing into the input data tensor at index` `4` `4` `positions determined by elements of the indices tensor.` `positions determined by elements of the indices tensor.` `5` `5` `Its output shape is the same as the shape of indices and consists of one value` `Its output shape is the same as the shape of indices and consists of one value` `6` `6` `(gathered from the data) for each element in indices.` `(gathered from the data) for each element in indices.` `7` `7` `8` `8` `For instance, in the 3-D case (r = 3), the output produced is determined` `For instance, in the 3-D case (r = 3), the output produced is determined` `9` `9` `by the following equations:` `by the following equations:` `10` `10` `::` `::` `11` `11` `12` `12` ` out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,` ` out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,` `13` `13` ` out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,` ` out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,` `14` `14` ` out[i][j][k] = input[i][j][index[i][j][k]] if axis = 2,` ` out[i][j][k] = input[i][j][index[i][j][k]] if axis = 2,` `15` `15` `16` `16` `This operator is also the inverse of ScatterElements. It is similar to Torch's gather operation.` `This operator is also the inverse of ScatterElements. It is similar to Torch's gather operation.` `17` `17` `18` `18` `Example 1:` `Example 1:` `19` `19` `::` `::` `20` `20` `21` `21` ` data = [` ` data = [` `22` `22` ` [1, 2],` ` [1, 2],` `23` `23` ` [3, 4],` ` [3, 4],` `24` `24` ` ]` ` ]` `25` `25` ` indices = [` ` indices = [` `26` `26` ` [0, 0],` ` [0, 0],` `27` `27` ` [1, 0],` ` [1, 0],` `28` `28` ` ]` ` ]` `29` `29` ` axis = 1` ` axis = 1` `30` `30` ` output = [` ` output = [` `31` ` [` `32` `31` ` [1, 1],` ` [1, 1],` `33` `32` ` [4, 3],` ` [4, 3],` `34` ` ],` `35` `33` ` ]` ` ]` `36` `34` `37` `35` `Example 2:` `Example 2:` `38` `36` `::` `::` `39` `37` `40` `38` ` data = [` ` data = [` `41` `39` ` [1, 2, 3],` ` [1, 2, 3],` `42` `40` ` [4, 5, 6],` ` [4, 5, 6],` `43` `41` ` [7, 8, 9],` ` [7, 8, 9],` `44` `42` ` ]` ` ]` `45` `43` ` indices = [` ` indices = [` `46` `44` ` [1, 2, 0],` ` [1, 2, 0],` `47` `45` ` [2, 0, 0],` ` [2, 0, 0],` `48` `46` ` ]` ` ]` `49` `47` ` axis = 0` ` axis = 0` `50` `48` ` output = [` ` output = [` `51` ` [` `52` `49` ` [4, 8, 3],` ` [4, 8, 3],` `53` `50` ` [7, 2, 3],` ` [7, 2, 3],` `54` ` ],` `55` `51` ` ]` ` ]` `56` `52` `57` `53` `**Attributes**` `**Attributes**` `58` `54` `59` `55` `* **axis**:` `* **axis**:` `60` `56` ` Which axis to gather on. Negative value means counting dimensions` ` Which axis to gather on. Negative value means counting dimensions` `61` `57` ` from the back. Accepted range is [-r, r-1] where r = rank(data). Default value is 0.` ` from the back. Accepted range is [-r, r-1] where r = rank(data). Default value is 0.` `62` `58` `63` `59` `**Inputs**` `**Inputs**` `64` `60` `65` `61` `* **data** (heterogeneous) - **T**:` `* **data** (heterogeneous) - **T**:` `66` `62` ` Tensor of rank r >= 1.` ` Tensor of rank r >= 1.` `67` `63` `* **indices** (heterogeneous) - **Tind**:` `* **indices** (heterogeneous) - **Tind**:` `68` `64` ` Tensor of int32/int64 indices, with the same rank r as the input.` ` Tensor of int32/int64 indices, with the same rank r as the input.` `69` `65` ` All index values are expected to be within bounds [-s, s-1] along` ` All index values are expected to be within bounds [-s, s-1] along` `70` `66` ` axis of size s. It is an error if any of the index values are out of` ` axis of size s. It is an error if any of the index values are out of` `71` `67` ` bounds.` ` bounds.` `72` `68` `73` `69` `**Outputs**` `**Outputs**` `74` `70` `75` `71` `* **output** (heterogeneous) - **T**:` `* **output** (heterogeneous) - **T**:` `76` `72` ` Tensor of the same shape as indices.` ` Tensor of the same shape as indices.` `77` `73` `78` `74` `**Type Constraints**` `**Type Constraints**` `79` `75` `80` `76` `* **T** in (` `* **T** in (` `77` ` tensor(bfloat16),` `81` `78` ` tensor(bool),` ` tensor(bool),` `82` `79` ` tensor(complex128),` ` tensor(complex128),` `83` `80` ` tensor(complex64),` ` tensor(complex64),` `84` `81` ` tensor(double),` ` tensor(double),` `85` `82` ` tensor(float),` ` tensor(float),` `86` `83` ` tensor(float16),` ` tensor(float16),` `87` `84` ` tensor(int16),` ` tensor(int16),` `88` `85` ` tensor(int32),` ` tensor(int32),` `89` `86` ` tensor(int64),` ` tensor(int64),` `90` `87` ` tensor(int8),` ` tensor(int8),` `91` `88` ` tensor(string),` ` tensor(string),` `92` `89` ` tensor(uint16),` ` tensor(uint16),` `93` `90` ` tensor(uint32),` ` tensor(uint32),` `94` `91` ` tensor(uint64),` ` tensor(uint64),` `95` `92` ` tensor(uint8)` ` tensor(uint8)` `96` `93` ` ):` ` ):` `97` `94` ` Constrain input and output types to any tensor type.` ` Constrain input and output types to any tensor type.` `98` `95` `* **Tind** in (` `* **Tind** in (` `99` `96` ` tensor(int32),` ` tensor(int32),` `100` `97` ` tensor(int64)` ` tensor(int64)` `101` `98` ` ):` ` ):` `102` `99` ` Constrain indices to integer types` ` Constrain indices to integer types`

## GatherElements - 11#

Version

• domain: main

• since_version: 11

• function: False

• support_level: SupportType.COMMON

• shape inference: True

This version of the operator has been available since version 11.

Summary

GatherElements takes two inputs data and indices of the same rank r >= 1 and an optional attribute axis that identifies an axis of data (by default, the outer-most axis, that is axis 0). It is an indexing operation that produces its output by indexing into the input data tensor at index positions determined by elements of the indices tensor. Its output shape is the same as the shape of indices and consists of one value (gathered from the data) for each element in indices.

For instance, in the 3-D case (r = 3), the output produced is determined by the following equations:

```out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,
out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,
out[i][j][k] = input[i][j][index[i][j][k]] if axis = 2,
```

This operator is also the inverse of ScatterElements. It is similar to Torch’s gather operation.

Example 1:

```data = [
[1, 2],
[3, 4],
]
indices = [
[0, 0],
[1, 0],
]
axis = 1
output = [
[
[1, 1],
[4, 3],
],
]
```

Example 2:

```data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
indices = [
[1, 2, 0],
[2, 0, 0],
]
axis = 0
output = [
[
[4, 8, 3],
[7, 2, 3],
],
]
```

Attributes

• axis: Which axis to gather on. Negative value means counting dimensions from the back. Accepted range is [-r, r-1] where r = rank(data). Default value is `0`.

Inputs

• data (heterogeneous) - T: Tensor of rank r >= 1.

• indices (heterogeneous) - Tind: Tensor of int32/int64 indices, with the same rank r as the input. All index values are expected to be within bounds [-s, s-1] along axis of size s. It is an error if any of the index values are out of bounds.

Outputs

• output (heterogeneous) - T: Tensor of the same shape as indices.

Type Constraints

• T in ( tensor(bool), tensor(complex128), tensor(complex64), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input and output types to any tensor type.

• Tind in ( tensor(int32), tensor(int64) ): Constrain indices to integer types