'fprop_conv:
Required Arguments:
layer: ConvLayer object created with conv_layer()
I: input tensor  (actiavtions)
F: filter tensor (weights)
O: output tensor (actiavtions)
Compounding Options:
X: tensor to use in bprop_relu or beta
can be same as O for beta accumulate (this is default when None)
should be same shape as O
bias: (K,1) tensor to use for adding bias to output
O += bias
bsum: (K,1) tensor to accumulate batch sum over (used in batchnorm or bprop_bias)
bsum = sum(O.reshape(K,-1), axis=1)
the sum operation is fully deterministic
alpha, beta:
O = alpha*O + beta*X
O = alpha*O + beta*O   (if X==O)
relu: boolean flag to apply:
O = max(O, 0) + slope*min(O, 0)
can be combined with bias (where bias is added first)
brelu: bprop_relu boolean flag to apply:
O *= (X > 0) + slope*(X < 0)
can be combined with bsum tensor to output bprop_bias
repeat: used in benchmarking'

def fprop_conv(self, layer, I, F, O, X=None, bias=None, bsum=None, alpha=1.0, beta=0.0, relu=False, brelu=False, slope=0.0, repeat=1, layer_op=None):

    assert (layer.sizeI == I.size)
    assert (layer.sizeF == F.size)
    assert (layer.sizeO == O.size)
    layer.fprop_kernels.bind_params(I, F, O, X, bias, bsum, alpha, beta, relu, brelu, slope)
    return self._execute_conv('fprop', layer, layer.fprop_kernels, repeat)
