code: func (p *Pooling) CalcOutputShape(input *TensorDescriptor, dims int) (retVal []int, err error) {
  	p.outDims = dims
  	p.inputTensor = cloneShape(input.shape)
  
  	switch dims {
  	case 0:
  		return nil, errors.Errorf("Cannot work on dims of 0")
  	case 2:
  		p.outputShape = make([]int, 4)
  		n := (*C.int)(unsafe.Pointer(&p.outputShape[0]))
  		c := (*C.int)(unsafe.Pointer(&p.outputShape[1]))
  		h := (*C.int)(unsafe.Pointer(&p.outputShape[2]))
  		w := (*C.int)(unsafe.Pointer(&p.outputShape[3]))
  		if err = result(C.cudnnGetPooling2dForwardOutputDim(p.internal, input.internal, n, c, h, w)); err != nil {
  			return nil, err
  		}
  
  	default:
  		p.outputShape = make([]int, dims)
  		ptr, ptrManaged := ints2CIntPtr(p.outputShape)
  		defer returnManaged(ptrManaged)
  		if err = result(C.cudnnGetPoolingNdForwardOutputDim(p.internal, input.internal, C.int(dims), ptr)); err != nil {
  			return nil, err
  		}
  	}
  	return cloneShape(p.outputShape), nil
  }
docs: // CalcOutputShape is like  OutputShape, but doesn't go through a check for the cached value.