For each input name in the forward op, check if we will need to add gradient accumulation. If so, do gradient accumulation and return the list of gradient operators. The criteria for doing gradient accumulation is: (1) the specific input version has been used by mult
(self, fwd_op_idx)
| 932 | return True |
| 933 | |
| 934 | def DoGradientAccumulation(self, fwd_op_idx): |
| 935 | """For each input name in the forward op, check if we will need to |
| 936 | add gradient accumulation. If so, do gradient accumulation and return |
| 937 | the list of gradient operators. |
| 938 | |
| 939 | The criteria for doing gradient accumulation is: |
| 940 | (1) the specific input version has been used by multiple operators. |
| 941 | (2) the current fwd_op_idx is the first to use that input, i.e. in the |
| 942 | backward pass, is the last to optionally generate the gradient for |
| 943 | the op. |
| 944 | (3) For the operators that used the input, their gradient operators |
| 945 | have generated more than 1 gradient. |
| 946 | |
| 947 | When accumulating operators, our current solution is to rename all the |
| 948 | created gradients with an internal intermediate name, and then add a |
| 949 | Sum() operator that adds up all the gradients. This may use more memory |
| 950 | due to intermediate storage, but is usually the fastest approach as one |
| 951 | can do one single sum for multiple intermediate gradients. |
| 952 | """ |
| 953 | forward_op, in_versions, out_versions = self.ssa[fwd_op_idx] |
| 954 | additional_sum_ops = [] |
| 955 | grad_map = {} |
| 956 | for _i, input_name in enumerate(set(forward_op.input)): |
| 957 | input_version = in_versions[input_name] |
| 958 | input_usage = self.input_usages[input_name][input_version] |
| 959 | if (len(input_usage) <= 1 or fwd_op_idx != input_usage[0]): |
| 960 | # We do not need to do gradient accumulation yet. |
| 961 | continue |
| 962 | generator = self.gradient_generators[input_name][input_version] |
| 963 | try: |
| 964 | if not self._VerifyGradientGenerators(generator): |
| 965 | continue |
| 966 | except RuntimeError as err: |
| 967 | raise RuntimeError( |
| 968 | "Gradients for param ''{}'' failed to verify: {}".format( |
| 969 | input_name, |
| 970 | err |
| 971 | ) |
| 972 | ) from err |
| 973 | |
| 974 | # Finally, let's create the sum operator. |
| 975 | sum_ops, g = self._MakeSumOps(input_name, input_version) |
| 976 | additional_sum_ops.extend(sum_ops) |
| 977 | grad_map[input_name] = g |
| 978 | return additional_sum_ops, grad_map |
| 979 | |
| 980 | def _AppendAutoGradGenerator(self, y, grad, autograd_op): |
| 981 | # Gradient here is not sparse as it was generated by |
no test coverage detected