code: def forward_gpu(self, gys):
      func = self.func
  
      if func.is_cudnn_used:
          return func.backward_cudnn(gys)
  
      ndim = func.ndim
      pad_value = func.pad_value
      ksize = func.ksize
      stride = func.stride
      pad = func.pad
      in_shape = func._in_shape
      in_dtype = func._in_dtype
  
      is_pad_value_none = pad_value is None
  
      (gy,) = gys
      n, c = in_shape[:2]
      idims = in_shape[2:]
      odims = gy.shape[2:]
      if is_pad_value_none:
          # This conversion from chainerx to cupy exists here for
          # double backward of chainerx on cuda.
          coeff = backend.from_chx(func.coeff)
          gy *= coeff
      gx = cuda.cupy.empty(in_shape, in_dtype)
  
      (
          in_params,
          out_params,
          operation,
          name,
      ) = average_pooling_nd_kernel.AveragePoolingNDKernelBackward.generate(
          ndim
      )
      cuda.elementwise(in_params, out_params, operation, name)(
          gy.reduced_view(),
          *(idims + odims + ksize + stride + pad + (gx,)),
      )
  
      if not is_pad_value_none:
          gx /= functools.reduce(operator.mul, ksize)
      return (gx,)
  
imports: import functools
  import operator
  import numpy
  import six
  import chainer
  from chainer import backend
  from chainer.backends import cuda
  from chainer import function_node
  from chainer.functions.pooling import average_pooling_nd_kernel
  from chainer.functions.pooling import pooling_nd
  from chainer.utils import conv
  from chainer.utils import conv_nd
  import chainerx
label_desc: Use image node_id 3 for calling the AveragePoolingNDGrad obj's underlying member method code with example usage: obj.forward_gpu(gys) and returns: gx, func