| 283 | int num_dims() const { return num_spatial_dims_ + 2; } |
| 284 | |
| 285 | void Compile(XlaOpKernelContext* ctx) override { |
| 286 | if (ctx->num_inputs() != 3) { |
| 287 | OP_REQUIRES( |
| 288 | ctx, ctx->num_inputs() == 5, |
| 289 | errors::InvalidArgument("Must supply ksize and stride arguments.")); |
| 290 | const TensorShape ksize_shape = ctx->InputShape(3); |
| 291 | // Validate input sizes. |
| 292 | OP_REQUIRES(ctx, TensorShapeUtils::IsVector(ksize_shape), |
| 293 | errors::InvalidArgument("ksize must be a vector, not shape ", |
| 294 | ksize_shape.DebugString())); |
| 295 | OP_REQUIRES_OK(ctx, ctx->ConstantInputAsIntVector(3, &ksize_)); |
| 296 | |
| 297 | const TensorShape stride_shape = ctx->InputShape(4); |
| 298 | // Validate input sizes. |
| 299 | OP_REQUIRES(ctx, TensorShapeUtils::IsVector(stride_shape), |
| 300 | errors::InvalidArgument("stride must be a vector, not shape ", |
| 301 | stride_shape.DebugString())); |
| 302 | OP_REQUIRES_OK(ctx, ctx->ConstantInputAsIntVector(4, &stride_)); |
| 303 | } |
| 304 | |
| 305 | OP_REQUIRES(ctx, ksize_.size() == num_dims(), |
| 306 | errors::InvalidArgument("Sliding window ksize field must " |
| 307 | "specify ", |
| 308 | num_dims(), " dimensions")); |
| 309 | OP_REQUIRES(ctx, stride_.size() == num_dims(), |
| 310 | errors::InvalidArgument("Sliding window strides field must " |
| 311 | "specify ", |
| 312 | num_dims(), " dimensions")); |
| 313 | |
| 314 | const TensorShape tensor_in_shape = ctx->InputShape(0); |
| 315 | const TensorShape tensor_out_shape = ctx->InputShape(1); |
| 316 | const TensorShape out_backprop_shape = ctx->InputShape(2); |
| 317 | |
| 318 | // For maxpooling, tensor_in should have num_dims() dimensions. |
| 319 | OP_REQUIRES(ctx, tensor_in_shape.dims() == num_dims(), |
| 320 | errors::InvalidArgument("tensor_in must be ", num_dims(), |
| 321 | "-dimensional")); |
| 322 | OP_REQUIRES(ctx, tensor_out_shape.dims() == num_dims(), |
| 323 | errors::InvalidArgument("tensor_out must be ", num_dims(), |
| 324 | "-dimensional")); |
| 325 | // For maxpooling, out_backprop should have num_dims() dimensions. |
| 326 | OP_REQUIRES(ctx, out_backprop_shape.dims() == num_dims(), |
| 327 | errors::InvalidArgument("out_backprop must be ", num_dims(), |
| 328 | "-dimensional")); |
| 329 | |
| 330 | // TODO(phawkins): The XLA version doesn't need tensor_out. Investigate |
| 331 | // whether this is a good time/space tradeoff. |
| 332 | auto input = ctx->Input(0); |
| 333 | auto out_backprop = ctx->Input(2); |
| 334 | |
| 335 | xla::Padding xla_padding = |
| 336 | (padding_ == VALID) ? xla::Padding::kValid : xla::Padding::kSame; |
| 337 | |
| 338 | // Create a MaxPool operation to check the expected resulting shape, and |
| 339 | // then throw away the operation because we don't actually neeed it here. |
| 340 | TensorShape expected_out_shape; |
| 341 | auto pooling = |
| 342 | xla::MaxPool(ctx->Input(0), ksize_, stride_, xla_padding, |
nothing calls this directly
no test coverage detected