class_docstr: Block of reversible layers. See rev_block.
class_docstr_tok: ["Block","of","reversible","layers",".","See","rev_block","."]
code: def _make_efficient_grad_fn(self, inputs_, ys_):
      def _efficient_grad_fn(*grad_ys, **kwargs):
          """Custom gradient fn for a block of reversible residual layers."""
          inputs = inputs_
          ys = ys_
          variables = kwargs["variables"]
          side_inputs = inputs[2:]
  
          f_side_idxs = [None] * len(self.f_side_input)
          g_side_idxs = [None] * len(self.g_side_input)
          assert len(side_inputs) == len(self.f_side_input) + len(
              self.g_side_input
          )
  
          for i, t in enumerate(side_inputs):
              if t in self.f_side_input:
                  f_side_idxs[self.f_side_input.index(t)] = i
              elif t in self.g_side_input:
                  g_side_idxs[self.g_side_input.index(t)] = i
              else:
                  assert False
  
          f_vars = [[] for _ in range(self.num_layers)]
          g_vars = [[] for _ in range(self.num_layers)]
          f_vars_idxs = [[] for _ in range(self.num_layers)]
          g_vars_idxs = [[] for _ in range(self.num_layers)]
  
          for i, ref in enumerate(variables):
              # Use the name to identify the layer number and function (f or g)
              regex = LAYER_RE.match(ref.name)
              layer_no = int(regex.group(1))
              fn_name = regex.group(2)
              if fn_name == "f":
                  f_vars[layer_no].append(ref)
                  f_vars_idxs[layer_no].append(i)
              else:
                  assert fn_name == "g"
                  g_vars[layer_no].append(ref)
                  g_vars_idxs[layer_no].append(i)
  
          f_var_grads = []
          g_var_grads = []
          f_side_grads = []
          g_side_grads = []
  
          # Reverse variable containers to go backward
          f_vars.reverse()
          g_vars.reverse()
          f = list(self.f)
          g = list(self.g)
          f.reverse()
          g.reverse()
  
          with variable_scope.variable_scope(
              self.scope_name, reuse=True
          ):
              for i in xrange(self.num_layers):
                  ys, grad_ys, f_ret, g_ret = _rev_layer_backward(
                      ys,
                      grad_ys,
                      f[i],
                      g[i],
                      f_vars[i],
                      self.f_side_input,
                      g_vars[i],
                      self.g_side_input,
                  )
  
                  grad_f_vars, grad_f_side = f_ret
                  grad_g_vars, grad_g_side = g_ret
                  f_var_grads.append(grad_f_vars)
                  g_var_grads.append(grad_g_vars)
                  f_side_grads.append(grad_f_side)
                  g_side_grads.append(grad_g_side)
  
          # Accumulate layer gradients for f_side_input and g_side_input
          acc_f_side_grads = _acc_grads(*f_side_grads)
          acc_g_side_grads = _acc_grads(*g_side_grads)
  
          # Use the stored idxs to put gradients in the passed-in order.
          side_input_grads = [None] * len(side_inputs)
          variable_grads = [None] * len(variables)
  
          # Variable gradients were collected in reverse layer order. Reverse to
          # match idxs.
          f_var_grads.reverse()
          g_var_grads.reverse()
          for idxs, grads in list(zip(f_vars_idxs, f_var_grads)) + list(
              zip(g_vars_idxs, g_var_grads)
          ):
              for i, grad in zip(idxs, grads):
                  variable_grads[i] = grad
  
          for i, grad in zip(f_side_idxs, acc_f_side_grads):
              side_input_grads[i] = grad
          for i, grad in zip(g_side_idxs, acc_g_side_grads):
              side_input_grads[i] = grad
  
          grad_x1, grad_x2 = grad_ys
          return [grad_x1, grad_x2] + side_input_grads, variable_grads
  
      return _efficient_grad_fn
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import functools
  import re
  import numpy
  import six
  from six.moves import xrange
  from ..None import contrib_framework
  from tensorflow.python.eager import backprop
  from tensorflow.python.framework import dtypes
  from tensorflow.python.framework import ops
  from tensorflow.python.layers import base
  from tensorflow.python.ops import array_ops
  from tensorflow.python.ops import control_flow_ops
  from tensorflow.python.ops import control_flow_util
  from tensorflow.python.ops import custom_gradient
  from tensorflow.python.ops import gradients_impl
  from tensorflow.python.ops import math_ops
  from tensorflow.python.ops import variable_scope
  from tensorflow.python.ops import variables
  from tensorflow.python.platform import tf_logging
  from tensorflow.python.util import nest
  from tensorflow.python.util import tf_inspect
label_desc: Use image node_id 6 for calling the RevBlock obj's underlying member method code with example usage: obj._make_efficient_grad_fn(inputs_, ys_) and returns: _efficient_grad_fn, unknown,  variable_grads