| 303 | |
| 304 | template <bool IsPadV2> |
| 305 | Status PadGrad(const Scope& scope, const Operation& op, |
| 306 | const std::vector<Output>& grad_inputs, |
| 307 | std::vector<Output>* grad_outputs) { |
| 308 | auto x = op.input(0); |
| 309 | auto a = op.input(1); // [Rank(x), 2] |
| 310 | // Takes a slice of a. The 1st column. [Rank(x), 1]. |
| 311 | auto size = Stack(scope, {Rank(scope, x), 1}); |
| 312 | auto pad_before = Slice(scope, a, {0, 0}, size); |
| 313 | // Make it a 1-D tensor. |
| 314 | auto begin = Reshape(scope, pad_before, {-1}); |
| 315 | grad_outputs->push_back(Slice(scope, grad_inputs[0], begin, Shape(scope, x))); |
| 316 | grad_outputs->push_back(NoGradient()); |
| 317 | // PadV2 adds a "constant_values" input. |
| 318 | if (IsPadV2) { |
| 319 | grad_outputs->push_back(NoGradient()); |
| 320 | } |
| 321 | return scope.status(); |
| 322 | } |
| 323 | REGISTER_GRADIENT_OP("Pad", PadGrad<false>); |
| 324 | REGISTER_GRADIENT_OP("PadV2", PadGrad<true>); |
| 325 | |