Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f15d10a
Batched SVD support for ROCSOLVER and CUSOLVER
Aug 21, 2026
0dfb4ae
Go back to QRIteration default
Aug 22, 2026
756bd02
Fix default driver for CUDA
kshyatt Aug 23, 2026
76b6665
Fix typo
kshyatt Aug 23, 2026
6fc6a76
And fix bad check in yacusolver
kshyatt Aug 23, 2026
ead34c6
One more API fix
kshyatt Aug 23, 2026
db0d4b8
Fix size of U and V bar
kshyatt Aug 23, 2026
e09586c
More API fixes
kshyatt Aug 23, 2026
39349fe
Remove redundant dummy one liners
kshyatt Sep 14, 2026
5aa0617
Switch to batched_svd_f and get rid of Batched versions of algorithms
kshyatt Sep 14, 2026
cdcf956
Fixup AMD default algos
kshyatt Sep 14, 2026
ce3565b
Move ragged batch handling and cutoffs etc into MAK
kshyatt Sep 15, 2026
b7f9c93
Add support for a batched svd_via_adjoint for algos requiring tall ma…
Sep 15, 2026
12c2d70
Add batched svd_full too
kshyatt Sep 15, 2026
7d00e25
Add special path for AMDGPU, implement gesvdx batching there, and fix…
Sep 16, 2026
0578c38
Some fixes and actually test Bisection on AMD
Sep 16, 2026
5b7a058
A few more fixes for Bisection
Sep 17, 2026
939f9c1
Support svd_full for Bisection
Sep 17, 2026
6199602
Remove batched and non-batched bisection for now
kshyatt Sep 18, 2026
0527bab
Restore Bisection test
kshyatt Sep 24, 2026
e67c712
Avoid some allocs
kshyatt Sep 24, 2026
9616379
one to one-liner and more checks for batch_size
kshyatt Sep 25, 2026
2d775bb
Apply batched suggestions from code review
kshyatt Sep 28, 2026
9f41e62
Fix sizes of dummy arrays
kshyatt Sep 28, 2026
1bf1afc
Don't return foreach
kshyatt Sep 28, 2026
6859f58
Missing batched Bisection piping
Sep 29, 2026
83bf9c4
Refactor out gaugefixing for batches
Sep 29, 2026
92a39d1
Add a flag for whether the driver supports ragged batches
kshyatt Sep 29, 2026
b9c72c0
Dumb typos
kshyatt Sep 29, 2026
4b513b4
Have batched_svd_compact use Diagonal
kshyatt Sep 29, 2026
9ec647d
Fix dimension check in gesvdx_strided_batched!
Sep 29, 2026
8011ad9
supports_ragged_batch takes a driver, not an algorithm
Sep 29, 2026
974a1d4
Make sure to mark bisection as supporting svd full here
Sep 29, 2026
9368acc
Move some batching utilities into a common file
kshyatt Sep 29, 2026
2a838f1
Move supports_ragged_batch to Driver definition
kshyatt Sep 29, 2026
dbb09c9
Just put batches below algos
kshyatt Sep 29, 2026
370b91e
Put the basis completion in the implementation file
Sep 30, 2026
305b1bb
Move batch_size length checks into else
kshyatt Sep 30, 2026
c0996d9
Apply batched suggestions from code review
kshyatt Sep 30, 2026
d398490
Strides for safety
kshyatt Sep 30, 2026
6d3d77e
Use both alg and driver in the batch checks
kshyatt Sep 30, 2026
16972d7
batch_size checks for batched gesvdx
Oct 1, 2026
fea0ae3
Force driver lookup for support checks
kshyatt Oct 1, 2026
b287776
Dumb typo
kshyatt Oct 1, 2026
4dafcbb
Actually make sure matrices that are too big aren't sent to the batch…
kshyatt Oct 1, 2026
fef45dd
Move batch_size check for CUSOLVER too
kshyatt Oct 1, 2026
66d8f71
Reorder check_inputs
kshyatt Oct 1, 2026
ee46715
Add TODO for CUSOLVER
kshyatt Oct 1, 2026
06e7f13
Use supports_pointer_batch and fix oversized test
kshyatt Oct 1, 2026
30d11c1
Formatter
kshyatt Oct 1, 2026
5832020
Check that inputs are preserved for in-place batch methods
Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 48 additions & 8 deletions ext/MatrixAlgebraKitAMDGPUExt/MatrixAlgebraKitAMDGPUExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,26 @@ using MatrixAlgebraKit: one!, zero!, uppertriangular!, lowertriangular!
using MatrixAlgebraKit: diagview, sign_safe
using MatrixAlgebraKit: ROCSOLVER, LQViaTransposedQR, TruncationStrategy, NoTruncation, TruncationByValue, AbstractAlgorithm
using MatrixAlgebraKit: default_qr_algorithm, default_lq_algorithm, default_svd_algorithm, default_eigh_algorithm
import MatrixAlgebraKit: geqrf!, ungqr!, unmqr!, gesvd!, gesvdx!, gesvdj!
import MatrixAlgebraKit: geqrf!, ungqr!, unmqr!, gesvd!, gesdd!, gesvdx!, gesvdj!
import MatrixAlgebraKit: gesvdj_batched!, gesdd_batched!, gesvd_batched!, gesvdx_batched!
import MatrixAlgebraKit: heevj!, heevd!, heev!, heevx!
import MatrixAlgebraKit: _sylvester, svd_rank, svd_pullback!, complete_svd_basis!
import MatrixAlgebraKit: _sylvester, svd_rank, svd_pullback!
using AMDGPU
using LinearAlgebra
using LinearAlgebra: BlasFloat

include("yarocsolver.jl")

MatrixAlgebraKit.default_driver(::Type{TA}) where {TA <: StridedROCVecOrMat{<:BlasFloat}} = ROCSOLVER()
MatrixAlgebraKit.default_driver(::Type{TA}) where {TA <: StridedROCArray{<:BlasFloat}} = ROCSOLVER()
MatrixAlgebraKit.default_driver(::Type{TA}) where {TA <: AbstractVector{<:StridedROCMatrix{<:BlasFloat}}} = ROCSOLVER()

function MatrixAlgebraKit.default_svd_algorithm(::Type{T}; kwargs...) where {T <: StridedROCVecOrMat{<:BlasFloat}}
function MatrixAlgebraKit.default_svd_algorithm(::Type{T}; kwargs...) where {T <: StridedROCMatrix{<:BlasFloat}}
return QRIteration(; kwargs...)
end
function MatrixAlgebraKit.default_svd_algorithm(::Type{T}; kwargs...) where {T <: StridedROCArray{<:BlasFloat, 3}}
return QRIteration(; kwargs...)
end
function MatrixAlgebraKit.default_svd_algorithm(::Type{T}; kwargs...) where {T <: AbstractVector{<:StridedROCMatrix{<:BlasFloat}}}
return QRIteration(; kwargs...)
end
function MatrixAlgebraKit.default_eigh_algorithm(::Type{T}; kwargs...) where {T <: StridedROCVecOrMat{<:BlasFloat}}
Expand All @@ -28,7 +36,12 @@ for f in (:geqrf!, :ungqr!, :unmqr!)
@eval $f(::ROCSOLVER, args...) = YArocSOLVER.$f(args...)
end

MatrixAlgebraKit.supports_svd_full(::ROCSOLVER, f::Symbol) = f in (:qr_iteration, :jacobi, :bisection)
MatrixAlgebraKit.supports_svd_full(::ROCSOLVER, f::Symbol) = f in (:qr_iteration, :jacobi, :divide_and_conquer, :bisection)

# rocSOLVER's `gesvd*_batched` functions take the batch as an array
# of device pointers, so a group of equally sized matrices
# doesn't need a copy into a 3D ROCArray.
MatrixAlgebraKit.supports_pointer_batch(::AbstractAlgorithm, ::ROCSOLVER, ::Type{<:StridedROCMatrix{<:BlasFloat}}) = true

function gesvd!(::ROCSOLVER, A::StridedROCMatrix, S::StridedROCVector, U::StridedROCMatrix, Vᴴ::StridedROCMatrix; kwargs...)
m, n = size(A)
Expand All @@ -42,11 +55,38 @@ function gesvdj!(::ROCSOLVER, A::StridedROCMatrix, S::StridedROCVector, U::Strid
return MatrixAlgebraKit.svd_via_adjoint!(gesvdj!, ROCSOLVER(), A, S, U, Vᴴ; kwargs...)
end

function gesvdx!(::ROCSOLVER, A::StridedROCMatrix, S::StridedROCVector, U::StridedROCMatrix, Vᴴ::StridedROCMatrix; kwargs...)
gesvdx!(::ROCSOLVER, A::StridedROCMatrix, S::StridedROCVector, U::StridedROCMatrix, Vᴴ::StridedROCMatrix; kwargs...) =
YArocSOLVER.gesvdx!(A, S, U, Vᴴ; kwargs...)
complete_svd_basis!(U, Vᴴ, length(S))
return S, U, Vᴴ

# rocSOLVER's batched `gesvd` requires m ≥ n, so wide matrices go through the adjoint
function gesvd_batched!(::ROCSOLVER, As::AbstractVector{<:StridedROCMatrix}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat}
Comment thread
kshyatt marked this conversation as resolved.
m, n = size(first(As))
m >= n && return YArocSOLVER.gesvd_batched!(As, Ss, Us, Vᴴs; kwargs...)
return MatrixAlgebraKit.batched_svd_via_adjoint!(gesvd_batched!, ROCSOLVER(), As, Ss, Us, Vᴴs; kwargs...)
end
function gesvd_batched!(::ROCSOLVER, As::StridedROCArray{T, 3}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat}
m, n, _ = size(As)
m >= n && return YArocSOLVER.gesvd_strided_batched!(As, Ss, Us, Vᴴs; kwargs...)
return MatrixAlgebraKit.batched_svd_via_adjoint!(gesvd_batched!, ROCSOLVER(), As, Ss, Us, Vᴴs; kwargs...)
end

gesdd_batched!(::ROCSOLVER, As::AbstractVector{<:StridedROCMatrix}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat} =
YArocSOLVER.gesdd_batched!(As, Ss, Us, Vᴴs; kwargs...)
gesdd_batched!(::ROCSOLVER, As::StridedROCArray{T, 3}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat} =
YArocSOLVER.gesdd_strided_batched!(As, Ss, Us, Vᴴs; kwargs...)

gesvdj_batched!(::ROCSOLVER, As::AbstractVector{<:StridedROCMatrix}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat} =
YArocSOLVER.gesvdj_batched!(As, Ss, Us, Vᴴs; kwargs...)
gesvdj_batched!(::ROCSOLVER, As::StridedROCArray{T, 3}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat} =
YArocSOLVER.gesvdj_strided_batched!(As, Ss, Us, Vᴴs; kwargs...)

gesvdx_batched!(::ROCSOLVER, As::AbstractVector{<:StridedROCMatrix}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat} =
YArocSOLVER.gesvdx_batched!(As, Ss, Us, Vᴴs; kwargs...)
gesvdx_batched!(::ROCSOLVER, As::StridedROCArray{T, 3}, Ss::StridedROCMatrix, Us::StridedROCArray{T, 3}, Vᴴs::StridedROCArray{T, 3}; kwargs...) where {T <: BlasFloat} =
YArocSOLVER.gesvdx_strided_batched!(As, Ss, Us, Vᴴs; kwargs...)

gesdd!(::ROCSOLVER, A::StridedROCMatrix, S::StridedROCVector, U::StridedROCMatrix, Vᴴ::StridedROCMatrix; kwargs...) =
YArocSOLVER.gesdd!(A, S, U, Vᴴ; kwargs...)

heevj!(::ROCSOLVER, A::StridedROCMatrix, Dd::StridedROCVector, V::StridedROCMatrix; kwargs...) =
YArocSOLVER.heevj!(A, Dd, V; kwargs...)
Expand Down
Loading
Loading