'Function to perform batch normalization forward pass. Included
for API compatibility with GPU compound kernel call.
Arguments:
x (Tensor): Input from previous layer
xsum (Tensor): Precomputed batch sum over PQN dimension
xvar (Tensor): Buffer for variance (computed in kernel)
gmean (Tensor): global mean ()
gvar (Tensor): global variance
gamma (Tensor): scale parameter
beta (Tensor): location parameter
y (Tensor): normalized output
eps (float): constant for numerical stability
rho (float): exponential window averaging constant'

def compound_fprop_bn(self, x, xsum, xvar, gmean, gvar, gamma, beta, y, eps, rho, compute_batch_sum, accumbeta=0.0, relu=False, binary=False, inference=False, outputs=None, layer=None):

    if inference:
        xhat = ((x - gmean) / self.sqrt((gvar + eps)))
        y[:] = (((y * accumbeta) + (xhat * gamma)) + beta)
        return
    if compute_batch_sum:
        xsum[:] = self.sum(x, axis=1)
    xvar[:] = self.var(x, axis=1, binary=binary)
    xsum[:] = (xsum / x.shape[1])
    gmean[:] = ((gmean * rho) + ((1.0 - rho) * xsum))
    gvar[:] = ((gvar * rho) + ((1.0 - rho) * xvar))
    if binary:
        xhat = self.shift((x - xsum), (1.0 / self.sqrt((xvar + eps))))
        outputs = y.reshape(xhat.shape)
        outputs[:] = ((self.shift(xhat, gamma) + beta) + (accumbeta * outputs))
    else:
        xhat = ((x - xsum) / self.sqrt((xvar + eps)))
        outputs = y.reshape(xhat.shape)
        outputs[:] = (((xhat * gamma) + beta) + (accumbeta * outputs))
