code: def _create_grad_func(
      ys,
      xs,
      grads,
      cond_graph,
      body_graph,
      name,
      while_op,
      maximum_iterations,
  ):
      """Builds and returns the gradient FuncGraph of `func_graph` and its args.
  
      The returned grad_func_graph must be called with the returned
      args + grad_func_graph.captures.
  
      Args:
        ys: A `Tensor` or list of tensors to be differentiated.
        xs: A `Tensor` or list of tensors to be used for differentiation.
        grads: The incoming grads for `ys`.
        cond_graph: FuncGraph for the forward cond function.
        body_graph: FuncGraph for the forward body function.
        name: Name of the returned gradient function.
        while_op: The forward While op.
        maximum_iterations: Tensor. The maximum number of iterations.
  
      Returns:
        2-tuple of (grad_func_graph, args).
      """
      assert len(ys) == len(grads)
  
      total_iters = while_op.outputs[0]
      counter = constant_op.constant(
          0, dtype=total_iters.dtype, name="grad_counter"
      )
  
      # Build frozen sets so that we do not have linear time lookups in
      # `_is_loop_invariant`. Note: `body_graph.inputs` and `body_graph.outputs`
      # may get updated during gradient computation because we add accumulators to
      # the forward op. However, those are not loop invariants so wouldn't affect
      # the output of `_is_loop_invariant`. Also we would never attempt to capture
      # those accumulators so `_is_loop_invariant` should never receive those new
      # tensors as args.
      body_graph_inputs = object_identity.ObjectIdentitySet(
          body_graph.inputs
      )
      body_graph_outputs = object_identity.ObjectIdentitySet(
          body_graph.outputs
      )
  
      args = [counter, maximum_iterations, total_iters] + list(grads)
      # Note: The returned function does not have `args` in the list of
      # `external_captures`.
      grad_func_graph = func_graph_module.func_graph_from_py_func(
          name,
          lambda *args: _grad_fn(ys, xs, args, body_graph),
          args,
          {},
          func_graph=_WhileBodyGradFuncGraph(
              name,
              cond_graph,
              body_graph,
              maximum_iterations,
              while_op,
              body_graph_inputs,
              body_graph_outputs,
          ),
      )
  
      # Update the list of outputs with tensors corresponding to the captured
      # tensors. We capture 3 types of tensors when building the grad fn:
      # 1. Accumulators for forward graph intermediates which are not loop
      #    invariants. The outputs corresponding to these are populated in
      #    `internal_capture_to_output` by `_WhileBodyGradFuncGraph`.
      # 2. Resources, which are output as is.
      # 3. Forward graph loop invariants, which are output as is.
      for (
          external_capture,
          internal_capture,
      ) in grad_func_graph.captures:
          if (
              ops.tensor_id(internal_capture)
              in grad_func_graph.internal_capture_to_output
          ):
              new_output = grad_func_graph.internal_capture_to_output[
                  ops.tensor_id(internal_capture)
              ]
          else:
              raise ValueError(
                  f"Tensor {str(internal_capture)} which captures "
                  f"{str(external_capture)} is in list of "
                  f"internal_captures but not in internal_capture_to_output."
              )
          grad_func_graph.outputs.append(new_output)
          grad_func_graph.structured_outputs.append(new_output)
  
      return grad_func_graph, args
  
imports: import collections
  from tensorflow.core.framework import attr_value_pb2
  from tensorflow.python.client import pywrap_tf_session
  from tensorflow.python.eager import backprop_util
  from tensorflow.python.framework import auto_control_deps_utils
  from tensorflow.python.framework import constant_op
  from tensorflow.python.framework import dtypes
  from tensorflow.python.framework import func_graph
  from tensorflow.python.framework import indexed_slices
  from tensorflow.python.framework import ops
  from tensorflow.python.framework import tensor
  from tensorflow.python.framework import tensor_shape
  from tensorflow.python.framework import tensor_spec
  from tensorflow.python.framework import tensor_util
  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 control_flow_util_v2
  from tensorflow.python.ops import default_gradient
  from tensorflow.python.ops import gen_functional_ops
  from tensorflow.python.ops import gen_resource_variable_ops
  from tensorflow.python.ops import gradients_util
  from tensorflow.python.ops import handle_data_util
  from tensorflow.python.ops import list_ops
  from tensorflow.python.ops import math_ops
  from tensorflow.python.ops import tensor_array_ops
  from tensorflow.python.ops import while_v2_indexed_slices_rewriter
  from tensorflow.python.util import compat
  from tensorflow.python.util import nest
  from tensorflow.python.util import object_identity
  from tensorflow.python.util import variable_utils
label_desc: Use image node_id 9 for calling a global function with example usage: _create_grad_func(ys, xs, grads, cond_graph, body_graph, name, while_op, maximum_iterations) and returns: grad_func_graph,  args