code: def batch_norm(
      x: Union[ivy.NativeArray, ivy.Array],
      mean: Union[ivy.NativeArray, ivy.Array],
      variance: Union[ivy.NativeArray, ivy.Array],
      /,
      *,
      offset: Optional[Union[ivy.NativeArray, ivy.Array]] = None,
      scale: Optional[Union[ivy.NativeArray, ivy.Array]] = None,
      training: Optional[bool] = False,
      eps: Optional[float] = 1e-5,
      momentum: Optional[float] = 1e-1,
      data_format: Optional[str] = "NSC",
      out: Optional[Tuple[ivy.Array, ivy.Array, ivy.Array]] = None,
  ) -> Tuple[ivy.Array, ivy.Array, ivy.Array]:
      """
      Apply batch normalization to the input array and returns the normalized input,
      running mean and running variance arrays as output. If ``training == False``,
      the mean and variance arrays passed as input are used for normalization
      and the same arrays are returned as running mean and running variance
      respectively. However, when ``training ==True``, this function computes the
      batch mean and batch variance which is then used for normalization.In this case,
      the function returns the running mean and running variance calculated
      using the following formula:
  
      running_mean = (1 - momentum) * running_mean + momentum * batch_mean
      running_var = (1 - momentum) * running_var + momentum * frac{n}{n-1} * batch_var
  
      Parameters
      ----------
      x
          Input array of default shape (N, *S, C), where N is the batch dimension,
          *S corresponds to any number of spatial dimensions and
           C corresponds to the channel dimension.
      mean
          Mean array used for input's normalization. It can be of any shape
          braodcastable to (N,*S,C).
      variance
          Variance array used for input's normalization. It can be of any shape
          braodcastable to (N,*S,C).
      offset
          An offset array. If present, will be added to the normalized input.
          It can be of any shape broadcastable to (N,*S,C).
      scale
          A scale array. If present, the scale is applied to the normalized input.
          It can be of any shape broadcastable to (N,*S,C).
      training
          If true, calculate and use the mean and variance of `x`. Otherwise, use the
          provided `mean` and `variance`.
      eps
          A small float number to avoid dividing by 0.
      momentum
           the value used for the running_mean and running_var computation.
            Default value is 0.1.
      data_format
          The ordering of the dimensions in the input, one of "NSC" or "NCS",
          where N is the batch dimension, S represents any number of spatial
          dimensions and C is the channel dimension. Default is "NSC".
      out
          optional output arrays, for writing the result to.
  
      Returns
      -------
      ret
           Tuple of arrays containing
            the normalized input, running_mean, and running_variance.
      """
      xdims = len(x.shape)
  
      if data_format == "NCS":
          x = ivy.permute_dims(x, axes=(0, *range(2, xdims), 1))
  
      runningmean = mean
      runningvariance = variance
  
      if training:
          n = x.size if xdims == 1 else x.size / x.shape[-1]
          dims = (0, *range(1, xdims - 1))
          mean = ivy.mean(x, axis=dims)
          variance = ivy.var(x, axis=dims)
          runningmean = (1 - momentum) * runningmean + momentum * mean
          runningvariance = (
              1 - momentum
          ) * runningvariance + momentum * variance * n / (n - 1)
      inv = 1.0 / ivy.sqrt(variance + eps)
      offset = 0 if offset is None else offset
      if scale is not None:
          inv = inv * scale
      xnormalized = x * inv + offset - mean * inv
  
      if data_format == "NCS":
          xnormalized = ivy.permute_dims(
              xnormalized, axes=(0, xdims - 1, *range(1, xdims - 1))
          )
  
      if ivy.exists(out):
          xnormalized = ivy.inplace_update(out[0], xnormalized)
          runningmean = ivy.inplace_update(out[1], runningmean)
          runningvariance = ivy.inplace_update(out[2], runningvariance)
  
      return xnormalized, runningmean, runningvariance
  
file_path: ivy/ivy/functional/ivy/experimental/norms.py
imports: from typing import Literal, Union, Optional, Tuple
  import ivy
  from ivy.utils.backend import current_backend
  from ivy.func_wrapper import handle_partial_mixed_function, to_native_arrays_and_back, handle_out_argument, handle_nestable, handle_array_like_without_promotion, inputs_to_ivy_arrays, handle_array_function, handle_device, handle_backend_invalid
  from ivy.utils.exceptions import handle_exceptions
label_desc: Use image node_id 4 for calling a global function with example usage: batch_norm() and returns: xnormalized,  runningmean,  runningvariance