Skip to content
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

Optimized arithmetic methods for strided triangular matrices #52571

Merged
merged 13 commits into from
Dec 30, 2023

Conversation

jishnub
Copy link
Contributor

@jishnub jishnub commented Dec 18, 2023

This uses broadcasting for operations like A::UpperTriangular + B::UpperTriangular in case the parents are StridedMatrixes. Looping only over the triangular part is usually faster for large matrices, where presumably memory is the bottleneck.

Some performance comparisons, using

julia> U = UpperTriangular(rand(1000,1000));

julia> U1 = UnitUpperTriangular(rand(size(U)...));
Operation master PR
-U 1.011 ms (3 allocations: 7.63 MiB) 559.680 μs (3 allocations: 7.63 MiB)
U + U/U - U 971.740 μs (3 allocations: 7.63 MiB) 560.063 μs (3 allocations: 7.63 MiB)
U + U1/U - U1 3.014 ms (9 allocations: 22.89 MiB) 944.772 μs (3 allocations: 7.63 MiB)
U1 + U1 4.509 ms (12 allocations: 30.52 MiB) 1.687 ms (3 allocations: 7.63 MiB)
U1 - U1 3.357 ms (9 allocations: 22.89 MiB) 1.763 ms (3 allocations: 7.63 MiB)

I've retained the existing methods as fallback, in case there's current code that works without broadcasting.

@jishnub jishnub added domain:linear algebra Linear algebra domain:arrays [a, r, r, a, y, s] labels Dec 18, 2023
@dkarrasch dkarrasch added the performance Must go faster label Dec 19, 2023
Copy link
Member

@dkarrasch dkarrasch left a comment

Choose a reason for hiding this comment

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

LGTM

jishnub added a commit that referenced this pull request Dec 25, 2023
Since the values stored in the parent corresponding to the structural
zeros of a tridiagonal matrix aren't well-defined, using it in `ldiv!`
is a footgun that may lead to heisenbugs (one seen in
https://buildkite.com/julialang/julia-master/builds/31285#018c7cc7-6c77-41ac-a01b-1c7d14cb1b15).
This PR changes it to using the tridiagonal matrix directly in `ldiv!`,
which should lead to predictable results, and be bug-free. The failing
tests for #52571 pass locally with this change.
@jishnub
Copy link
Contributor Author

jishnub commented Dec 26, 2023

Although this PR improves performance and resolves several issues, I don't really like the hacky nature of the new methods that are specifically working around bugs with using a partly initialized A.data. However, perhaps there is existing code that works correctly without broadcasting, so we may need to retain the general methods that forward the arithmetic operations to the parent.

@dkarrasch
Copy link
Member

Ready to go? I still like it. 😉

@jishnub
Copy link
Contributor Author

jishnub commented Dec 30, 2023

Looks good to me. Perhaps we should update the branch to ensure that the tests are passing? Unfortunately my computer has broken down, so progress has stalled

@dkarrasch dkarrasch added the status:merge me PR is reviewed. Merge when all tests are passing label Dec 30, 2023
@jishnub
Copy link
Contributor Author

jishnub commented Dec 30, 2023

Test failures appear unrelated, so should be good

@dkarrasch dkarrasch merged commit 89cae45 into master Dec 30, 2023
6 of 8 checks passed
@dkarrasch dkarrasch deleted the jishnub/tristrided branch December 30, 2023 17:08
@dkarrasch dkarrasch removed the status:merge me PR is reviewed. Merge when all tests are passing label Dec 30, 2023
KristofferC pushed a commit that referenced this pull request Jan 5, 2024
Since the values stored in the parent corresponding to the structural
zeros of a tridiagonal matrix aren't well-defined, using it in `ldiv!`
is a footgun that may lead to heisenbugs (one seen in
https://buildkite.com/julialang/julia-master/builds/31285#018c7cc7-6c77-41ac-a01b-1c7d14cb1b15).
This PR changes it to using the tridiagonal matrix directly in `ldiv!`,
which should lead to predictable results, and be bug-free. The failing
tests for #52571 pass locally with this change.

(cherry picked from commit ef549ae)
KristofferC pushed a commit that referenced this pull request Jan 5, 2024
Since the values stored in the parent corresponding to the structural
zeros of a tridiagonal matrix aren't well-defined, using it in `ldiv!`
is a footgun that may lead to heisenbugs (one seen in
https://buildkite.com/julialang/julia-master/builds/31285#018c7cc7-6c77-41ac-a01b-1c7d14cb1b15).
This PR changes it to using the tridiagonal matrix directly in `ldiv!`,
which should lead to predictable results, and be bug-free. The failing
tests for #52571 pass locally with this change.

(cherry picked from commit ef549ae)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:arrays [a, r, r, a, y, s] domain:linear algebra Linear algebra performance Must go faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants