| 146 | } |
| 147 | |
| 148 | void Compute(OpKernelContext* c) override { |
| 149 | const Tensor& input = c->input(0); |
| 150 | const Tensor& indices = c->input(1); |
| 151 | const Tensor& updates = c->input(2); |
| 152 | |
| 153 | OP_REQUIRES(c, indices.shape().dims() >= 1, |
| 154 | errors::InvalidArgument( |
| 155 | "Indices shape must have rank at least one. Found:", |
| 156 | indices.shape().DebugString())); |
| 157 | OP_REQUIRES(c, updates.shape().dims() >= 1, |
| 158 | errors::InvalidArgument( |
| 159 | "Updates shape must have rank at least one. Found:", |
| 160 | updates.shape().DebugString())); |
| 161 | |
| 162 | TensorShape shape = input.shape(); |
| 163 | |
| 164 | OP_REQUIRES(c, |
| 165 | ValidEmptyOutputShape(shape.num_elements(), |
| 166 | indices.shape().num_elements(), |
| 167 | updates.shape().num_elements()), |
| 168 | errors::InvalidArgument( |
| 169 | "Indices and updates specified for empty output shape")); |
| 170 | |
| 171 | const int64 outer_dims = indices.shape().dims() - 1; |
| 172 | |
| 173 | for (int i = 0; i < outer_dims; ++i) { |
| 174 | OP_REQUIRES(c, indices.shape().dim_size(i) == updates.shape().dim_size(i), |
| 175 | errors::InvalidArgument( |
| 176 | "Outer dimensions of indices and update must match. " |
| 177 | "Indices shape: ", |
| 178 | indices.shape().DebugString(), |
| 179 | ", updates shape:", updates.shape().DebugString())); |
| 180 | } |
| 181 | |
| 182 | const int64 ix = indices.shape().dim_size(outer_dims); |
| 183 | OP_REQUIRES( |
| 184 | c, updates.shape().dims() - outer_dims == shape.dims() - ix, |
| 185 | errors::InvalidArgument("Inner dimensions of output shape must match " |
| 186 | "inner dimensions of updates shape. Output: ", |
| 187 | shape.DebugString(), |
| 188 | " updates: ", updates.shape().DebugString())); |
| 189 | for (int i = 0; i + outer_dims < updates.shape().dims(); ++i) { |
| 190 | OP_REQUIRES( |
| 191 | c, updates.shape().dim_size(i + outer_dims) == shape.dim_size(ix + i), |
| 192 | errors::InvalidArgument( |
| 193 | "The inner ", shape.dims() - ix, |
| 194 | " dimensions of output.shape=", shape.DebugString(), |
| 195 | " must match the inner ", updates.shape().dims() - outer_dims, |
| 196 | " dimensions of updates.shape=", updates.shape().DebugString())); |
| 197 | } |
| 198 | |
| 199 | std::unique_ptr<Tensor> forwarded_input = c->forward_input( |
| 200 | 0, 0, input.dtype(), shape, DEVICE_MEMORY, AllocatorAttributes()); |
| 201 | |
| 202 | if (forwarded_input == nullptr) { |
| 203 | // We were not able to forward the input, so we deep copy the tensor and |
| 204 | // set the output. |
| 205 | Tensor* out; |
nothing calls this directly
no test coverage detected