( # type: ignore
ctx: Any,
dummy_tensor_requires_grad: torch.Tensor,
run_function: Any,
parent_ctx_dict: Dict[str, Any],
kwarg_keys: Tuple[str, ...],
*args: Any,
**kwargs: Any
)
| 416 | |
| 417 | @staticmethod |
| 418 | def forward( # type: ignore |
| 419 | ctx: Any, |
| 420 | dummy_tensor_requires_grad: torch.Tensor, |
| 421 | run_function: Any, |
| 422 | parent_ctx_dict: Dict[str, Any], |
| 423 | kwarg_keys: Tuple[str, ...], |
| 424 | *args: Any, |
| 425 | **kwargs: Any |
| 426 | ) -> Any: |
| 427 | torch_checkpoint.check_backward_validity(args) |
| 428 | |
| 429 | ctx.run_function = run_function |
| 430 | ctx.kwarg_keys = kwarg_keys |
| 431 | ctx.fwd_rng_state = get_rng_state() |
| 432 | ctx.had_autocast_in_fwd = is_autocast_enabled() |
| 433 | |
| 434 | tensor_inputs, packed_non_tensor_inputs = split_non_tensors(args) |
| 435 | if parent_ctx_dict["offload"]: |
| 436 | ctx.fwd_device = tuple(x.device for x in tensor_inputs) |
| 437 | ctx.grad_requirements = tuple(x.requires_grad for x in tensor_inputs) |
| 438 | tensor_inputs = tuple(x.to("cpu", non_blocking=True) for x in tensor_inputs) |
| 439 | else: |
| 440 | ctx.fwd_device, ctx.grad_requirements = None, None |
| 441 | |
| 442 | ctx.save_for_backward(*tensor_inputs) |
| 443 | ctx.packed_non_tensor_inputs = packed_non_tensor_inputs |
| 444 | |
| 445 | with torch.no_grad(), enable_checkpointing(): |
| 446 | unpacked_args, unpacked_kwargs = unpack_kwargs(kwarg_keys, args) |
| 447 | outputs = run_function(*unpacked_args, **unpacked_kwargs) |
| 448 | the_module = unpacked_args[0] |
| 449 | |
| 450 | # Because we run with torch.no_grad(), we can't actually access |
| 451 | # outputs.requires_grad. Instead, we manually compute it by |
| 452 | # checking if either the input or the module needs grads |
| 453 | parameters = list(the_module.parameters()) |
| 454 | |
| 455 | # If the module is wrapped by FlattenParamsWrapper, then the |
| 456 | # parameters would have been deleted. If so, we need to access |
| 457 | # the views into the flattened parameters. |
| 458 | if hasattr(the_module, "_unflattened_param_views"): |
| 459 | parameters += the_module._unflattened_param_views |
| 460 | |
| 461 | output_requires_grad = any(param.requires_grad for param in parameters) or any( |
| 462 | x.requires_grad for x in tensor_inputs |
| 463 | ) |
| 464 | parent_ctx_dict["output_requires_grad"] = output_requires_grad |
| 465 | |
| 466 | if not isinstance(outputs, torch.Tensor): |
| 467 | # Autograd Functions don't like non-Tensor outputs. We can split the |
| 468 | # non-Tensor and Tensor outputs, returning the former by reference |
| 469 | # through *parent_ctx_dict* and returning the latter directly. |
| 470 | outputs, packed_non_tensor_outputs = split_non_tensors(outputs) |
| 471 | parent_ctx_dict["packed_non_tensor_outputs"] = packed_non_tensor_outputs |
| 472 | |
| 473 | return outputs |
| 474 | |
| 475 | @staticmethod |
nothing calls this directly
no test coverage detected