| 52 | const ComputeOptions& options) = 0; |
| 53 | |
| 54 | void Compute(OpKernelContext* context) override { |
| 55 | const Tensor& input = context->input(0); |
| 56 | const Tensor& delta = context->input(1); |
| 57 | OP_REQUIRES(context, input.dims() >= 3, |
| 58 | errors::InvalidArgument("input must be at least 3-D, got shape", |
| 59 | input.shape().DebugString())); |
| 60 | OP_REQUIRES(context, TensorShapeUtils::IsScalar(delta.shape()), |
| 61 | errors::InvalidArgument("delta must be scalar: ", |
| 62 | delta.shape().DebugString())); |
| 63 | auto channels = input.dim_size(input.dims() - 1); |
| 64 | OP_REQUIRES( |
| 65 | context, channels == 3, |
| 66 | errors::InvalidArgument("input must have 3 channels but instead has ", |
| 67 | channels, " channels.")); |
| 68 | |
| 69 | Tensor* output = nullptr; |
| 70 | OP_REQUIRES_OK(context, context->forward_input_or_allocate_output( |
| 71 | {0}, 0, input.shape(), &output)); |
| 72 | |
| 73 | if (input.NumElements() > 0) { |
| 74 | const int64 channel_count = input.NumElements() / channels; |
| 75 | ComputeOptions options; |
| 76 | options.input = &input; |
| 77 | options.delta = δ |
| 78 | options.output = output; |
| 79 | options.channel_count = channel_count; |
| 80 | DoCompute(context, options); |
| 81 | } |
| 82 | } |
| 83 | }; |
| 84 | |
| 85 | template <class Device, typename T> |
nothing calls this directly
no test coverage detected