code: def check_double_backward(
      func,
      x_data,
      y_grad,
      x_grad_grad,
      params=(),
      params_grad_grad=(),
      eps=1e-3,
      atol=1e-4,
      rtol=1e-3,
      no_grads=None,
      dtype=None,
      detect_nondifferentiable=False,
  ):
      """Test twice differentiation of a given procedure.
  
      This function automatically checks if the backward procedure of ``func``
      is correctly implemented for further differentiation. It first computes the
      gradient of ``func`` w.r.t. its inputs in the same way as
      :func:`~chainer.gradient_check.check_backward`. This function then further
      invokes the backward procedure against the gradient variables, starting
      from the initial gradient given by ``x_grad_grad``. It also computes the
      second gradient using :func:`~chainer.gradient_check.numerical_grad`. The
      resulting gradients are compared to confirm if the second-order gradients
      are approximately correct.
  
      Note that this function **DOES NOT** check if the first-order
      differentiation is correct; the numerical gradient assumes that the
      first-order gradient given by the usual :meth:`chainer.Variable.backward`
      is correct. The implementation of each differentiable function should be
      tested by :func:`~chainer.gradient_check.check_backward` first, and then
      should be tested by this function if necessary.
  
      For the details of the arguments, see
      :func:`~chainer.gradient_check.check_backward`. The additional arguments
      ``x_grad_grad`` and ``params_grad_grad`` are (tuples of)
      :class:`~chainer.Variable` (s) that include the initial gradient
      corresponding to the first-order gradient of each input and parameter. Note
      that the default error tolerance ``atol`` and ``rtol`` are slightly larger
      than those of :func:`~chainer.gradient_check.check_backward` because the
      numerical gradients of the second order differentiation are less accurate
      than those of the first order gradients.
  
      """
      # Rename variables
      xs = x_data
      gys = y_grad
      ggxs = x_grad_grad
      ggparams = params_grad_grad
      no_gxs = no_grads
      del x_data
      del y_grad
      del x_grad_grad
      del params_grad_grad
      del no_grads
  
      xs = _as_tuple(xs)
      params = _as_tuple(params)
      gys = _as_tuple(gys)
      ggxs = _as_tuple(ggxs)
      ggparams = _as_tuple(ggparams)
      n_x = len(xs)
  
      first_order_no_gxs = [x.dtype.kind != "f" for x in xs]
  
      def first_order_grad(*inputs):
          xs = inputs[:n_x]
          gys = inputs[n_x:]
  
          ys = _as_tuple(func(*xs))
  
          # `gys` (inputs to `first_order_grad` forward function) may have been
          # casted to float64 by `numerical_grad`. For certain functions demoting
          # the dtypes (e.g. `F.cast` that casts to float16), the dtypes of `ys`
          # (e.g. outputs of `F.cast`) and `gys` (e.g. given by `numerical_grad`)
          # may mismatch and we need to align those dtypes here.
          gys = [
              None
              if gy is None
              else chainer.functions.cast(gy, y.dtype)
              for y, gy in zip(ys, gys)
          ]
  
          _check_outputs_and_grad_outputs(ys, gys)
  
          chainer.backward(ys, gys, enable_double_backprop=True)
  
          gxs = []
          errors = []
          for i, (no_gx, x) in enumerate(
              six.moves.zip(first_order_no_gxs, xs)
          ):
              if no_gx:
                  if x.grad is not None:
                      errors.append(
                          "[{}]: Gradient was calculated while expected to not.".format(
                              i
                          )
                      )
              else:
                  if x.grad is None:
                      gxs.append(None)
                  else:
                      gxs.append(x.grad_var)
  
          if len(errors) > 0:
              f = six.StringIO()
              f.write(
                  "There are errors retrieving first-order gradients:\n"
              )
              f.write(
                  "Inputs: {}\n".format(utils._format_array_props(xs))
              )
              f.write(
                  "Skip: {}\n".format(
                      ", ".join(
                          str(no_gx) for no_gx in first_order_no_gxs
                      )
                  )
              )
              f.write("Errors:\n")
              for error in errors:
                  f.write("{}\n".format(error))
              raise RuntimeError(f.getvalue())
  
          return tuple(gxs + [p.grad_var for p in params])
  
      inputs = xs + gys
      grad_grad = ggxs + ggparams
      try:
          check_backward(
              first_order_grad,
              inputs,
              grad_grad,
              params=params,
              eps=eps,
              atol=atol,
              rtol=rtol,
              no_grads=no_gxs,
              dtype=dtype,
              detect_nondifferentiable=detect_nondifferentiable,
          )
      except AssertionError as e:
          f = six.StringIO()
          f.write(
              "check_double_backward failed "
              "(eps={} atol={} rtol={})\n".format(eps, atol, rtol)
          )
          for i, x in enumerate(xs):
              f.write("input[{}]:\n".format(i))
              f.write("{}\n".format(x))
          for i, gy in enumerate(gys):
              f.write("grad_output[{}]:\n".format(i))
              f.write("{}\n".format(gy))
          for i, ggx in enumerate(ggxs):
              f.write("grad_grad_input[{}]:\n".format(i))
              f.write("{}\n".format(ggx))
          for i, ggp in enumerate(ggparams):
              f.write("grad_grad_param[{}]:\n".format(i))
              f.write("{}\n".format(ggp))
          f.write("\n")
          f.write(str(e))
          utils._raise_from(AssertionError, f.getvalue(), e)
  
imports: from __future__ import absolute_import
  import warnings
  import numpy
  import six
  import chainer
  from chainer import backend
  from chainer.backends import _cpu
  from chainer.backends import cuda
  from chainer import configuration
  from chainer import testing
  from chainer import utils
  from chainer import variable
  import chainerx
label_desc: Use image node_id 10 for calling a global function with example usage: check_double_backward(func, x_data, y_grad, x_grad_grad, params, params_grad_grad, eps, atol, rtol, no_grads, dtype, detect_nondifferentiable) and returns: tuple