code: def ref_group_normalization(
      x,
      beta,
      gamma,
      num_groups,
      channel_axis,
      batch_axis,
      eps,
      output_stat,
  ):
      cdim = x.shape[channel_axis]
  
      if cdim % num_groups > 0:
          raise ValueError()
  
      shape = x.shape[:channel_axis] + (
          num_groups,
          int(cdim / num_groups),
      )
  
      channel_axis += x.ndim * (channel_axis < 0)
      batch_axis = _force_list(batch_axis)
      batch_axis = [b + x.ndim * (b < 0) for b in batch_axis]
  
      if channel_axis < len(x.shape) - 1:
          shape += x.shape[channel_axis + 1 :]
  
      tmp = x.reshape(shape).copy()
  
      ignore_axes = batch_axis + [
          channel_axis,
      ]
  
      axes = tuple(_get_axes_excluding(len(shape), ignore_axes))
  
      x_mean = tmp.mean(axis=axes, keepdims=True)
      x_var = tmp.var(axis=axes, keepdims=True)
  
      norm = (tmp - x_mean) / (x_var + eps) ** 0.5
  
      norm = norm.reshape(x.shape)
  
      if gamma is not None:
          norm *= gamma
  
      if beta is not None:
          norm += beta
  
      if output_stat:
          return norm, x_mean, x_var
  
      return norm
  
file_path: nnabla/python/test/function/test_group_normalization.py
imports: import pytest
  import numpy
  import nnabla
  import nnabla.functions
  from nbla_test_utils import list_context
  from nnabla.normalization_functions import _force_list, _get_axes_excluding
label_desc: Use image node_id 1 for calling a global function with example usage: ref_group_normalization(x, beta, gamma, num_groups, channel_axis, batch_axis, eps, output_stat) and returns: norm, norm,  x_mean,  x_var