For DDP mixed precision, put low precision copies on separate stream and create events to wait for them. When training with DDP mixed precision, this root pre-forward hook kicks off low precision copies on a separate stream and creates respective events to wait for
(self, *args: Any, **kwargs: Any)
| 966 | self.reducer._autograd_hook(idx) # type: ignore[attr-defined] |
| 967 | |
| 968 | def _root_copy_hook(self, *args: Any, **kwargs: Any) -> None: |
| 969 | """ |
| 970 | For DDP mixed precision, put low precision copies on separate stream and create events to wait for them. |
| 971 | |
| 972 | When training with DDP mixed precision, this root pre-forward hook kicks |
| 973 | off low precision copies on a separate stream and creates respective |
| 974 | events to wait for them. |
| 975 | """ |
| 976 | # Clear out previous iteration submodule to event. This is because we |
| 977 | # may have populated some events for modules that didn't end up being |
| 978 | # used. |
| 979 | self._submodule_to_event = defaultdict(deque) # type: ignore[var-annotated] |
| 980 | with torch.cuda.stream(self._mp_stream): |
| 981 | for submodule in self.module.modules(): |
| 982 | for param in submodule.parameters(recurse=False): |
| 983 | # Do not cast DDP ignored parameters. |
| 984 | if hasattr(param, "_ddp_ignored") and param._ddp_ignored: |
| 985 | continue |
| 986 | _alloc_storage(param._mp_param, param.size()) |
| 987 | # copy() implicitly casts to low precision |
| 988 | with torch.no_grad(): |
| 989 | param._mp_param.copy_(param.data) |
| 990 | # TODO: when zero_grad(set_to_none=False) or in grad |
| 991 | # accumulation case, accumulated grads can be in fp32 |
| 992 | # which can cause errors when running DDP backwards due |
| 993 | # to mismatched incoming and accumulated gradient types. |
| 994 | # So we manually cast the accumulated grad down for now, |
| 995 | # in the future we may shift to FSDP style gradient |
| 996 | # accumulation management where the accumulated gradient |
| 997 | # is saved and .grad field is set to None, bypassing |
| 998 | # this issue. |
| 999 | if param.grad is not None: |
| 1000 | param.grad.data = param.grad.to( |
| 1001 | self.mixed_precision.param_dtype # type: ignore[union-attr] |
| 1002 | ) |
| 1003 | param.data = param._mp_param |
| 1004 | copy_event = torch.cuda.Event() |
| 1005 | copy_event.record() |
| 1006 | self._submodule_to_event[submodule].append(copy_event) |
| 1007 | |
| 1008 | def _module_wait_for_copy_hook( |
| 1009 | self, |
nothing calls this directly
no test coverage detected