code: def call_func_function(self, backend_config, x1, x2, x3):
      forward_xp, backward_xp = _get_expected_xp(backend_config, True)
  
      class Func(chainer.Function):
          def __init__(self):
              self.array_init = backend_config.device.send(
                  numpy.array([3], numpy.float32)
              )
  
          def forward(self, inputs):
              # Inputs
              assert isinstance(inputs, tuple)
              # x1, x3: float32
              # x2: int32
              x1, x2, x3 = inputs
              assert isinstance(x1, forward_xp.ndarray)
              assert isinstance(x2, forward_xp.ndarray)
              assert isinstance(x3, forward_xp.ndarray)
  
              # attribute fallback
              assert isinstance(self.array_init, forward_xp.ndarray)
              self.array_forward = forward_xp.array([2], numpy.float32)
              assert isinstance(self.array_forward, forward_xp.ndarray)
  
              y1 = x2 - 1  # int32
              y2 = x1 * x3 + x2.astype(x1.dtype)
              y3 = x1 + x3
              self.retain_inputs((0, 2))
              self.retain_outputs(
                  (
                      0,
                      1,
                  )
              )
              return y1, y2, y3
  
          def backward(self, inputs, grad_outputs):
              # Retained inputs
              assert isinstance(inputs, tuple)
              x1, x2, x3 = inputs
              assert isinstance(x1, backward_xp.ndarray)
              assert x2 is None  # not retained
              assert isinstance(x3, backward_xp.ndarray)
  
              # Output gradients
              assert isinstance(grad_outputs, tuple)
              gy1, gy2, gy3 = grad_outputs
              assert gy1 is None  # y1 is int32
              # y3 is disconnected
              # TODO(niboshi): Expression after "or" is workaround for
              # chainerx. ChainerX backward should return None for
              # disconnected output and this workaround should be removed.
              assert gy3 is None or (
                  float(gy3.max()) == 0 and float((-gy3).max()) == 0
              )
  
              # Retained outputs
              output_data = self.output_data
              assert isinstance(output_data, tuple)
              y1, y2, y3 = output_data
              assert isinstance(y1, backward_xp.ndarray)
              assert isinstance(y2, backward_xp.ndarray)
              assert y3 is None
  
              # attribute fallback
              assert isinstance(self.array_init, backward_xp.ndarray)
              assert isinstance(self.array_forward, backward_xp.ndarray)
              self.array_backward = backward_xp.array(
                  [4], numpy.float32
              )
              assert isinstance(
                  self.array_backward, backward_xp.ndarray
              )
  
              gx1 = x3 * gy2  # + gy3
              gx2 = None
              gx3 = x1 * gy2  # + gy3
              return gx1, gx2, gx3
  
      return Func()(x1, x2, x3)
  
imports: import unittest
  import numpy
  import chainer
  from chainer import testing
  import chainer.testing.backend
  import chainerx
label_desc: Use image node_id 1 for calling the TestFunctionBackprop obj's underlying member method code with example usage: obj.call_func_function(backend_config, x1, x2, x3) and returns: Func, y1,  y2,  y3, gx1,  gx2,  gx3