:nosearch: .. _op_ai_onnx_GatherND-12: GatherND - version 12 ===================== This page documents version **12** of operator **GatherND**. See :doc:`GatherND` for the latest version (since version 13). - **Domain**: ``ai.onnx`` - **Since version**: 12 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 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`` .. code-block:: text 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`` .. code-block:: text 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`` .. code-block:: text 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`` .. code-block:: text 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`` .. code-block:: text 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] **Inputs** - **data** (*T*): Tensor of rank r >= 1. - **indices** (*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** (*T*): Tensor of rank q + r - indices_shape[-1] - 1. **Attributes** - **batch_dims** (*int*): The number of batch dimensions. The gather of indexing starts from dimension of data[batch_dims:] **Type Constraints** - **T**: Constrain input and output types to any tensor type. Allowed types: 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). Differences with previous version (11) -------------------------------------- **SchemaDiff**: ``GatherND`` (domain ``'ai.onnx'``) * old version: 11 * new version: 12 * breaking: no **Attributes:** * added 'batch_dims': type=INT; required=False; default=0 **Documentation:** * line similarity: 0.67 (+39/-13 lines) .. code-block:: diff --- GatherND v11 +++ GatherND v12 @@ -1,38 +1,47 @@ -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`. +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 `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r` (inclusive) +2) The first `b` dimensions of the shape of `indices` tensor and `data` tensor must be equal. -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`. +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` => error condition +1) If `indices_shape[-1] > r-b` => 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) +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`, 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) +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] @@ -42,6 +51,8 @@ `Example 2` + batch_dims = 0 + data = [[0,1],[2,3]] # data_shape = [2, 2] indices = [[1],[0]] # indices_shape = [2, 1] @@ -49,6 +60,8 @@ 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] @@ -58,9 +71,22 @@ `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] + +