class_docstr: An invertible autograd function. This allows for automatic
  backpropagation in a reversible fashion so that the memory of intermediate
  results can be freed during the forward pass and be constructed on-the-fly
  during the bachward pass.
  
  Args:
      ctx (torch.autograd.function.InvertibleFunctionBackward):
          A context object that can be used to stash information for backward
          computation.
      fn (torch.nn.Module): The forward function.
      fn_inverse (torch.nn.Module): The inverse function to recompute the
          freed input.
      num_bwd_passes (int): Number of backward passes to retain a link
          with the output. After the last backward pass the output is
          discarded and memory is freed.
      num_inputs (int): The number of inputs to the forward function.
      *args (tuple): Inputs and weights.
class_docstr_tok: ["An","invertible","autograd","function",".","This","allows","for","automatic","backpropagation","in","a","reversible","fashion","so","that","the","memory","of","intermediate","results","can","be","freed","during","the","forward","pass","and","be","constructed","on-the-fly","during","the","bachward","pass",".","Args",":","ctx","(","torch.autograd.function.InvertibleFunctionBackward",")",":","A","context","object","that","can","be","used","to","stash","information","for","backward","computation",".","fn","(","torch.nn.Module",")",":","The","forward","function",".","fn_inverse","(","torch.nn.Module",")",":","The","inverse","function","to","recompute","the","freed","input",".","num_bwd_passes","(","int",")",":","Number","of","backward","passes","to","retain","a","link","with","the","output",".","After","the","last","backward","pass","the","output","is","discarded","and","memory","is","freed",".","num_inputs","(","int",")",":","The","number","of","inputs","to","the","forward","function",".","*","args","(","tuple",")",":","Inputs","and","weights","."]
code: def forward(
      ctx,
      fn: torch.nn.Module,
      fn_inverse: torch.nn.Module,
      num_bwd_passes: int,
      num_inputs: int,
      *args,
  ):
      ctx.fn = fn
      ctx.fn_inverse = fn_inverse
      ctx.weights = args[num_inputs:]
      ctx.num_bwd_passes = num_bwd_passes
      ctx.num_inputs = num_inputs
      inputs = args[:num_inputs]
      ctx.input_requires_grad = []
  
      with torch.no_grad():  # Make a detached copy which shares the storage:
          x = []
          for element in inputs:
              if isinstance(element, torch.Tensor):
                  x.append(element.detach())
                  ctx.input_requires_grad.append(element.requires_grad)
              else:
                  x.append(element)
                  ctx.input_requires_grad.append(None)
          outputs = ctx.fn(*x)
  
      if not isinstance(outputs, tuple):
          outputs = (outputs,)
  
      # Detaches outputs in-place, allows discarding the intermedate result:
      detached_outputs = tuple(element.detach_() for element in outputs)
  
      # Clear memory of node features:
      if torch_geometric.typing.WITH_PT20:
          inputs[0].untyped_storage().resize_(0)
      else:  # pragma: no cover
          inputs[0].storage().resize_(0)
  
      # Store these tensor nodes for backward passes:
      ctx.inputs = [inputs] * num_bwd_passes
      ctx.outputs = [detached_outputs] * num_bwd_passes
  
      return detached_outputs
  
imports: import copy
  from abc import ABC, abstractmethod
  from typing import Any, List, Optional, Union
  import numpy
  import torch
  from torch import Tensor
  import torch_geometric.typing
  from torch_geometric.typing import Adj
label_desc: Use image node_id 1 for calling the InvertibleFunction obj's underlying member method code with example usage: obj.forward(ctx, fn, fn_inverse, num_bwd_passes, num_inputs) and returns: detached_outputs