Creates the main backprop loop that computes the gradient of the loop associated with `while_ctx`. `grad_inputs` are the partial derivatives w.r.t. the loop outputs, i.e. the exit nodes. `backprop_execution_pred` is the predicate to use for the backprop loop (see AddBackPropLoopCounter()). The partial derivatives w.r.t. the loop inputs, i.e. the input loop vars, are returned in `grad_outputs`.
| 134 | // The partial derivatives w.r.t. the loop inputs, i.e. the input loop vars, are |
| 135 | // returned in `grad_outputs`. |
| 136 | Status AddWhileGradientLoop(WhileContext* while_ctx, |
| 137 | const std::vector<Output>& grad_inputs, |
| 138 | const Output& backprop_execution_pred, |
| 139 | const Scope& parent_scope, |
| 140 | std::vector<Output>* grad_outputs) { |
| 141 | DCHECK_EQ(grad_inputs.size(), while_ctx->body_outputs().size()); |
| 142 | DCHECK_EQ(while_ctx->body_inputs().size(), while_ctx->body_outputs().size()); |
| 143 | |
| 144 | Scope scope = parent_scope.NewSubScope("while"); |
| 145 | |
| 146 | // Create while loop: |
| 147 | // while backprop_execution_pred: |
| 148 | // forward loop body gradient |
| 149 | |
| 150 | // Condition function that returns 'backprop_execution_pred'. |
| 151 | CondGraphBuilderFn cond_fn = [backprop_execution_pred]( |
| 152 | const Scope& scope, |
| 153 | const std::vector<Output>& inputs, |
| 154 | Output* output) { |
| 155 | *output = backprop_execution_pred; |
| 156 | return Status::OK(); |
| 157 | }; |
| 158 | |
| 159 | // Body function that builds while body gradient subgraph. |
| 160 | BodyGraphBuilderFn body_fn = [while_ctx](const Scope& scope, |
| 161 | const std::vector<Output>& inputs, |
| 162 | std::vector<Output>* outputs) { |
| 163 | std::vector<Output> body_outputs = |
| 164 | ToOutputVector(while_ctx->body_outputs()); |
| 165 | std::vector<Output> body_inputs = ToOutputVector(while_ctx->body_inputs()); |
| 166 | return AddSymbolicGradients(scope, body_outputs, body_inputs, inputs, |
| 167 | outputs); |
| 168 | }; |
| 169 | |
| 170 | string frame_name = BackPropFrameName(while_ctx->frame_name()); |
| 171 | TF_RETURN_IF_ERROR(BuildWhileLoop(scope, grad_inputs, cond_fn, body_fn, |
| 172 | frame_name, grad_outputs, |
| 173 | /* create_while_ctx */ false)); |
| 174 | return Status::OK(); |
| 175 | } |
| 176 | |
| 177 | } // namespace |
| 178 |
no test coverage detected