code: def convolution_nd(
      x, w, b, pad, stride, dilation, group, dtype=np.float32
  ):
      """ """
      C = x.shape[0]
      inshape = x.shape[1:]
      ndim = len(inshape)
      assert w.ndim == ndim + 2
      K, Cg = w.shape[:2]
      kshape = w.shape[2:]
  
      def get_conv_out_size_recursive(d, ndim):
          if d == ndim:
              return []
          s = get_conv_out_size(
              inshape[d], kshape[d], pad[d], stride[d], dilation[d]
          )
          return [s] + get_conv_out_size_recursive(d + 1, ndim)
  
      outshape = get_conv_out_size_recursive(0, ndim)
      inshape_pad = [C] + [inshape[d] + 2 * pad[d] for d in range(ndim)]
      x_pad = np.zeros(inshape_pad, dtype=dtype)
      s = [
          slice(
              None,
          )
      ] + [slice(pad[d], pad[d] + inshape[d]) for d in range(ndim)]
      x_pad[tuple(s)] = x
      y = np.zeros([K] + outshape, dtype=dtype)
      for k in range(K):
          g = int(k // (K // group))
          for outindex in itertools.product(*map(range, outshape)):
              inindex = [
                  outindex[d] * stride[d]
                  + np.arange(0, kshape[d]) * dilation[d]
                  for d in range(ndim)
              ]
              ci = np.arange(g * Cg, (g + 1) * Cg)
              y[(k,) + tuple(outindex)] = (
                  w[k] * x_pad[np.ix_(ci, *inindex)]
              ).sum()
      if b is not None:
          y += b[tuple([Ellipsis] + [np.newaxis for d in range(ndim)])]
      return y
  
imports: from __future__ import division
  from six.moves import range
  import itertools
  import numpy
label_desc: Use image node_id 6 for calling a global function with example usage: convolution_nd(x, w, b, pad, stride, dilation, group, dtype) and returns: y, unknown, list