def qr(a: ndarray) -> tuple[ndarray, ...]:
    """
    Compute the qr factorization of a matrix.

    Factor the matrix a as qr, where q is orthonormal
    and r is upper-triangular.

    Parameters
    ----------
    a : (M, N) array_like
        Array like, at least dimension 2.

    Returns
    -------
    q : (M, K) array_like
        A matrix with orthonormal columns. K = min(M, N).
    r : (K, N) array_like
        The uppoer triangular matrix.

    Raises
    ------
    LinAlgError
        If factoring fails.

    Notes
    -----
    Currently does not support the parameter 'mode' from numpy 1.8.

    See Also
    --------
    numpy.linalg.qr

    Availability
    --------
    Single GPU, Single CPU
    """
    shape = a.shape
    if len(shape) < 2:
        raise LinAlgError(
            f"{len(shape)}-dimensional array given. "
            "Array must be at least two-dimensional"
        )
    if len(shape) > 2:
        raise NotImplementedError(
            "cuPyNumeric does not yet support stacked 2d arrays"
        )
    if np.dtype("e") == a.dtype:
        raise TypeError("array type float16 is unsupported in linalg")
    return _thunk_qr(a)

    Compute the qr factorization of a matrix.

    Factor the matrix a as qr, where q is orthonormal
    and r is upper-triangular.

    Parameters
    ----------
    a : (M, N) array_like
        Array like, at least dimension 2.

    Returns
    -------
    q : (M, K) array_like
        A matrix with orthonormal columns. K = min(M, N).
    r : (K, N) array_like
        The uppoer triangular matrix.

    Raises
    ------
    LinAlgError
        If factoring fails.

    Notes
    -----
    Currently does not support the parameter 'mode' from numpy 1.8.

    See Also
    --------
    numpy.linalg.qr

    Availability
    --------
    Single GPU, Single CPU
    
cupynumeric/linalg/linalg.py