class_docstr: Extension of torch.autograd
code: def forward(ctx, fn, fn_inverse, num_inputs, *inputs_and_weights):
      ctx.fn = fn
      ctx.fn_inverse = fn_inverse
      ctx.weights = inputs_and_weights[num_inputs:]
      inputs = inputs_and_weights[: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)
          # Detach the output, which then allows discarding the intermediary results
          outputs = ctx.fn(*x).detach_()
  
      # clear memory of input node features
      inputs[1].storage().resize_(0)
  
      # store for backward pass
      ctx.inputs = [inputs]
      ctx.outputs = [outputs]
  
      return outputs
  
file_path: dgl/python/dgl/nn/pytorch/conv/grouprevres.py
imports: from copy import deepcopy
  import numpy
  import torch
  import torch.nn
label_desc: Use image node_id 1 for calling the InvertibleCheckpoint obj's underlying member method code with example usage: obj.forward(ctx, fn, fn_inverse, num_inputs) and returns: outputs