(self)
| 2948 | return grad |
| 2949 | |
| 2950 | def _backward_post_hook(self): |
| 2951 | if is_functorch_transforming(): |
| 2952 | return |
| 2953 | if not self._running_engine_backward: |
| 2954 | # Check if loss scaling was required but not applied |
| 2955 | needs_scaler = False |
| 2956 | if isinstance(self.optimizer, ZeROOptimizer): |
| 2957 | needs_scaler = self.optimizer.needs_scaler() |
| 2958 | elif self.torch_autocast_z0_gradscaler is not None: |
| 2959 | needs_scaler = True |
| 2960 | elif self.amp_enabled(): |
| 2961 | needs_scaler = True |
| 2962 | |
| 2963 | if needs_scaler and not self._manual_backward_expected: |
| 2964 | # User called backward() directly without using engine.scale() or engine.backward() |
| 2965 | error_msg = ("Loss scaling is required for this configuration, but backward() was called " |
| 2966 | "directly without scaling the loss. Please use one of the following:" |
| 2967 | " 1. engine.backward(loss)" |
| 2968 | " 2. engine.scale(loss).backward()") |
| 2969 | if self.amp_enabled(): |
| 2970 | error_msg += " Note: AMP (NVIDIA Apex) only supports engine.backward(loss)." |
| 2971 | raise RuntimeError(error_msg) |
| 2972 | |
| 2973 | # Clear the flag for next backward |
| 2974 | self._manual_backward_expected = False |
| 2975 | |
| 2976 | self._backward_epilogue() |
| 2977 | |
| 2978 | @contextmanager |
| 2979 | def no_sync(self): |
nothing calls this directly
no test coverage detected