(
self, forward_op_idx, input_to_grad)
| 1015 | return input_to_grad, gradient_ops |
| 1016 | |
| 1017 | def _GenerateGradientsForForwardOp( |
| 1018 | self, forward_op_idx, input_to_grad): |
| 1019 | new_input_to_grad = {} |
| 1020 | gradient_ops = [] |
| 1021 | forward_op, in_versions, out_versions = self.ssa[forward_op_idx] |
| 1022 | g_output = list( |
| 1023 | input_to_grad.get(name, None) for name in forward_op.output) |
| 1024 | |
| 1025 | if not all(g is None for g in g_output) or ( |
| 1026 | forward_op.type == "ZeroGradient"): |
| 1027 | gradient_ops, g_input = GradientRegistry.GetGradientForOp( |
| 1028 | forward_op, g_output) |
| 1029 | # Check if the gradient operators are legal, and update |
| 1030 | # gradient_generators and gradient_frontier |
| 1031 | self.BuildGradientGenerators( |
| 1032 | forward_op_idx, gradient_ops, g_output, g_input) |
| 1033 | # Record the gradient map to all_input_to_grad. |
| 1034 | for name, grad in zip(forward_op.input, g_input): |
| 1035 | # Do not overwrite an existing gradient with a None |
| 1036 | # unless the input is also an output of the op, since |
| 1037 | # we update the blob version when blob is output of an |
| 1038 | # operator. |
| 1039 | if grad is not None or \ |
| 1040 | name not in input_to_grad or \ |
| 1041 | name in list(forward_op.output): |
| 1042 | new_input_to_grad[name] = grad |
| 1043 | |
| 1044 | return new_input_to_grad, gradient_ops |
| 1045 | |
| 1046 | def GetBackwardPass(self, ys): |
| 1047 | """Gets the backward pass that computes the derivatives of given blobs. |
no test coverage detected