code: def _rev_layer_backward(
      ys, grad_ys, f, g, f_vars, f_side_input, g_vars, g_side_input
  ):
      """Backprop for 1 layer."""
      y1, y2 = ys
      grad_y1, grad_y2 = grad_ys
  
      # Reconstruct intermediates and inputs (x1, x2)
      # stop_gradients required on fn inputs to prevent infinite recursion into this
      # grad function on the calls to gradients.
      y1_stop = array_ops.stop_gradient(y1)
      g_side_input = [array_ops.stop_gradient(t) for t in g_side_input]
      gy1 = g(y1_stop, g_side_input) if g_side_input else g(y1_stop)
  
      x2 = y2 - gy1
      x2_stop = array_ops.stop_gradient(x2)
      f_side_input = [array_ops.stop_gradient(t) for t in f_side_input]
      fx2 = f(x2_stop, f_side_input) if f_side_input else f(x2_stop)
  
      x1 = y1 - fx2
  
      # Compute gradients wrt to inputs
      # dL/dy2 * dG(y1)/y1
      grad_gy1_y2 = gradients_impl.gradients(gy1, y1_stop, grad_y2)[0]
      grad_x1 = grad_y1 + grad_gy1_y2
      grad_x2 = (
          gradients_impl.gradients(fx2, x2_stop, grad_y1)[0]
          + grad_y2
          + gradients_impl.gradients(fx2, x2_stop, grad_gy1_y2)[0]
      )
  
      # Compute gradients wrt to vars and side inputs in f and g
      grads1 = gradients_impl.gradients(
          gy1, g_vars + g_side_input, grad_y2
      )
      grad_g_vars, grad_g_side = (
          grads1[: len(g_vars)],
          grads1[len(g_vars) :],
      )
      grads2 = gradients_impl.gradients(
          fx2, f_vars + f_side_input, grad_y1
      )
      grad_f_y1, grad_f_side1 = (
          grads2[: len(f_vars)],
          grads2[len(f_vars) :],
      )
      grads3 = gradients_impl.gradients(
          fx2, f_vars + f_side_input, grad_gy1_y2
      )
      grad_f_y2, grad_f_side2 = (
          grads3[: len(f_vars)],
          grads3[len(f_vars) :],
      )
      grad_f_vars = _acc_grads(grad_f_y1, grad_f_y2)
  
      grad_f_side = _acc_grads(grad_f_side1, grad_f_side2)
  
      # Put returns in a tuple to ensure a constant memory budget (i.e. don't want
      # the subsequent layer to start computing and consuming memory based on a
      # subset of these values).
      outputs = (
          (x1, x2),
          (grad_x1, grad_x2),
          (grad_f_vars, grad_f_side),
          (grad_g_vars, grad_g_side),
      )
      tupled = control_flow_ops.tuple(nest.flatten(outputs))
      return nest.pack_sequence_as(outputs, tupled)
  
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 3 for calling a global function with example usage: _rev_layer_backward(ys, grad_ys, f, g, f_vars, f_side_input, g_vars, g_side_input) and returns: nest