class_docstr: ConvLayer parameter object.
  This then is passed as an argument to all the convolution operations.
  
  N: Number of images in mini-batch
  C: Number of input feature maps
  K: Number of output feature maps
  
  D: Depth  of input image
  H: Height of input image
  W: Width  of input image
  
  T: Depth  of filter kernel
  R: Height of filter kernel
  S: Width  of filter kernel
  
  padding: amount of zero-padding around the given edge
  strides: factor to step the filters by in a given direction
  dilation: dilation factor for each dimension
code: def __init__(
      self,
      lib,
      dtype,
      N,
      C,
      K,
      D=1,
      H=1,
      W=1,
      T=1,
      R=1,
      S=1,
      pad_d=0,
      pad_h=0,
      pad_w=0,
      str_d=1,
      str_h=1,
      str_w=1,
      dil_d=1,
      dil_h=1,
      dil_w=1,
  ):
      # Compute the output spatial dimensions
      M = lib.output_dim(D, T, pad_d, str_d, dilation=dil_d)
      P = lib.output_dim(H, R, pad_h, str_h, dilation=dil_h)
      Q = lib.output_dim(W, S, pad_w, str_w, dilation=dil_w)
  
      self.C = C
      self.K = K
      self.M = M
      self.P = P
      self.Q = Q
      self.NCK = (N, C, K)
      self.TRS = (T, R, S)
      self.DHW = (D, H, W)
      self.MPQ = (M, P, Q)
      self.padding = (pad_d, pad_h, pad_w)
      self.strides = (str_d, str_h, str_w)
      self.dilation = (dil_d, dil_h, dil_w)
  
      self.dimI = (C, D, H, W, N)
      self.dimF = (C, T, R, S, K)
      self.dimO = (K, M, P, Q, N)
      self.dimS = (K, 1)
      self.dimI2 = (C * D * H * W, N)
      self.dimF2 = (C * T * R * S, K)
      self.dimO2 = (K * M * P * Q, N)
      self.sizeI = reduce(mul, self.dimI, 1)
      self.sizeF = reduce(mul, self.dimF, 1)
      self.sizeO = reduce(mul, self.dimO, 1)
      self.nOut = reduce(mul, self.MPQ, 1) * K
  
      if (
          all(x == 1 for x in self.TRS)
          and all(p == 0 for p in self.padding)
          and all(s == 1 for s in self.strides)
          and all(d == 1 for d in self.dilation)
      ):
          self.dot = True
      else:
          self.dot = False
  
          self.mSlice = [
              self.fprop_slice(m, T, D, pad_d, str_d, dil_d)
              for m in range(M)
          ]
          self.pSlice = [
              self.fprop_slice(p, R, H, pad_h, str_h, dil_h)
              for p in range(P)
          ]
          self.qSlice = [
              self.fprop_slice(q, S, W, pad_w, str_w, dil_w)
              for q in range(Q)
          ]
          self.dSlice = [
              self.bprop_slice(d, T, M, pad_d, str_d, dil_d)
              for d in range(D)
          ]
          self.hSlice = [
              self.bprop_slice(h, R, P, pad_h, str_h, dil_h)
              for h in range(H)
          ]
          self.wSlice = [
              self.bprop_slice(w, S, Q, pad_w, str_w, dil_w)
              for w in range(W)
          ]
      self.is_mklop = False
  
imports: from __future__ import division
  from builtins import object
  import math
  from operator import mul
  import numpy
  from functools import reduce
label_desc: Use image node_id 1 to create a new ConvLayer object from inherited base classes: object with example: obj = ConvLayer(lib, dtype, N, C, K, D, H, W, T, R, S, pad_d, pad_h, pad_w, str_d, str_h, str_w, dil_d, dil_h, dil_w)