Linear Algebra
cuNumeric.jl provides matrix multiplication, solves, Cholesky, eigen, SVD, QR, and related helpers for NDArray. For Einstein-index contractions, see Tensor Contractions.
Supported element types
All of the decompositions accept Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion (or allowpromotion) only when it widens the element type, so Int64 and UInt64 pass through silently while Int32, smaller integers, and Bool do not.
In this section
| Page | Topics |
|---|---|
| Standard functions | Matrix and vector products, norms, linear systems, and helpers |
| Factorizations | Cholesky, eigendecomposition, SVD, and QR |
| Batched operations | Solves and decompositions for stacks of matrices |
| Diagonal and identity | Structured diagonal matrices and uniform scaling |
| Tuning | Multi-GPU selection rules, cutoffs, and block sizes |
Which entry point to use
Single matrices use familiar LinearAlgebra functions. Most decompositions return standard factorization objects. QR returns cuNumeric's NDArrayQR. Stacks of matrices have no LinearAlgebra equivalent, so they get their own batched_* names.
| Single matrix (2D) | Returns | Stack of matrices (3D) |
|---|---|---|
LinearAlgebra.cholesky(A) | Cholesky | cuNumeric.batched_cholesky(A) |
LinearAlgebra.eigen(A) | Eigen | cuNumeric.batched_eigen(A) |
LinearAlgebra.eigvals(A) | NDArray | cuNumeric.batched_eigvals(A) |
LinearAlgebra.svd(A) | SVD | not supported |
LinearAlgebra.qr(A) | NDArrayQR | not supported |
cuNumeric.solve(A, b), A \ b | NDArray | cuNumeric.batched_solve(A, B) |
Not available yet
There is no public dense-matrix lu, matrix inv, or ldiv! yet (beyond the diagonal-matrix operations). Elementwise inv / ^-1 are unary operations, not matrix inverse.
Also missing: eigh / Hermitian eigen (needs Hermitian and Symmetric support on NDArray), and batched SVD and QR.
Reference
cuNumeric.NDArrayQR Type
NDArrayQR <: LinearAlgebra.FactorizationQR factorization of an NDArray, holding the explicit factors Q and R with A ≈ Q * R.
The backend returns materialized factors rather than the packed Householder representation Base uses, so this is a distinct type from LinearAlgebra.QR and QRCompactWY. It destructures as (Q, R) and exposes F.Q and F.R.
Base.:\ Method
A \ bSolve A * x = b for a square 2D NDArray A. Equivalent to cuNumeric.solve.
LinearAlgebra.cholesky Method
LinearAlgebra.cholesky(A::NDArray{T,2}) -> CholeskyCholesky factorization of the Hermitian positive-definite matrix A, returned as a LinearAlgebra.Cholesky object holding the lower factor L with A ≈ L * L'.
Only the lower triangle of A is read and, unlike Base, it is not checked for being Hermitian. A non-positive-definite input raises an ErrorException from the task rather than LinearAlgebra.PosDefException, so the check keyword is not supported.
Large matrices use cuSolverMp when available with multiple active GPUs. Other multi-processor configurations use cuPyNumeric's tiled Cholesky algorithm.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
For a stack of matrices of shape (b, m, m) use cuNumeric.batched_cholesky.
LinearAlgebra.eigen Method
LinearAlgebra.eigen(A::NDArray{T,2}) -> EigenEigenvalues and right eigenvectors of the square matrix A, returned as a LinearAlgebra.Eigen object. Column j of F.vectors is the eigenvector for F.values[j].
Values and vectors are always complex, even when A is real with real eigenvalues. This follows the underlying LAPACK geev path and differs from Base, which returns real factors for such input.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
For a stack of matrices of shape (b, m, m) use cuNumeric.batched_eigen.
LinearAlgebra.eigvals Method
LinearAlgebra.eigvals(A::NDArray{T,2})Eigenvalues of the square matrix A as a complex NDArray. See LinearAlgebra.eigen for the supported element types and for why the result is always complex.
LinearAlgebra.eigvecs Method
LinearAlgebra.eigvecs(A::NDArray{T,2})Right eigenvectors of the square matrix A, as columns of a complex NDArray. See LinearAlgebra.eigen for the supported element types.
LinearAlgebra.qr Method
LinearAlgebra.qr(A::NDArray{T,2}) -> NDArrayQRReduced QR factorization of A, with A ≈ F.Q * F.R. For an m × n input and k = min(m, n), F.Q is m × k and F.R is k × n.
Large matrices automatically use cuSolverMp when available with multiple active GPUs, including tall and wide inputs.
See NDArrayQR for why this is not a LinearAlgebra.QRCompactWY.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
LinearAlgebra.svd Method
LinearAlgebra.svd(A::NDArray{T,2}; full=false) -> SVDSingular value decomposition of A, returned as a LinearAlgebra.SVD object with A ≈ F.U * Diagonal(F.S) * F.Vt.
With m, n = size(A) and k = min(m, n), full=false gives an m × k F.U and a k × n F.Vt, and full=true gives m × m and n × n. F.S has length k and is real-valued for both real and complex input.
Destructuring an SVD yields (U, S, V) — the adjoint of F.Vt, not F.Vt itself. F.V is a lazy Adjoint wrapper, so operating on it falls back to scalar indexing until adjoint(::NDArray) is implemented; prefer F.Vt.
The backend only factors tall or square matrices (m >= n). A wide input throws ArgumentError rather than hitting the C++ m >= n assert.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
cuNumeric.solve Method
cuNumeric.solve(A, b)Solve the linear system A * x = b.
A must be a square (m, m) matrix. b must have shape (m,) or (m, n). The result has the same shape as b.
Large systems automatically use cuSolverMp when it is available and Legate has multiple active GPUs. Algorithm selection follows cuPyNumeric 26.06.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
For a stack of systems of shape (b, m, m) use cuNumeric.batched_solve.
See also \.
cuNumeric.batched_cholesky Method
cuNumeric.batched_cholesky(A)Cholesky factor of every matrix in the stack A, returned as a single array of the same shape. Each A[i, :, :] is factored independently into a lower triangular L with A[i, :, :] ≈ L * L'; the upper triangle is zeroed.
A must have shape (b, m, m). As in LinearAlgebra.cholesky, only the lower triangle is read and Hermitian-ness is not checked.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
cuNumeric.batched_eigen Method
cuNumeric.batched_eigen(A) -> (values, vectors)Eigenvalues and right eigenvectors of every matrix in the stack A.
A must have shape (b, m, m). values has shape (b, m) and vectors has the shape of A, with vectors[i, :, j] the eigenvector for values[i, j].
Both results are always complex, even for real input. See LinearAlgebra.eigen.
cuNumeric.batched_eigvals Method
cuNumeric.batched_eigvals(A)Eigenvalues of every matrix in the stack A, as a complex array of shape (b, m). See cuNumeric.batched_eigen.
cuNumeric.batched_solve Method
cuNumeric.batched_solve(A, B)Solve a stack of linear systems A * X = B.
A must have shape (b, m, m) and B shape (b, m, n). The result has the same shape as B.
Accepted element types are Float32, Float64, ComplexF32, and ComplexF64. Integer and Bool inputs are converted to Float64. As everywhere else in the package, that conversion needs @allowpromotion only when it widens the element type, so Int64 and UInt64 pass through silently.
For a single system use cuNumeric.solve.
LinearAlgebra.axpby! Method
axpby!(α, x::NDArray, β, y::NDArray)Update and return y with y = α * x + β * y.
LinearAlgebra.axpy! Method
axpy!(α, x::NDArray, y::NDArray)Update and return y with y = α * x + y.
LinearAlgebra.dot Method
dot(x::NDArray, y::NDArray)Return the vector inner product as a CNScalar. Complex inputs conjugate x.
LinearAlgebra.mul! Method
mul!(y::NDArray, A::NDArray, x::NDArray, α, β)Store α * A * x + β * y in y. The destination must not alias an input. α and β accept host numbers, 0D NDArray{T,0} values, or CNScalar wrappers.
LinearAlgebra.mul! Method
mul!(y::NDArray, A::NDArray, x::NDArray)Store the matrix-vector product A * x in y.
LinearAlgebra.mul! Method
mul!(C::NDArray, A::NDArray, B::NDArray, α, β)Store α * A * B + β * C in C. The destination must not alias an input. α and β accept host numbers, 0D NDArray{T,0} values, or CNScalar wrappers.
LinearAlgebra.norm Method
norm(x::NDArray, p::Real=2)Return the entrywise p-norm as a real CNScalar, not a matrix operator norm. Dense-array norms currently require a GPU. Unscaled accumulation can overflow or underflow.
cuNumeric.diag Method
cuNumeric.diag(arr::NDArray; k=0)Extract the k-th diagonal from a 2D NDArray.
cuNumeric.diagonal Method
cuNumeric.diagonal(arr::NDArray; offset=0, dims=(1, 2))Extract the diagonal of arr along two 1-based axes dims. The result has rank ndims(arr) - 1, with the diagonal stored as the last axis. offset selects a superdiagonal (> 0) or subdiagonal (< 0), matching LinearAlgebra.diag.
For a 2D matrix this is the same 1D diagonal as diag. For N > 2 the non-diagonal axes are kept in order, followed by the extracted diagonal.
cuNumeric.trace Method
cuNumeric.trace(arr::NDArray; offset=0, a1=0, a2=1)Compute the trace (sum of a diagonal) of the NDArray. Returns a 0-dimensional NDArray. The accumulator type follows promotions of other reductions like sum.