'Function to perform batch normalization forward pass.
Arguments:
delta_out (Tensor): Delta buffer (where to write the output deltas)
grad_gamma (Tensor): Gradient w.r.t. gamma
grad_beta (Tensor): Gradient w.r.t. beta
delta_in (Tensor): Delta buffer (where to get the input deltas)
x (Tensor): feedforward input
xsum (Tensor): Batch sum over PQN dimension
xvar (Tensor): Batch variance
gamma (Tensor): scale parameter
eps (float): constant for numerical stability
threads (int): Number of GPU threads
repeat (int): Repeats for benchmarking
binary (bool): Binary shift based computations'

def compound_bprop_bn(self, delta_out, grad_gamma, grad_beta, delta_in, x, xsum, xvar, gamma, eps, threads=None, repeat=1, binary=False, layer=None):

    assert (xsum.dtype.type is np.float32), 'xsum    should    be    fp32'
    K = int(x.shape[0])
    N = int(x.shape[1])
    if (threads is None):
        if (N <= 8192):
            threads = (1 << max(5, (int(round(log(N, 2))) - 3)))
        else:
            threads = (128 if (K < 192) else 64)
    params = [(K, 1, 1), (threads, 1, 1), x.backend.stream, delta_out.gpudata, grad_gamma.gpudata, grad_beta.gpudata, delta_in.gpudata, x.gpudata, xsum.gpudata, xvar.gpudata, gamma.gpudata, eps, N, binary]
    from neon.backends.float_ew import _get_bn_bprop_kernel
    kernel = _get_bn_bprop_kernel(x.dtype.str[1:], threads, self.compute_capability)
    self._execute_bn(kernel, params, repeat, (x.nbytes * 4), N)
