0  0  Given data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathers  Given data tensor of rank r >= 1, indices tensor of rank q >= 1, and batch_dims integer b, this operator gathers 
1  1  slices 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. 
2  2 


3  3  indices is an qdimensional integer tensor, best thought of as a (q1)dimensional tensor of indextuples into data,  indices is an qdimensional integer tensor, best thought of as a (q1)dimensional tensor of indextuples into data, 
4  4  where each element defines a slice of data  where each element defines a slice of data 
5  5 


6  6  batch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions of  batch_dims (denoted as b) is an integer indicating the number of batch dimensions, i.e the leading b number of dimensions of 
7  7  data 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. 
8  8 


9  9  Some salient points about the inputs' rank and shape:  Some salient points about the inputs' rank and shape: 
10  10 


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


13  13  2) 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. 
14  14 


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


17  17  4) The indices_shape[1] should have a value between 1 (inclusive) and rank rb (inclusive)  4) The indices_shape[1] should have a value between 1 (inclusive) and rank rb (inclusive) 
18  18 


19  19  5) All values in indices are expected to be within bounds [s, s1] 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, s1] along axis of size s (i.e.) data_shape[i] <= indices[...,i] <= data_shape[i]  1. 
20  20  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. 
21  21 


22  22  The output is computed as follows:  The output is computed as follows: 
23  23 


24  24  The output tensor is obtained by mapping each indextuple in the indices tensor to the corresponding slice of the input data.  The output tensor is obtained by mapping each indextuple in the indices tensor to the corresponding slice of the input data. 
25  25 


26  26  1) If indices_shape[1] > rb => error condition  1) If indices_shape[1] > rb => error condition 
27  27 


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


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


38  38  This operator is the inverse of ScatterND.  This operator is the inverse of ScatterND. 
39  39 


40  40  Example 1  Example 1 
41  41 


42  42  batch_dims = 0  batch_dims = 0 
43  43 


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


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


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


50  50  Example 2  Example 2 
51  51 


52  52  batch_dims = 0  batch_dims = 0 
53  53 


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


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


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


60  60  Example 3  Example 3 
61  61 


62  62  batch_dims = 0  batch_dims = 0 
63  63 


64  64  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] 
65  65 


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


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


70  70  Example 4  Example 4 
71  71 


72  72  batch_dims = 0  batch_dims = 0 
73  73 


74  74  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] 
75  75 


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


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


80  80  Example 5  Example 5 
81  81 


82  82  batch_dims = 1  batch_dims = 1 
83  83 


84  84  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] 
85  85 


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


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


90  90  **Attributes**  **Attributes** 
91  91 


92  92  * **batch_dims**:  * **batch_dims**: 
93  93  The number of batch dimensions. The gather of indexing starts from  The number of batch dimensions. The gather of indexing starts from 
94  94  dimension of data[batch_dims:] Default value is 0.  dimension of data[batch_dims:] Default value is 0. 
95  95 


96  96  **Inputs**  **Inputs** 
97  97 


98  98  * **data** (heterogeneous)  **T**:  * **data** (heterogeneous)  **T**: 
99  99  Tensor of rank r >= 1.  Tensor of rank r >= 1. 
100  100  * **indices** (heterogeneous)  **tensor(int64)**:  * **indices** (heterogeneous)  **tensor(int64)**: 
101  101  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 
102  102  bounds [s, s1] along axis of size s. It is an error if any of the  bounds [s, s1] along axis of size s. It is an error if any of the 
103  103  index values are out of bounds.  index values are out of bounds. 
104  104 


105  105  **Outputs**  **Outputs** 
106  106 


107  107  * **output** (heterogeneous)  **T**:  * **output** (heterogeneous)  **T**: 
108  108  Tensor of rank q + r  indices_shape[1]  1.  Tensor of rank q + r  indices_shape[1]  1. 
109  109 


110  110  **Type Constraints**  **Type Constraints** 
111  111 


112  112  * **T** in (  * **T** in ( 
 113   tensor(bfloat16), 
113  114  tensor(bool),  tensor(bool), 
114  115  tensor(complex128),  tensor(complex128), 
115  116  tensor(complex64),  tensor(complex64), 
116  117  tensor(double),  tensor(double), 
117  118  tensor(float),  tensor(float), 
118  119  tensor(float16),  tensor(float16), 
119  120  tensor(int16),  tensor(int16), 
120  121  tensor(int32),  tensor(int32), 
121  122  tensor(int64),  tensor(int64), 
122  123  tensor(int8),  tensor(int8), 
123  124  tensor(string),  tensor(string), 
124  125  tensor(uint16),  tensor(uint16), 
125  126  tensor(uint32),  tensor(uint32), 
126  127  tensor(uint64),  tensor(uint64), 
127  128  tensor(uint8)  tensor(uint8) 
128  129  ):  ): 
129  130  Constrain input and output types to any tensor type.  Constrain input and output types to any tensor type. 