code: def forward(self, inputs):
      self.retain_inputs((0,))
      xp = cuda.get_array_module(*inputs)
      x, gy = inputs
      self._gy_shape = gy.shape
      gW = xp.zeros(self.w_shape, dtype=gy.dtype)
  
      if xp is numpy:
          # It is equivalent to `numpy.add.at(gW, x, gy)` but ufunc.at is
          # too slow.
          for ix, igy in zip(x.ravel(), gy.reshape(x.size, -1)):
              if ix == self.ignore_label:
                  continue
              gW[ix] += igy
      else:
          """
          # original code based on cuda elementwise method
          if self.ignore_label is None:
              cuda.elementwise(
                  'T gy, S x, S n_out', 'raw T gW',
                  'ptrdiff_t w_ind[] = {x, i % n_out};'
                  'atomicAdd(&gW[w_ind], gy)',
                  'embed_id_bwd')(
                      gy, xp.expand_dims(x, -1), gW.shape[1], gW)
          else:
              cuda.elementwise(
                  'T gy, S x, S n_out, S ignore', 'raw T gW',
                  '''
                  if (x != ignore) {
                    ptrdiff_t w_ind[] = {x, i % n_out};
                    atomicAdd(&gW[w_ind], gy);
                  }
                  ''',
                  'embed_id_bwd_ignore_label')(
                      gy, xp.expand_dims(x, -1), gW.shape[1],
                      self.ignore_label, gW)
          """
          # EmbedID gradient alternative without atomicAdd, which simply
          # creates a one-hot vector and applies dot product
          xi = xp.zeros((x.size, len(gW)), dtype=numpy.float32)
          idx = (
              xp.arange(x.size, dtype=numpy.int32) * len(gW) + x.ravel()
          )
          xi.ravel()[idx] = 1.0
          if self.ignore_label is not None:
              xi[:, self.ignore_label] = 0.0
          gW = xi.T.dot(gy.reshape(x.size, -1)).astype(
              gW.dtype, copy=False
          )
  
      return (gW,)
  
imports: import chainer
  import numpy
  from chainer import cuda, function_node, link, variable
  from chainer.initializers import normal
  from chainer.utils import type_check
label_desc: Use image node_id 2 for calling the EmbedIDGrad obj's underlying member method code with example usage: obj.forward(inputs) and returns: gW