GatherND#

GatherND - 13#

Version

  • name: GatherND (GitHub)

  • 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

Given data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathers slices of data into an output tensor of rank q + r - indices_shape[-1] - 1 - b.

indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data, where each element defines a slice of data

batch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions of data tensor and indices are representing the batches, and the gather starts from the b+1 dimension.

Some salient points about the inputs’ rank and shape:

  1. r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q

  2. The first b dimensions of the shape of indices tensor and data tensor must be equal.

  3. b < min(q, r) is to be honored.

  4. The indices_shape[-1] should have a value between 1 (inclusive) and rank r-b (inclusive)

  5. All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[…,i] <= data_shape[i] - 1. It is an error if any of the index values are out of bounds.

The output is computed as follows:

The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.

  1. If indices_shape[-1] > r-b => error condition

  2. If indices_shape[-1] == r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensors containing 1-D tensors of dimension r-b, where N is an integer equals to the product of 1 and all the elements in the batch dimensions of the indices_shape. Let us think of each such r-b ranked tensor as indices_slice. Each scalar value corresponding to data[0:b-1,indices_slice] is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Example 1 below)

  3. If indices_shape[-1] < r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensor containing 1-D tensors of dimension < r-b. Let us think of each such tensors as indices_slice. Each tensor slice corresponding to data[0:b-1, indices_slice , :] is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Examples 2, 3, 4 and 5 below)

This operator is the inverse of ScatterND.

Example 1

batch_dims = 0

data = [[0,1],[2,3]] # data_shape = [2, 2]

indices = [[0,0],[1,1]] # indices_shape = [2, 2]

output = [0,3] # output_shape = [2]

Example 2

batch_dims = 0

data = [[0,1],[2,3]] # data_shape = [2, 2]

indices = [[1],[0]] # indices_shape = [2, 1]

output = [[2,3],[0,1]] # output_shape = [2, 2]

Example 3

batch_dims = 0

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[0,1],[1,0]] # indices_shape = [2, 2]

output = [[2,3],[4,5]] # output_shape = [2, 2]

Example 4

batch_dims = 0

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]

output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]

Example 5

batch_dims = 1

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[1],[0]] # indices_shape = [2, 1]

output = [[2,3],[4,5]] # output_shape = [2, 2]

Attributes

  • batch_dims: The number of batch dimensions. The gather of indexing starts from dimension of data[batch_dims:] Default value is 0.

Inputs

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

  • indices (heterogeneous) - tensor(int64): Tensor of rank q >= 1. 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 rank q + r - indices_shape[-1] - 1.

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.

Examples

_int32

node = onnx.helper.make_node(
    "GatherND",
    inputs=["data", "indices"],
    outputs=["output"],
)

data = np.array([[0, 1], [2, 3]], dtype=np.int32)
indices = np.array([[0, 0], [1, 1]], dtype=np.int64)
output = gather_nd_impl(data, indices, 0)
expected_output = np.array([0, 3], dtype=np.int32)
assert np.array_equal(output, expected_output)
expect(
    node,
    inputs=[data, indices],
    outputs=[output],
    name="test_gathernd_example_int32",
)

_float32

node = onnx.helper.make_node(
    "GatherND",
    inputs=["data", "indices"],
    outputs=["output"],
)

data = np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]], dtype=np.float32)
indices = np.array([[[0, 1]], [[1, 0]]], dtype=np.int64)
output = gather_nd_impl(data, indices, 0)
expected_output = np.array([[[2, 3]], [[4, 5]]], dtype=np.float32)
assert np.array_equal(output, expected_output)
expect(
    node,
    inputs=[data, indices],
    outputs=[output],
    name="test_gathernd_example_float32",
)

_int32_batchdim_1

node = onnx.helper.make_node(
    "GatherND",
    inputs=["data", "indices"],
    outputs=["output"],
    batch_dims=1,
)

data = np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]], dtype=np.int32)
indices = np.array([[1], [0]], dtype=np.int64)
output = gather_nd_impl(data, indices, 1)
expected_output = np.array([[2, 3], [4, 5]], dtype=np.int32)
assert np.array_equal(output, expected_output)
expect(
    node,
    inputs=[data, indices],
    outputs=[output],
    name="test_gathernd_example_int32_batch_dim1",
)

Differences

00Given data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathersGiven data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathers
11slices of data into an output tensor of rank q + r - indices_shape[-1] - 1 - b.slices of data into an output tensor of rank q + r - indices_shape[-1] - 1 - b.
22
33indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data,indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data,
44where each element defines a slice of datawhere each element defines a slice of data
55
66batch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions ofbatch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions of
77data tensor and indices are representing the batches, and the gather starts from the b+1 dimension.data tensor and indices are representing the batches, and the gather starts from the b+1 dimension.
88
99Some salient points about the inputs' rank and shape:Some salient points about the inputs' rank and shape:
1010
11111) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q1) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q
1212
13132) The first b dimensions of the shape of indices tensor and data tensor must be equal.2) The first b dimensions of the shape of indices tensor and data tensor must be equal.
1414
15153) b < min(q, r) is to be honored.3) b < min(q, r) is to be honored.
1616
17174) The indices_shape[-1] should have a value between 1 (inclusive) and rank r-b (inclusive)4) The indices_shape[-1] should have a value between 1 (inclusive) and rank r-b (inclusive)
1818
19195) All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[...,i] <= data_shape[i] - 1.5) All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[...,i] <= data_shape[i] - 1.
2020 It is an error if any of the index values are out of bounds. It is an error if any of the index values are out of bounds.
2121
2222The output is computed as follows:The output is computed as follows:
2323
2424The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.
2525
26261) If indices_shape[-1] > r-b => error condition1) If indices_shape[-1] > r-b => error condition
2727
28282) If indices_shape[-1] == r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensors2) If indices_shape[-1] == r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensors
2929 containing 1-D tensors of dimension r-b, where N is an integer equals to the product of 1 and all the elements in the batch dimensions containing 1-D tensors of dimension r-b, where N is an integer equals to the product of 1 and all the elements in the batch dimensions
3030 of the indices_shape. Let us think of each such r-b ranked tensor as indices_slice. Each *scalar value* corresponding to data[0:b-1,indices_slice] of the indices_shape. Let us think of each such r-b ranked tensor as indices_slice. Each *scalar value* corresponding to data[0:b-1,indices_slice]
3131 is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Example 1 below) is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Example 1 below)
3232
33333) If indices_shape[-1] < r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensor3) If indices_shape[-1] < r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensor
3434 containing 1-D tensors of dimension < r-b. Let us think of each such tensors as indices_slice. Each *tensor slice* corresponding containing 1-D tensors of dimension < r-b. Let us think of each such tensors as indices_slice. Each *tensor slice* corresponding
3535 to data[0:b-1, indices_slice , :] is filled into the corresponding location of the (q-b-1)-dimensional tensor to data[0:b-1, indices_slice , :] is filled into the corresponding location of the (q-b-1)-dimensional tensor
3636 to form the output tensor (Examples 2, 3, 4 and 5 below) to form the output tensor (Examples 2, 3, 4 and 5 below)
3737
3838This operator is the inverse of ScatterND.This operator is the inverse of ScatterND.
3939
4040Example 1Example 1
4141
4242 batch_dims = 0 batch_dims = 0
4343
4444 data = [[0,1],[2,3]] # data_shape = [2, 2] data = [[0,1],[2,3]] # data_shape = [2, 2]
4545
4646 indices = [[0,0],[1,1]] # indices_shape = [2, 2] indices = [[0,0],[1,1]] # indices_shape = [2, 2]
4747
4848 output = [0,3] # output_shape = [2] output = [0,3] # output_shape = [2]
4949
5050Example 2Example 2
5151
5252 batch_dims = 0 batch_dims = 0
5353
5454 data = [[0,1],[2,3]] # data_shape = [2, 2] data = [[0,1],[2,3]] # data_shape = [2, 2]
5555
5656 indices = [[1],[0]] # indices_shape = [2, 1] indices = [[1],[0]] # indices_shape = [2, 1]
5757
5858 output = [[2,3],[0,1]] # output_shape = [2, 2] output = [[2,3],[0,1]] # output_shape = [2, 2]
5959
6060Example 3Example 3
6161
6262 batch_dims = 0 batch_dims = 0
6363
6464 data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2] data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]
6565
6666 indices = [[0,1],[1,0]] # indices_shape = [2, 2] indices = [[0,1],[1,0]] # indices_shape = [2, 2]
6767
6868 output = [[2,3],[4,5]] # output_shape = [2, 2] output = [[2,3],[4,5]] # output_shape = [2, 2]
6969
7070Example 4Example 4
7171
7272 batch_dims = 0 batch_dims = 0
7373
7474 data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2] data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]
7575
7676 indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2] indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]
7777
7878 output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2] output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
7979
8080Example 5Example 5
8181
8282 batch_dims = 1 batch_dims = 1
8383
8484 data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2] data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]
8585
8686 indices = [[1],[0]] # indices_shape = [2, 1] indices = [[1],[0]] # indices_shape = [2, 1]
8787
8888 output = [[2,3],[4,5]] # output_shape = [2, 2] output = [[2,3],[4,5]] # output_shape = [2, 2]
8989
9090**Attributes****Attributes**
9191
9292* **batch_dims**:* **batch_dims**:
9393 The number of batch dimensions. The gather of indexing starts from The number of batch dimensions. The gather of indexing starts from
9494 dimension of data[batch_dims:] Default value is 0. dimension of data[batch_dims:] Default value is 0.
9595
9696**Inputs****Inputs**
9797
9898* **data** (heterogeneous) - **T**:* **data** (heterogeneous) - **T**:
9999 Tensor of rank r >= 1. Tensor of rank r >= 1.
100100* **indices** (heterogeneous) - **tensor(int64)**:* **indices** (heterogeneous) - **tensor(int64)**:
101101 Tensor of rank q >= 1. All index values are expected to be within Tensor of rank q >= 1. All index values are expected to be within
102102 bounds [-s, s-1] along axis of size s. It is an error if any of the bounds [-s, s-1] along axis of size s. It is an error if any of the
103103 index values are out of bounds. index values are out of bounds.
104104
105105**Outputs****Outputs**
106106
107107* **output** (heterogeneous) - **T**:* **output** (heterogeneous) - **T**:
108108 Tensor of rank q + r - indices_shape[-1] - 1. Tensor of rank q + r - indices_shape[-1] - 1.
109109
110110**Type Constraints****Type Constraints**
111111
112112* **T** in (* **T** in (
113 tensor(bfloat16),
113114 tensor(bool), tensor(bool),
114115 tensor(complex128), tensor(complex128),
115116 tensor(complex64), tensor(complex64),
116117 tensor(double), tensor(double),
117118 tensor(float), tensor(float),
118119 tensor(float16), tensor(float16),
119120 tensor(int16), tensor(int16),
120121 tensor(int32), tensor(int32),
121122 tensor(int64), tensor(int64),
122123 tensor(int8), tensor(int8),
123124 tensor(string), tensor(string),
124125 tensor(uint16), tensor(uint16),
125126 tensor(uint32), tensor(uint32),
126127 tensor(uint64), tensor(uint64),
127128 tensor(uint8) tensor(uint8)
128129 ): ):
129130 Constrain input and output types to any tensor type. Constrain input and output types to any tensor type.

GatherND - 12#

Version

  • name: GatherND (GitHub)

  • domain: main

  • since_version: 12

  • function: False

  • support_level: SupportType.COMMON

  • shape inference: True

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

Summary

Given data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathers slices of data into an output tensor of rank q + r - indices_shape[-1] - 1 - b.

indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data, where each element defines a slice of data

batch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions of data tensor and indices are representing the batches, and the gather starts from the b+1 dimension.

Some salient points about the inputs’ rank and shape:

  1. r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q

  2. The first b dimensions of the shape of indices tensor and data tensor must be equal.

  3. b < min(q, r) is to be honored.

  4. The indices_shape[-1] should have a value between 1 (inclusive) and rank r-b (inclusive)

  5. All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[…,i] <= data_shape[i] - 1. It is an error if any of the index values are out of bounds.

The output is computed as follows:

The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.

  1. If indices_shape[-1] > r-b => error condition

  2. If indices_shape[-1] == r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensors containing 1-D tensors of dimension r-b, where N is an integer equals to the product of 1 and all the elements in the batch dimensions of the indices_shape. Let us think of each such r-b ranked tensor as indices_slice. Each scalar value corresponding to data[0:b-1,indices_slice] is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Example 1 below)

  3. If indices_shape[-1] < r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensor containing 1-D tensors of dimension < r-b. Let us think of each such tensors as indices_slice. Each tensor slice corresponding to data[0:b-1, indices_slice , :] is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Examples 2, 3, 4 and 5 below)

This operator is the inverse of ScatterND.

Example 1

batch_dims = 0

data = [[0,1],[2,3]] # data_shape = [2, 2]

indices = [[0,0],[1,1]] # indices_shape = [2, 2]

output = [0,3] # output_shape = [2]

Example 2

batch_dims = 0

data = [[0,1],[2,3]] # data_shape = [2, 2]

indices = [[1],[0]] # indices_shape = [2, 1]

output = [[2,3],[0,1]] # output_shape = [2, 2]

Example 3

batch_dims = 0

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[0,1],[1,0]] # indices_shape = [2, 2]

output = [[2,3],[4,5]] # output_shape = [2, 2]

Example 4

batch_dims = 0

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]

output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]

Example 5

batch_dims = 1

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[1],[0]] # indices_shape = [2, 1]

output = [[2,3],[4,5]] # output_shape = [2, 2]

Attributes

  • batch_dims: The number of batch dimensions. The gather of indexing starts from dimension of data[batch_dims:] Default value is 0.

Inputs

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

  • indices (heterogeneous) - tensor(int64): Tensor of rank q >= 1. 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 rank q + r - indices_shape[-1] - 1.

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.

Differences

00Given data tensor of rank r >= 1, and indices tensor of rank q >= 1, this operator gathersGiven data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathers
11slices of data into an output tensor of rank q + r - indices_shape[-1] - 1.slices of data into an output tensor of rank q + r - indices_shape[-1] - 1 - b.
22
33indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data,indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data,
44where each element defines a slice of datawhere each element defines a slice of data
55
6batch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions of
7data tensor and indices are representing the batches, and the gather starts from the b+1 dimension.
8
69Some salient points about the inputs' rank and shape:Some salient points about the inputs' rank and shape:
710
8111) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q1) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q
912
132) The first b dimensions of the shape of indices tensor and data tensor must be equal.
14
153) b < min(q, r) is to be honored.
16
10172) The indices_shape[-1] should have a value between 1 (inclusive) and rank r (inclusive)4) The indices_shape[-1] should have a value between 1 (inclusive) and rank r-b (inclusive)
1118
12193) All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[...,i] <= data_shape[i] - 1.5) All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[...,i] <= data_shape[i] - 1.
1320 It is an error if any of the index values are out of bounds. It is an error if any of the index values are out of bounds.
1421
1522The output is computed as follows:The output is computed as follows:
1623
1724The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.
1825
19261) If indices_shape[-1] > r => error condition1) If indices_shape[-1] > r-b => error condition
2027
21282) If indices_shape[-1] == r, since the rank of indices is q, indices can be thought of as a (q-1)-dimensional tensor2) If indices_shape[-1] == r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensors
2229 containing 1-D tensors of dimension r. Let us think of each such r ranked tensor as indices_slice. containing 1-D tensors of dimension r-b, where N is an integer equals to the product of 1 and all the elements in the batch dimensions
23 Each *scalar value* corresponding to data[indices_slice] is filled into the corresponding location of the (q-1)-dimensional tensor
2430 to form the output tensor (Example 1 below) of the indices_shape. Let us think of each such r-b ranked tensor as indices_slice. Each *scalar value* corresponding to data[0:b-1,indices_slice]
31 is filled into the corresponding location of the (q-b-1)-dimensional tensor to form the output tensor (Example 1 below)
2532
26333) If indices_shape[-1] < r, since the rank of indices is q, indices can be thought of as a (q-1)-dimensional tensor3) If indices_shape[-1] < r-b, since the rank of indices is q, indices can be thought of as N (q-b-1)-dimensional tensor
2734 containing 1-D tensors of dimension < r. Let us think of each such tensors as indices_slice. containing 1-D tensors of dimension < r-b. Let us think of each such tensors as indices_slice. Each *tensor slice* corresponding
2835 Each *tensor slice* corresponding to data[indices_slice , :] is filled into the corresponding location of the (q-1)-dimensional tensor to data[0:b-1, indices_slice , :] is filled into the corresponding location of the (q-b-1)-dimensional tensor
2936 to form the output tensor (Examples 2, 3, and 4 below) to form the output tensor (Examples 2, 3, 4 and 5 below)
3037
3138This operator is the inverse of ScatterND.This operator is the inverse of ScatterND.
3239
3340Example 1Example 1
3441
42 batch_dims = 0
43
3544 data = [[0,1],[2,3]] # data_shape = [2, 2] data = [[0,1],[2,3]] # data_shape = [2, 2]
3645
3746 indices = [[0,0],[1,1]] # indices_shape = [2, 2] indices = [[0,0],[1,1]] # indices_shape = [2, 2]
3847
3948 output = [0,3] # output_shape = [2] output = [0,3] # output_shape = [2]
4049
4150Example 2Example 2
4251
52 batch_dims = 0
53
4354 data = [[0,1],[2,3]] # data_shape = [2, 2] data = [[0,1],[2,3]] # data_shape = [2, 2]
4455
4556 indices = [[1],[0]] # indices_shape = [2, 1] indices = [[1],[0]] # indices_shape = [2, 1]
4657
4758 output = [[2,3],[0,1]] # output_shape = [2, 2] output = [[2,3],[0,1]] # output_shape = [2, 2]
4859
4960Example 3Example 3
5061
62 batch_dims = 0
63
5164 data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2] data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]
5265
5366 indices = [[0,1],[1,0]] # indices_shape = [2, 2] indices = [[0,1],[1,0]] # indices_shape = [2, 2]
5467
5568 output = [[2,3],[4,5]] # output_shape = [2, 2] output = [[2,3],[4,5]] # output_shape = [2, 2]
5669
5770Example 4Example 4
5871
72 batch_dims = 0
73
5974 data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2] data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]
6075
6176 indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2] indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]
6277
6378 output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2] output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
6479
80Example 5
81
82 batch_dims = 1
83
84 data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]
85
86 indices = [[1],[0]] # indices_shape = [2, 1]
87
88 output = [[2,3],[4,5]] # output_shape = [2, 2]
89
90**Attributes**
91
92* **batch_dims**:
93 The number of batch dimensions. The gather of indexing starts from
94 dimension of data[batch_dims:] Default value is 0.
95
6596**Inputs****Inputs**
6697
6798* **data** (heterogeneous) - **T**:* **data** (heterogeneous) - **T**:
6899 Tensor of rank r >= 1. Tensor of rank r >= 1.
69100* **indices** (heterogeneous) - **tensor(int64)**:* **indices** (heterogeneous) - **tensor(int64)**:
70101 Tensor of rank q >= 1. All index values are expected to be within Tensor of rank q >= 1. All index values are expected to be within
71102 bounds [-s, s-1] along axis of size s. It is an error if any of the bounds [-s, s-1] along axis of size s. It is an error if any of the
72103 index values are out of bounds. index values are out of bounds.
73104
74105**Outputs****Outputs**
75106
76107* **output** (heterogeneous) - **T**:* **output** (heterogeneous) - **T**:
77108 Tensor of rank q + r - indices_shape[-1] - 1. Tensor of rank q + r - indices_shape[-1] - 1.
78109
79110**Type Constraints****Type Constraints**
80111
81112* **T** in (* **T** in (
82113 tensor(bool), tensor(bool),
83114 tensor(complex128), tensor(complex128),
84115 tensor(complex64), tensor(complex64),
85116 tensor(double), tensor(double),
86117 tensor(float), tensor(float),
87118 tensor(float16), tensor(float16),
88119 tensor(int16), tensor(int16),
89120 tensor(int32), tensor(int32),
90121 tensor(int64), tensor(int64),
91122 tensor(int8), tensor(int8),
92123 tensor(string), tensor(string),
93124 tensor(uint16), tensor(uint16),
94125 tensor(uint32), tensor(uint32),
95126 tensor(uint64), tensor(uint64),
96127 tensor(uint8) tensor(uint8)
97128 ): ):
98129 Constrain input and output types to any tensor type. Constrain input and output types to any tensor type.

GatherND - 11#

Version

  • name: GatherND (GitHub)

  • 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

Given data tensor of rank r >= 1, and indices tensor of rank q >= 1, this operator gathers slices of data into an output tensor of rank q + r - indices_shape[-1] - 1.

indices is an q-dimensional integer tensor, best thought of as a (q-1)-dimensional tensor of index-tuples into data, where each element defines a slice of data

Some salient points about the inputs’ rank and shape:

  1. r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks r and q

  2. The indices_shape[-1] should have a value between 1 (inclusive) and rank r (inclusive)

  3. All values in indices are expected to be within bounds [-s, s-1] along axis of size s (i.e.) -data_shape[i] <= indices[…,i] <= data_shape[i] - 1. It is an error if any of the index values are out of bounds.

The output is computed as follows:

The output tensor is obtained by mapping each index-tuple in the indices tensor to the corresponding slice of the input data.

  1. If indices_shape[-1] > r => error condition

  2. If indices_shape[-1] == r, since the rank of indices is q, indices can be thought of as a (q-1)-dimensional tensor containing 1-D tensors of dimension r. Let us think of each such r ranked tensor as indices_slice. Each scalar value corresponding to data[indices_slice] is filled into the corresponding location of the (q-1)-dimensional tensor to form the output tensor (Example 1 below)

  3. If indices_shape[-1] < r, since the rank of indices is q, indices can be thought of as a (q-1)-dimensional tensor containing 1-D tensors of dimension < r. Let us think of each such tensors as indices_slice. Each tensor slice corresponding to data[indices_slice , :] is filled into the corresponding location of the (q-1)-dimensional tensor to form the output tensor (Examples 2, 3, and 4 below)

This operator is the inverse of ScatterND.

Example 1

data = [[0,1],[2,3]] # data_shape = [2, 2]

indices = [[0,0],[1,1]] # indices_shape = [2, 2]

output = [0,3] # output_shape = [2]

Example 2

data = [[0,1],[2,3]] # data_shape = [2, 2]

indices = [[1],[0]] # indices_shape = [2, 1]

output = [[2,3],[0,1]] # output_shape = [2, 2]

Example 3

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[0,1],[1,0]] # indices_shape = [2, 2]

output = [[2,3],[4,5]] # output_shape = [2, 2]

Example 4

data = [[[0,1],[2,3]],[[4,5],[6,7]]] # data_shape = [2, 2, 2]

indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]

output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]

Inputs

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

  • indices (heterogeneous) - tensor(int64): Tensor of rank q >= 1. 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 rank q + r - indices_shape[-1] - 1.

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.