code: def matrix_rank(
      x: np.ndarray,
      /,
      *,
      atol: Optional[Union[float, Tuple[float]]] = None,
      rtol: Optional[Union[float, Tuple[float]]] = None,
      hermitian: Optional[bool] = False,
      out: Optional[np.ndarray] = None,
  ) -> np.ndarray:
      if (x.ndim < 2) or (0 in x.shape):
          return np.asarray(0, np.int64)
      # we don't use the native matrix_rank function because the behaviour of the
      # tolerance argument is difficult to unify,
      # and the native implementation is compositional
      svd_values = np.linalg.svd(
          x, hermitian=hermitian, compute_uv=False
      )
      sigma = np.max(svd_values, axis=-1, keepdims=False)
      atol = (
          atol
          if atol is not None
          else np.finfo(x.dtype).eps * max(x.shape[-2:]) * sigma
      )
      rtol = rtol if rtol is not None else 0.0
      tol = np.maximum(atol, rtol * sigma)
      # make sure it's broadcastable again with svd_values
      tol = np.expand_dims(tol, axis=-1)
      ret = np.count_nonzero(svd_values > tol, axis=-1)
      return ret
  
imports: from collections import namedtuple
  from typing import Union, Optional, Tuple, Literal, List, NamedTuple, Sequence
  import numpy
  import ivy
  from ivy import inf
  from ivy.func_wrapper import with_unsupported_dtypes
  from ivy.functional.backends.numpy.helpers import _scalar_output_to_0d_array
  from .None import backend_version
label_desc: Use image node_id 12 for calling a global function with example usage: matrix_rank() and returns: ret, np