class_docstr: Custom Backpropagation function to allow (A) flusing memory in foward
  and (B) activation recomputation reversibly in backward for gradient calculation.
  
  Inspired by https://github.com/RobinBruegger/RevTorch/blob/master/revtorch/revtorch.py
class_docstr_tok: ["Custom","Backpropagation","function","to","allow","(","A",")","flusing","memory","in","foward","and","(","B",")","activation","recomputation","reversibly","in","backward","for","gradient","calculation",".","Inspired","by","https",":","\/\/github.com\/RobinBruegger\/RevTorch\/blob\/master\/revtorch\/revtorch.py"]
docstr: Reversible Backward pass. Any intermediate activations from `buffer_layers` are
  recovered from ctx. Each layer implements its own loic for backward pass (both
  activation recomputation and grad calculation).
docstr_tok: ["Reversible","Backward","pass",".","Any","intermediate","activations","from","`","buffer_layers","`","are","recovered","from","ctx",".","Each","layer","implements","its","own","loic","for","backward","pass","(","both","activation","recomputation","and","grad","calculation",")","."]
code: def backward(ctx, dx):
      """
      Reversible Backward pass. Any intermediate activations from `buffer_layers` are
      recovered from ctx. Each layer implements its own loic for backward pass (both
      activation recomputation and grad calculation).
      """
      dX_1, dX_2 = torch.chunk(dx, 2, dim=-1)
  
      # retrieve params from ctx for backward
      X_1, X_2, *int_tensors = ctx.saved_tensors
  
      # no buffering
      if len(int_tensors) != 0:
          buffer_layers = int_tensors[0].tolist()
  
      else:
          buffer_layers = []
  
      layers = ctx.layers
  
      for _, layer in enumerate(layers[::-1]):
          if layer.layer_id in buffer_layers:
              X_1, X_2, dX_1, dX_2 = layer.backward_pass(
                  Y_1=int_tensors[
                      buffer_layers.index(layer.layer_id) * 2 + 1
                  ],
                  Y_2=int_tensors[
                      buffer_layers.index(layer.layer_id) * 2 + 2
                  ],
                  dY_1=dX_1,
                  dY_2=dX_2,
              )
  
          else:
              X_1, X_2, dX_1, dX_2 = layer.backward_pass(
                  Y_1=X_1,
                  Y_2=X_2,
                  dY_1=dX_1,
                  dY_2=dX_2,
              )
  
      dx = torch.cat([dX_1, dX_2], dim=-1)
  
      del int_tensors
      del dX_1, dX_2, X_1, X_2
  
      return dx, None, None
  
imports: import sys
  from functools import partial
  import torch
  from torch import nn
  from torch.autograd import Function
  from slowfast.models.attention import MultiScaleAttention, attention_pool
  from slowfast.models.common import Mlp, TwoStreamFusion, drop_path
  from slowfast.models.utils import round_width
label_desc: Use image node_id 2 for calling the RevBackProp obj's underlying member method code with example usage: obj.backward(ctx, dx) and returns: dx,  None,  None