code: def svd(a, full_matrices=True, compute_uv=True):
      """Singular Value Decomposition.
  
      Factorizes the matrix ``a`` as ``u * np.diag(s) * v``, where ``u`` and
      ``v`` are unitary and ``s`` is an one-dimensional array of ``a``'s
      singular values.
  
      Args:
          a (cupy.ndarray): The input matrix with dimension ``(..., M, N)``.
          full_matrices (bool): If True, it returns u and v with dimensions
              ``(..., M, M)`` and ``(..., N, N)``. Otherwise, the dimensions
              of u and v are ``(..., M, K)`` and ``(..., K, N)``, respectively,
              where ``K = min(M, N)``.
          compute_uv (bool): If ``False``, it only returns singular values.
  
      Returns:
          tuple of :class:`cupy.ndarray`:
              A tuple of ``(u, s, v)`` such that ``a = u * np.diag(s) * v``.
  
      .. warning::
          This function calls one or more cuSOLVER routine(s) which may yield
          invalid results if input conditions are not met.
          To detect these invalid results, you can set the `linalg`
          configuration to a value that is not `ignore` in
          :func:`cupyx.errstate` or :func:`cupyx.seterr`.
  
      .. note::
          On CUDA, when ``a.ndim > 2`` and the matrix dimensions <= 32, a fast
          code path based on Jacobian method (``gesvdj``) is taken. Otherwise,
          a QR method (``gesvd``) is used.
  
          On ROCm, there is no such a fast code path that switches the underlying
          algorithm.
  
      .. seealso:: :func:`numpy.linalg.svd`
      """
      from cupy_backends.cuda.libs import cusolver
  
      _util._assert_cupy_array(a)
      if a.ndim > 2:
          return _svd_batched(a, full_matrices, compute_uv)
  
      # Cast to float32 or float64
      dtype, uv_dtype = _util.linalg_common_type(a)
      real_dtype = dtype.char.lower()
      s_dtype = uv_dtype.char.lower()
  
      # Remark 1: gesvd only supports m >= n (WHAT?)
      # Remark 2: gesvd returns matrix U and V^H
      n, m = a.shape
  
      if m == 0 or n == 0:
          s = cupy.empty((0,), s_dtype)
          if compute_uv:
              if full_matrices:
                  u = cupy.eye(n, dtype=uv_dtype)
                  vt = cupy.eye(m, dtype=uv_dtype)
              else:
                  u = cupy.empty((n, 0), dtype=uv_dtype)
                  vt = cupy.empty((0, m), dtype=uv_dtype)
              return u, s, vt
          else:
              return s
  
      # `a` must be copied because xgesvd destroys the matrix
      if m >= n:
          x = a.astype(dtype, order="C", copy=True)
          trans_flag = False
      else:
          m, n = a.shape
          x = a.transpose().astype(dtype, order="C", copy=True)
          trans_flag = True
  
      k = n  # = min(m, n) where m >= n is ensured above
      if compute_uv:
          if full_matrices:
              u = cupy.empty((m, m), dtype=dtype)
              vt = x[:, :n]
              job_u = ord("A")
              job_vt = ord("O")
          else:
              u = x
              vt = cupy.empty((k, n), dtype=dtype)
              job_u = ord("O")
              job_vt = ord("S")
          u_ptr, vt_ptr = u.data.ptr, vt.data.ptr
      else:
          u_ptr, vt_ptr = 0, 0  # Use nullptr
          job_u = ord("N")
          job_vt = ord("N")
      s = cupy.empty(k, dtype=real_dtype)
      handle = device.get_cusolver_handle()
      dev_info = cupy.empty(1, dtype=numpy.int32)
  
      if dtype == "f":
          gesvd = cusolver.sgesvd
          gesvd_bufferSize = cusolver.sgesvd_bufferSize
      elif dtype == "d":
          gesvd = cusolver.dgesvd
          gesvd_bufferSize = cusolver.dgesvd_bufferSize
      elif dtype == "F":
          gesvd = cusolver.cgesvd
          gesvd_bufferSize = cusolver.cgesvd_bufferSize
      else:  # dtype == 'D':
          gesvd = cusolver.zgesvd
          gesvd_bufferSize = cusolver.zgesvd_bufferSize
  
      buffersize = gesvd_bufferSize(handle, m, n)
      workspace = cupy.empty(buffersize, dtype=dtype)
      if not runtime.is_hip:
          # rwork can be NULL if the information from supperdiagonal isn't needed
          # https://docs.nvidia.com/cuda/cusolver/index.html#cuSolverDN-lt-t-gt-gesvd  # noqa
          rwork_ptr = 0
      else:
          rwork = cupy.empty(min(m, n) - 1, dtype=s_dtype)
          rwork_ptr = rwork.data.ptr
      gesvd(
          handle,
          job_u,
          job_vt,
          m,
          n,
          x.data.ptr,
          m,
          s.data.ptr,
          u_ptr,
          m,
          vt_ptr,
          n,
          workspace.data.ptr,
          buffersize,
          rwork_ptr,
          dev_info.data.ptr,
      )
      cupy.linalg._util._check_cusolver_dev_info_if_synchronization_allowed(
          gesvd, dev_info
      )
  
      s = s.astype(s_dtype, copy=False)
  
      # Note that the returned array may need to be transposed
      # depending on the structure of an input
      if compute_uv:
          u = u.astype(uv_dtype, copy=False)
          vt = vt.astype(uv_dtype, copy=False)
          if trans_flag:
              return u.transpose(), s, vt.transpose()
          else:
              return vt, s, u
      else:
          return s
  
file_path: cupy/cupy/linalg/_decomposition.py
imports: import numpy
  import cupy
  from cupy_backends.cuda.api import runtime
  from cupy._core import internal
  from cupy.cuda import device
  from cupy.linalg import _util
label_desc: Use image node_id 7 for calling a global function with example usage: svd(a, full_matrices, compute_uv) and returns: _svd_batched, s, u,  s,  vt, s, u,  s,  vt, vt,  s,  u