code: def _coo_matmul_gpu(A_data, A_row, A_col, A_shape, A_order, B, dtype):
      cupy_dtype = dtype
      if cupy_dtype == numpy.float16:
          cupy_dtype = numpy.float32
          # fp32 is used in cupy kernel because fp16 atomicAdd is not supported
  
      # A_shape: (_m, _k)
      # B.shape: ((nb,) _k, _n)
      # A_data/row/col.shape: ((nb,) ldnz)
      _m, _k = A_shape
      _n = B.shape[-1]
      ldnz = A_data.shape[-1]
      if B.ndim == 2:
          nb = 1
          C = cuda.cupy.zeros((_m, _n), dtype=cupy_dtype)
      else:
          nb = B.shape[0]
          C = cuda.cupy.zeros((nb, _m, _n), dtype=cupy_dtype)
  
      if A_order == "C":
          # A chunk is the number of non-zero elements handled by a single GPU
          # thread. If contiguous non-zero elemets are related to the same
          # location of the output matrix and they are processed in the same
          # thread, number of atomic-add operations can be reduced.
          chunk = max(ldnz // _m, 1)
      else:
          chunk = 1
      nthreads = (nb * ldnz + chunk - 1) // chunk * _n
      _cupy_coo_matmul()(
          nb,
          _m,
          _n,
          _k,
          ldnz,
          chunk,
          A_data,
          A_row,
          A_col,
          B,
          C,
          size=nthreads,
      )
  
      return C.astype(dtype, copy=False)
  
imports: import numpy
  import chainer
  from chainer import backend
  from chainer.backends import cuda
  from chainer import function_node
  from chainer import utils
  from chainer.utils import type_check
label_desc: Use image node_id 3 for calling a global function with example usage: _coo_matmul_gpu(A_data, A_row, A_col, A_shape, A_order, B, dtype) and returns: C