Skip to content

Batched SVD support for ROCSOLVER and CUSOLVER - #275

Draft
kshyatt wants to merge 11 commits into
mainfrom
ksh/batched_svd
Draft

kshyatt wants to merge 11 commits into
mainfrom
ksh/batched_svd

Conversation

@kshyatt

@kshyatt kshyatt commented Aug 21, 2026

Copy link
Copy Markdown
Member

Basically what it says on the tin. For CTMRG and other algorithms, we're getting absolutely slaughtered on GPU performance for TensorMaps with sectors because we have to spin up huge numbers of very small SVDs. I'm wrapping the batched SVDs each library provides to try to address this. Extremely open to comments but I wanted to get this rolling so I can unblock others.

@kshyatt
kshyatt requested review from Jutho and lkdvos August 21, 2026 14:52
@kshyatt

kshyatt commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

TODOs here:

  • Finish wrapping the BisectionBatched logic for AMD
  • Add the checks for CUSOLVER gesvdj_batched (blocks may not be larger than 32 x 32)
  • Finish the tests for svd_trunc!
  • Pullback/pushforward rules

Since I'll be out for 3 weeks everyone should feel free to just push to this.

@lkdvos lkdvos left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks great, I think the main thing I am wondering about is about the interface decision around wether we implement this as a set of BatchedAlg versions, or rather as a set of batched_f(...) functions. I definitely like using dispatch for switching between the strided and non-strided inputs, but I am wondering if there might be a benefit to really having a batched_svd_compact etc function.

This is also partially since that allows us to have a CPU version for this as well, so we can just offload all of this from TensorKit to here, (and possibly play with multithreading?).

)
summary_str = testargs_summary(T, sz)
return @testset "svd_compact! $summary_str batch_size $batch_size" begin
As = [instantiate_matrix(T, sz) for bi in 1:batch_size]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we try and vary the sizes within the batch?

Comment on lines +48 to +57
function _collect_batch(As::AbstractVector{<:AbstractMatrix})
B = similar(first(As), (size(first(As))..., length(As)))
for (i, A) in enumerate(As)
copyto!(view(B, :, :, i), A)
end
return B
end
device_batch(As::AbstractVector{<:Array}) = _collect_batch(As)
device_batch(As::AbstractVector{<:CuArray}) = _collect_batch(As)
device_batch(As::AbstractVector{<:ROCArray}) = _collect_batch(As)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the same as stack(As; dims = 3), and does that work on both devices and host arrays?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the GPU arrays don't support stack 😭


# batched varieties
function check_input(::typeof(svd_full!), A::AbstractVector{<:AbstractMatrix}, USVᴴ, ::AbstractAlgorithm)
@assert all(==(size(first(A))), size.(A))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we require the sizes to be the same? I'm assuming this is some restriction of some of the drivers, but that does kind of seems to contradict the requirements we need in TensorKit

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a limitation of the drivers, you can work around it by padding the 3D Array with zeros as needed

Comment thread src/implementations/svd.jl Outdated
@Jutho

Jutho commented Aug 24, 2026

Copy link
Copy Markdown
Member

I mostly agree with Lukas here, I think I would prefer

  • separate batched_f methods instead of separate algorithms (with possible options provided in the driver rather than the algorithm if we need those)
  • support for varying sizes, which we will anyway need to implement, so we can do it on the MAK side I would think

@kshyatt

kshyatt commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

support for varying sizes, which we will anyway need to implement, so we can do it on the MAK side I would think

This is already implemented in a separate branch I have over at TensorKit, I can move it over here of course!

@kshyatt
kshyatt marked this pull request as draft September 14, 2026 13:21
@kshyatt

kshyatt commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

Latest commit gets rid of the JacobiBatched and friends algos, and adds instead batched_svd_compact etc. Remaining TODOs:

  • Add tests for batches with varying sizes of input matrix
  • Add padding support in here, rather than in TensorKit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants