code: def convolution_2d(
      x, w, b, pad, stride, dilation, group, dtype=np.float32
  ):
      """ """
      C, H, W = x.shape
      K, Cg, M, N = w.shape
  
      Ho = get_conv_out_size(H, M, pad[0], stride[0], dilation[0])
      Wo = get_conv_out_size(W, N, pad[1], stride[1], dilation[1])
      x_pad = np.zeros((C, H + pad[0] * 2, W + pad[1] * 2), dtype=dtype)
      x_pad[:, pad[0] : pad[0] + H, pad[1] : pad[1] + W] = x
      y = np.zeros((K, Ho, Wo), dtype=dtype)
      for k in range(K):
          g = int(k // (K // group))
          for ho in range(Ho):
              for wo in range(Wo):
                  hi = ho * stride[0] + np.arange(0, M) * dilation[0]
                  wi = wo * stride[1] + np.arange(0, N) * dilation[1]
                  ci = np.arange(g * Cg, (g + 1) * Cg)
                  y[k, ho, wo] = (
                      w[k] * x_pad[np.ix_(ci, hi, wi)]
                  ).sum()
      if b is not None:
          y += b[..., np.newaxis, np.newaxis]
      return y
  
imports: from __future__ import division
  from six.moves import range
  import itertools
  import numpy
label_desc: Use image node_id 5 for calling a global function with example usage: convolution_2d(x, w, b, pad, stride, dilation, group, dtype) and returns: y