Implements the `forward-redirection`. Taken from Pytorch-lightning: https://github.com/Lightning-AI/pytorch-lightning/blob/02311d03fb982560246eead7c08104481fac9579/src/lightning/pytorch/strategies/strategy.py#L602 A method call to a wrapped module gets rerouted through the wrapper's `f
| 399 | |
| 400 | |
| 401 | class _ForwardRedirection: |
| 402 | """Implements the `forward-redirection`. |
| 403 | |
| 404 | Taken from Pytorch-lightning: |
| 405 | https://github.com/Lightning-AI/pytorch-lightning/blob/02311d03fb982560246eead7c08104481fac9579/src/lightning/pytorch/strategies/strategy.py#L602 |
| 406 | |
| 407 | A method call to a wrapped module gets rerouted through the wrapper's `forward` method instead. |
| 408 | |
| 409 | """ |
| 410 | |
| 411 | def __call__( |
| 412 | self, wrapper_module: nn.Module, original_module: nn.Module, method: callable, *args: Any, **kwargs: Any |
| 413 | ): |
| 414 | """Reroutes a method call through the `wrapper_module`'s `forward` method. |
| 415 | |
| 416 | Args: |
| 417 | wrapper_module: The module that has `original_module` wrapped. |
| 418 | original_module: The module that was wrapped inside `wrapper_module`. |
| 419 | method_name: The name of the method that should be called on the `original_module` after inputs get |
| 420 | redirected through the `wrapper_module`'s `forward` method. |
| 421 | *args: The positional arguments to the method `method_name`. They will get passed to a patched |
| 422 | `forward` method instead. |
| 423 | **kwargs: The keyword arguments to the method `method_name`. They will get passed to a patched |
| 424 | `forward` method instead. |
| 425 | |
| 426 | """ |
| 427 | original_forward = original_module.forward |
| 428 | |
| 429 | def wrapped_forward(*_args: Any, **_kwargs: Any) -> Any: |
| 430 | # Unpatch ourselves immediately before calling the method `method_name` |
| 431 | # because itself may want to call the real `forward` |
| 432 | original_module.forward = original_forward # type: ignore[method-assign] |
| 433 | # Call the actual method e.g. `.training_step(...)` |
| 434 | out = method(*_args, **_kwargs) |
| 435 | self.on_after_inner_forward(wrapper_module, original_module) |
| 436 | return out |
| 437 | |
| 438 | # Patch the original_module's forward so we can redirect the arguments back to the real method |
| 439 | original_module.forward = wrapped_forward # type: ignore[method-assign] |
| 440 | |
| 441 | wrapper_output = wrapper_module(*args, **kwargs) |
| 442 | self.on_after_outer_forward(wrapper_module, original_module) |
| 443 | return wrapper_output |
| 444 | |
| 445 | def on_after_inner_forward(self, wrapper_module: nn.Module, original_module: nn.Module) -> None: |
| 446 | pass |
| 447 | |
| 448 | def on_after_outer_forward(self, wrapper_module: nn.Module, original_module: nn.Module) -> None: |
| 449 | pass |