| 509 | } |
| 510 | |
| 511 | void Compute(OpKernelContext* context) override { |
| 512 | const Tensor& tensor_in_shape = context->input(0); |
| 513 | const Tensor& out_backprop = context->input(1); |
| 514 | OP_REQUIRES( |
| 515 | context, |
| 516 | tensor_in_shape.dims() == 1 && tensor_in_shape.NumElements() == 5, |
| 517 | errors::InvalidArgument("tensor_in must be 1-dimensional and 5 " |
| 518 | "elements")); |
| 519 | OP_REQUIRES(context, out_backprop.dims() == 5, |
| 520 | errors::InvalidArgument("out_backprop must be 5-dimensional")); |
| 521 | |
| 522 | TensorShape output_shape; |
| 523 | auto shape_vec = tensor_in_shape.vec<int32>(); |
| 524 | for (int64 i = 0; i < tensor_in_shape.NumElements(); ++i) { |
| 525 | output_shape.AddDim(shape_vec(i)); |
| 526 | } |
| 527 | |
| 528 | Tensor* output; |
| 529 | OP_REQUIRES_OK(context, context->allocate_output(0, output_shape, &output)); |
| 530 | |
| 531 | // Dimension order for these arrays is x, y, z. |
| 532 | std::array<int64, 3> input_size{ |
| 533 | {GetTensorDim(output_shape, data_format_, '2'), |
| 534 | GetTensorDim(output_shape, data_format_, '1'), |
| 535 | GetTensorDim(output_shape, data_format_, '0')}}; |
| 536 | std::array<int64, 3> window{{GetTensorDim(ksize_, data_format_, '2'), |
| 537 | GetTensorDim(ksize_, data_format_, '1'), |
| 538 | GetTensorDim(ksize_, data_format_, '0')}}; |
| 539 | std::array<int64, 3> stride{{GetTensorDim(stride_, data_format_, '2'), |
| 540 | GetTensorDim(stride_, data_format_, '1'), |
| 541 | GetTensorDim(stride_, data_format_, '0')}}; |
| 542 | std::array<int64, 3> padding, out; |
| 543 | |
| 544 | OP_REQUIRES_OK(context, Get3dOutputSize(input_size, window, stride, |
| 545 | padding_, &out, &padding)); |
| 546 | |
| 547 | LaunchAvgPooling3dGradOp<Device, T>::launch( |
| 548 | context, output_shape, out_backprop, window, stride, out, padding, |
| 549 | data_format_, output); |
| 550 | } |
| 551 | |
| 552 | private: |
| 553 | std::vector<int32> ksize_; |
nothing calls this directly
no test coverage detected