code: def backprop_step(
      func, target_input_indexes, grad_outputs, grad_inputs, is_debug
  ):
      """Accumulates gradients of a FunctionNode
  
      This routine is used by :meth:`chainer.Variable.backward` and
      :func:`chainer.grad`.
  
      Args:
          func (~chainer.FunctionNode): The function for which gradients are
              accumulated.
          target_input_indexes (tuple of int): Sorted indices of the inputs
              that require gradients. It is guaranteed that this tuple contains
              at least one element.
          grad_outputs (tuple of Variable): Gradients w.r.t. the output
              variables. If the gradient w.r.t. an output variable is not
              given, the corresponding element is ``None``.
          grad_inputs (dict): References of the gradients w.r.t. the input
              variables.
          is_debug (bool): ``True`` if the debug mode is enabled.
  
      """
      if is_debug:
          assert isinstance(target_input_indexes, tuple)
          assert target_input_indexes == tuple(
              sorted(target_input_indexes)
          )
          assert isinstance(grad_outputs, tuple)
      if (
          func.backward_accumulate.__code__
          is not chainer.FunctionNode.backward_accumulate.__code__
      ):
          # backward_accumulate is overridden
          grad_inputs_tuple = tuple(
              [
                  _pop_or_none(grad_inputs[func.inputs[i]])
                  for i in target_input_indexes
              ]
          )
  
          # Call backward_accumulate()
          try:
              gxs = func.backward_accumulate(
                  target_input_indexes, grad_outputs, grad_inputs_tuple
              )
          except Exception as e:
              _reraise_with_stack(func, e)
  
      else:  # otherwise, backward should be overridden
          # Call backward()
          try:
              gxs = func.backward(target_input_indexes, grad_outputs)
          except Exception as e:
              _reraise_with_stack(func, e)
  
          if is_debug:
              for gx in gxs:
                  if not (
                      gx is None or isinstance(gx, chainer.Variable)
                  ):
                      raise ValueError(
                          func._get_error_message(
                              "type of gradients returned from backward is "
                              "incorrect: "
                              "{} != expected {}".format(
                                  type(gx), chainer.Variable
                              )
                          )
                      )
  
          len_gxs = len(gxs)
          if len_gxs == len(func.inputs):
              gxs = tuple([gxs[i] for i in target_input_indexes])
          elif len_gxs != len(target_input_indexes):
              msg = "number of gradients returned from backward is incorrect: "
              if len(func.inputs) == len(target_input_indexes):
                  msg += "%s != expected %s" % (
                      len_gxs,
                      len(func.inputs),
                  )
              else:
                  msg += "%s != expected %s or %s" % (
                      len_gxs,
                      len(func.inputs),
                      len(target_input_indexes),
                  )
              raise ValueError(func._get_error_message(msg))
  
      for i, gx in six.moves.zip(target_input_indexes, gxs):
          if gx is None or gx.raw_array is None:
              continue
  
          grad_inputs[func.inputs[i]].append(gx)
  
          if is_debug:
              node_x = func.inputs[i]
              g_input_list = grad_inputs[node_x]
              if gx.shape != node_x.shape:
                  raise ValueError(
                      func._get_error_message(
                          "shape of gradients returned from backward is "
                          "incorrect: "
                          "input-index={}, actual {} != expected {}".format(
                              i, gx.shape, node_x.shape
                          )
                      )
                  )
              if gx is not None and g_input_list:
                  g_input = g_input_list[0]
                  if gx.shape != g_input.shape:
                      raise ValueError(
                          func._get_error_message(
                              "shape of gradients returned from backward is "
                              "incorrect: "
                              "input-index={}, actual {} != expected {}".format(
                                  i, gx.shape, g_input.shape
                              )
                          )
                      )
                  if gx.dtype != g_input.dtype:
                      raise ValueError(
                          func._get_error_message(
                              "dtype of gradients returned from backward is "
                              "incorrect: "
                              "input-index={}, actual {} != expected {}".format(
                                  i, gx.dtype, g_input.dtype
                              )
                          )
                      )
      del gxs
  
      if is_debug:
          # each grad is a list of variables
          # iter_gxs expands it as a sequence of variables.
          def iter_gxs(gxs):
              for gx in gxs:
                  for gx_elem in gx:
                      yield gx_elem
  
          for gx in iter_gxs(grad_inputs.values()):
              if chainer.backend._contains_nan(gx.data):
                  raise RuntimeError(
                      "NaN is detected on backward computation of {}".format(
                          func.label
                      )
                  )
  
      if not func.lazy_grad_sum:
          for gx in grad_inputs.values():
              _reduce(gx)
  
imports: import os
  import shutil
  import sys
  import traceback
  import six
  import chainer
label_desc: Use image node_id 5 for calling a global function with example usage: backprop_step(func, target_input_indexes, grad_outputs, grad_inputs, is_debug) without return types