-
Notifications
You must be signed in to change notification settings - Fork 5
A few more updates for GPU compatibility for TensorKit #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it only the Diagonal giving issues?
We could also just add a specialization for Diagonal in general, which we should be able to handle in a GPU friendly way:
function project_hermitian_native!(A::Diagonal, B::Diagonal, ::Val{anti}) where {anti}
if anti
diagview(A) .= imag.(diagview(B)) .* im
else
diagview(A) .= real.(diagview(B))
end
end[edit] I think we have a utility function somewhere for the imaginary part, I can't remember the name though
|
That's also fine, I wrote this in the post lunch carb coma there's probably a better way |
|
I guess the diagonal specialization is something we want anyways so that might make sense? |
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
| MatrixAlgebraKit.isantihermitian_approx(A::StridedROCMatrix; kwargs...) = | ||
| @invoke MatrixAlgebraKit.isantihermitian_approx(A::Any; kwargs...) | ||
| function MatrixAlgebraKit.isantihermitian_approx(A::Diagonal{T, <:StridedROCVector{T}}; atol, rtol, kwargs...) where {T <: Real} | ||
| return sum(abs2, A.diag) ≤ max(atol, rtol * norm(A)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a strange condition, as the left hand side is norm(A)^2, so this is saying norm(A)^2 < max(atol, rtol * norm(A))
This amounts to norm(A)^2 < atol or norm(A) < rtol, both of which look off.
Because a real diagonal matrix equals its hermitian project and has zero non-hermitian projection, I think the condition simply needs to be norm(A) < atol to be compatible with how approximate antithermiticity is checked elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, doesn't this break things in the case that atol is 0, but rtol is not? (As CI shows)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, maybe max(atol, rtol). Although that is not really equivalent. I think it is natural that this cannot be satisfied if atol is zero (except for norm(A) == 0, so it should definitely be norm(A) <= atol instead of a strictly smaller than).
But the general condition is, for a matrix A that can always be split as
A_full = A_hermitian + A_antihermitian
Then our condition for isantihermitian_approx when atol == 0 amounts to
norm(A_hermitan) <= rtol * norm(A_full)
But in the case of a real diagonal matrix, there is no anti-hermitian part and A_full == A_hermitian. So the condition above can never be satisfied (for rtol < 1, whereas it is always satisfied for rtol >= 1, which isn't really a sane choice).
|
|
||
| return USVᴴ | ||
| end | ||
| svd_full!(A::Diagonal, USVᴴ, alg::GPU_SVDAlgorithm) = svd_full!(diagm(A.diag), USVᴴ, alg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually being used? This is to cover the case where somehow a Diagonal ends up with a GPU_SVDAlgorithm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We currently don't have a DiagonalGPUAlgorithm, which is why this happens, I suppose
| MatrixAlgebraKit.ishermitian_approx(A::StridedROCMatrix; kwargs...) = | ||
| @invoke MatrixAlgebraKit.ishermitian_approx(A::Any; kwargs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this kind of definition useful? What happens if it is removed?
Co-authored-by: Jutho <[email protected]>
|
Yes, I think the max of the two tolerances is the best compromise… the
original I think was some late night coding again.
…On Wed, Nov 26, 2025 at 10:57 AM Jutho ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In ext/MatrixAlgebraKitAMDGPUExt/MatrixAlgebraKitAMDGPUExt.jl
<#100 (comment)>
:
> MatrixAlgebraKit.isantihermitian_approx(A::StridedROCMatrix; kwargs...) =
@invoke MatrixAlgebraKit.isantihermitian_approx(A::Any; kwargs...)
+function MatrixAlgebraKit.isantihermitian_approx(A::Diagonal{T, <:StridedROCVector{T}}; atol, rtol, kwargs...) where {T <: Real}
+ return sum(abs2, A.diag) ≤ max(atol, rtol * norm(A))
Ok, maybe max(atol, rtol). Although that is not really equivalent. I
think it is natural that this cannot be satisfied if atol is zero (except
for norm(A) == 0, so it should definitely be norm(A) <= atol instead of a
strictly smaller than).
But the general condition is, for a matrix A that can always be split as
A_full = A_hermitian + A_antihermitian
Then our condition for isantihermitian_approx when atol == 0 amounts to
norm(A_hermitan) <= rtol * norm(A_full)
But in the case of a real diagonal matrix, there is no anti-hermitian part
and A_full == A_hermitian. So the condition above can never be satisfied
(for rtol < 1, whereas it is always satisfied for rtol >= 1, which isn't
really a sane choice).
—
Reply to this email directly, view it on GitHub
<#100 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGKJY4OG6JXW2F6HMPUEJT36V2SDAVCNFSM6AAAAACMLW45ISVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTKMJQGEZDSMZUGE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
| @invoke MatrixAlgebraKit.isantihermitian_approx(A::Any; kwargs...) | ||
| function MatrixAlgebraKit.isantihermitian_approx(A::Diagonal{T, <:StridedROCVector{T}}; atol, rtol, kwargs...) where {T <: Real} | ||
| return sum(abs2, A.diag) ≤ max(atol, rtol * norm(A)) | ||
| return norm(A) ≤ max(atol, rtol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think just having atol in the right hand side is what we want to be compatible with what is happening for non-GPU Diagonal arrays, or for the equivalent representation of the same matrix as dense CuMatrix or ROCMatrix. In all of these cases, the general implementation will essentially amount to norm(A) <= atol when A only has nonzero entries on the diagonal, which are furthermore purely real.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if that causes test failures, I would argue the tests are incorrect.
Base.require_one_based_indexingreturns aBoolon some versions, notn(integer).Converting to the full
CuMatrix/ROCMatrixis inefficient/ugly but dispatching on aSubArrayof aDiagonalof aCuVector(orROCVector) is also really ugly. Not sure what the best approach is here, but this works for now (we can revisit if it's really problematic).