| 454 | REGISTER_GRADIENT_OP("StridedSlice", StridedSliceGradHelper); |
| 455 | |
| 456 | Status SliceGrad(const Scope& scope, const Operation& op, |
| 457 | const std::vector<Output>& grad_inputs, |
| 458 | std::vector<Output>* grad_outputs) { |
| 459 | // Propagate the incoming gradient along all the selected values, |
| 460 | // and zero everywhere else. Use the Pad operator for this. |
| 461 | // |
| 462 | // First create an Nx2 padding where N is the number of input |
| 463 | // dimensions. The first column is the number of prepended zeros |
| 464 | // for each dimension, and the second column is the number of |
| 465 | // appended zeros. |
| 466 | // |
| 467 | // The first column is just the begin vector. |
| 468 | // The second column is the shape of the input element-wise |
| 469 | // subtracted by begin+size |
| 470 | |
| 471 | // Running example: |
| 472 | // input.shape = [3, 5, 3] |
| 473 | // begin = [1, 2, 1], size = [1, 3, 2] |
| 474 | Input input = op.input(0); |
| 475 | Input begin = op.input(1); |
| 476 | // input_rank = 3 |
| 477 | auto input_rank = Rank(scope, input); |
| 478 | // slice_size = [1, 3, 2] |
| 479 | auto slice_size = Shape(scope, op.output(0)); |
| 480 | // padding_shape = [3, 1] |
| 481 | auto padding_shape = Stack(scope, {input_rank, 1}); |
| 482 | // before_padding = [[1] |
| 483 | // [2] |
| 484 | // [1]] |
| 485 | Input before_padding = Reshape(scope, begin, padding_shape); |
| 486 | // after_padding_sizes = shape(input) - slice_size - begin |
| 487 | // = [3, 5, 3] - [1, 3, 2] - [1, 2, 1] |
| 488 | // = [1, 0, 0] |
| 489 | auto after_padding_sizes = |
| 490 | Sub(scope, Sub(scope, Shape(scope, input), slice_size), begin); |
| 491 | // after_padding = [[1] |
| 492 | // [0] |
| 493 | // [0]] |
| 494 | Input after_padding = Reshape(scope, after_padding_sizes, padding_shape); |
| 495 | // paddings = [[1 1] |
| 496 | // [2 0] |
| 497 | // [1 0]] |
| 498 | auto paddings = |
| 499 | Concat(scope, {before_padding, after_padding}, Const(scope, 1)); |
| 500 | grad_outputs->push_back(Pad(scope, grad_inputs[0], paddings)); |
| 501 | // Nothing propagated for "begin" and "size" inputs |
| 502 | grad_outputs->push_back(NoGradient()); |
| 503 | grad_outputs->push_back(NoGradient()); |
| 504 | return scope.status(); |
| 505 | } |
| 506 | REGISTER_GRADIENT_OP("Slice", SliceGrad); |
| 507 | |
| 508 | Status ConcatGradHelper(const Scope& scope, const Operation& op, |
nothing calls this directly
no test coverage detected