class_docstr: PoolLayer parameter object.
  This then is passed as an argument to all pooling kernels.
  
  op: max, avg, l2 pooling
  N: Number of images in mini-batch
  
  C: Number of input feature maps
  D: Depth  of input image
  H: Height of input image
  W: Width  of input image
  
  J: Size of feature map pooling window (maxout n_pieces)
  T: Depth  of pooling window
  R: Height of pooling window
  S: Width  of pooling window
  
  padding: amount of zero-padding around the given image or feature map edge
  strides: factor to step the window by in a given direction (overlap allowed)
  
  Leave spatial dimensions at 1 to allow feature map pooling in the fc layers.
code: def __init__(
      self,
      lib,
      dtype,
      op,
      N,
      C,
      D=1,
      H=1,
      W=1,
      J=1,
      T=1,
      R=1,
      S=1,
      pad_c=0,
      pad_d=0,
      pad_h=0,
      pad_w=0,
      str_c=None,
      str_d=None,
      str_h=None,
      str_w=None,
  ):
      # default to non-overlapping
      if str_c is None:
          str_c = J
      if str_d is None:
          str_d = T
      if str_h is None:
          str_h = R
      if str_w is None:
          str_w = S
  
      if str_c < J or str_d < T or str_h < R or str_w < S:
          self.overlap = (
              math.ceil(float(J) / str_c)
              * math.ceil(float(T) / str_d)
              * math.ceil(float(R) / str_h)
              * math.ceil(float(S) / str_w)
          )
      else:
          self.overlap = 0.0
  
      # Compute the output dimensions
      K = lib.output_dim(C, J, pad_c, str_c, pooling=True)
      M = lib.output_dim(D, T, pad_d, str_d, pooling=True)
      P = lib.output_dim(H, R, pad_h, str_h, pooling=True)
      Q = lib.output_dim(W, S, pad_w, str_w, pooling=True)
  
      self.op = op
      self.C = C
      self.K = K
      self.M = M
      self.P = P
      self.Q = Q
      self.N = N
      self.JTRS = (J, T, R, S)
      self.DHW = (D, H, W)
      self.MPQ = (M, P, Q)
      self.padding = (pad_c, pad_d, pad_h, pad_w)
      self.strides = (str_c, str_d, str_h, str_w)
  
      self.dimI = (C, D, H, W, N)
      self.dimO = (K, M, P, Q, N)
      self.dimF2 = None
      self.dimI2 = (C * D * H * W, N)
      self.dimO2 = (K * M * P * Q, N)
      self.sizeI = reduce(mul, self.dimI, 1)
      self.sizeO = reduce(mul, self.dimO, 1)
      self.nOut = reduce(mul, self.MPQ, 1) * K
  
      self.kSlice = [
          self.pool_slice(k, J, C, pad_c, str_c) for k in range(K)
      ]
      self.mSlice = [
          self.pool_slice(m, T, D, pad_d, str_d) for m in range(M)
      ]
      self.pSlice = [
          self.pool_slice(p, R, H, pad_h, str_h) for p in range(P)
      ]
      self.qSlice = [
          self.pool_slice(q, S, W, pad_w, str_w) for q in range(Q)
      ]
  
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 PoolLayer object from inherited base classes: object with example: obj = PoolLayer(lib, dtype, op, N, C, D, H, W, J, T, R, S, pad_c, pad_d, pad_h, pad_w, str_c, str_d, str_h, str_w)