code: def matrix_rank(
      x: torch.Tensor,
      /,
      *,
      atol: Optional[Union[float, Tuple[float]]] = None,
      rtol: Optional[Union[float, Tuple[float]]] = None,
      hermitian: Optional[bool] = False,
      out: Optional[torch.Tensor] = None,
  ) -> torch.Tensor:
      if (x.ndim < 2) or (0 in x.shape):
          return torch.tensor(0, dtype=torch.int64)
      # we don't use the native matrix_rank function because the behaviour of the
      # tolerance argument is difficult to unify
      # return torch.linalg.matrix_rank(
      #     x, atol=atol, rtol=rtol, hermitian=hermitian, out=out
      # )
      if hermitian:
          svd_values = torch.abs(torch.linalg.eigvalsh(x))
      else:
          svd_values = torch.linalg.svdvals(x)
      sigma = torch.max(svd_values, axis=-1, keepdim=False)[0]
      atol = (
          atol
          if atol is not None
          else torch.finfo(x.dtype).eps * max(x.shape[-2:]) * sigma
      )
      rtol = rtol if rtol is not None else 0.0
      atol = _cast_for_unary_op(atol)
      rtol = _cast_for_unary_op(rtol)
      tol = torch.maximum(atol, rtol * sigma)
      # make sure it's broadcastable again with svd_values
      tol = torch.unsqueeze(tol, dim=-1)
      ret = torch.count_nonzero(svd_values > tol, dim=-1)
      return ret
  
imports: import torch
  from typing import Union, Optional, Tuple, Literal, List, NamedTuple, Sequence
  from collections import namedtuple
  import ivy
  from ivy import inf
  from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes
  from .None import backend_version
  from .elementwise import _cast_for_unary_op
label_desc: Use image node_id 13 for calling a global function with example usage: matrix_rank() and returns: ret, torch