class_docstr: Extension of torch.autograd
code: def backward(ctx, *grad_outputs):
      if not torch.autograd._is_checkpoint_valid():
          raise RuntimeError(
              "InvertibleCheckpoint is not compatible with .grad(), \
                                 please use .backward() if possible"
          )
      # retrieve input and output tensor nodes
      if len(ctx.outputs) == 0:
          raise RuntimeError(
              "Trying to perform backward on the InvertibleCheckpoint \
                                 for more than once."
          )
      inputs = ctx.inputs.pop()
      outputs = ctx.outputs.pop()
  
      # reconstruct input node features
      with torch.no_grad():
          # inputs[0] is DGLGraph and inputs[1] is input node features
          inputs_inverted = ctx.fn_inverse(
              *((inputs[0], outputs) + inputs[2:])
          )
          # clear memory of outputs
          outputs.storage().resize_(0)
  
          x = inputs[1]
          x.storage().resize_(int(np.prod(x.size())))
          x.set_(inputs_inverted)
  
      # compute gradients
      with torch.set_grad_enabled(True):
          detached_inputs = []
          for i, element in enumerate(inputs):
              if isinstance(element, torch.Tensor):
                  element = element.detach()
                  element.requires_grad = ctx.input_requires_grad[i]
              detached_inputs.append(element)
  
          detached_inputs = tuple(detached_inputs)
          temp_output = ctx.fn(*detached_inputs)
  
      filtered_detached_inputs = tuple(
          filter(
              lambda x: getattr(x, "requires_grad", False),
              detached_inputs,
          )
      )
      gradients = torch.autograd.grad(
          outputs=(temp_output,),
          inputs=filtered_detached_inputs + ctx.weights,
          grad_outputs=grad_outputs,
      )
  
      input_gradients = []
      i = 0
      for rg in ctx.input_requires_grad:
          if rg:
              input_gradients.append(gradients[i])
              i += 1
          else:
              input_gradients.append(None)
  
      gradients = (
          tuple(input_gradients) + gradients[-len(ctx.weights) :]
      )
  
      return (None, None, None) + gradients
  
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 2 for calling the InvertibleCheckpoint obj's underlying member method code with example usage: obj.backward(ctx) and returns: unknown