code: def matrix_rank(
      x: paddle.Tensor,
      /,
      *,
      atol: Optional[Union[float, Tuple[float]]] = None,
      rtol: Optional[Union[float, Tuple[float]]] = None,
      hermitian: Optional[bool] = False,
      out: Optional[paddle.Tensor] = None,
  ) -> paddle.Tensor:
      if (x.ndim < 2) or (0 in x.shape):
          return paddle.to_tensor(0).squeeze().astype(x.dtype)
      # we don't use the native matrix_rank function because the behaviour of the
      # tolerance argument is difficult to unify
  
      if hermitian:
          svd_values = paddle_backend.abs(paddle_backend.eigvalsh(x))
      else:
          svd_values = paddle_backend.svd(x)[1]
      sigma = paddle_backend.max(svd_values, axis=-1, keepdims=False)
      atol = (
          atol
          if atol is not None
          else ivy.finfo(x.dtype).eps * max(x.shape[-2:]) * sigma
      )
      rtol = rtol if rtol is not None else 0.0
      tol = paddle_backend.maximum(
          atol, paddle_backend.multiply(rtol, sigma)
      )
      # make sure it's broadcastable again with svd_values
      tol = paddle_backend.expand_dims(tol, axis=-1)
      ret = paddle.count_nonzero(
          paddle_backend.greater(svd_values, tol), axis=-1
      )
      if x.ndim == 2 and tol.ndim < 2:
          # to fix the output shape when input is unbatched
          # and tol is batched
          ret = paddle_backend.squeeze(ret, axis=None)
      return ret
  
imports: import paddle
  from typing import Union, Optional, Tuple, Literal, List, NamedTuple, Sequence
  from collections import namedtuple
  import ivy
  from ivy import inf
  from ivy.utils.exceptions import IvyNotImplementedException
  import ivy.functional.backends.paddle
  from .None import backend_version
  from ivy.func_wrapper import with_unsupported_device_and_dtypes, with_unsupported_dtypes, with_supported_dtypes
  from .elementwise import _elementwise_helper
label_desc: Use image node_id 13 for calling a global function with example usage: matrix_rank() and returns: ret, paddle