-
Notifications
You must be signed in to change notification settings - Fork 5
add support for BigFloats via a new extension #87
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
add support for BigFloats via a new extension #87
Conversation
Add extension using GenericLinearAlgebra and GenericSchur to be able to deal with `BigFloat`s
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
lkdvos
left a comment
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.
Looks really cool, very nice work!
I have a couple questions that are mostly due to the fact that I am less familiar with these packages:
Do these packages have to come together, or are they really separate entities? From a quick glance it seems like GenericSchur is being used for eig, while GenericLinearAlgebra is used for the rest. I was under the impression that GenericLinearAlgebra also had a non-symmetric eigenvalue implementation but that might be wrong.
Anyways, the reason I'm asking is because I was wondering if it would make sense to simply have one extension for each, rather than requiring both.
It looks slightly odd to me to call these algorithms BigFloat_*, since IIRC these should work for generic element types, right? How would you feel about GenericLinearAlgebra_HouseholderQR, or simply GLA_HouseholderQR etc? Similarly, I think there are some type restrictions on the functions that are might not be required.
Considering the allocation of the output, do you know if we can pass the output to the implementations of these libraries? If not, that's definitely also okay, but in that case we should probably intercept allocating them in the first place, if they will be ignored. This can be achieved by overloading initialize_output(...) -> Nothing and altering the checks accordingly.
For the tests, should we try and invest in reducing the code duplication a bit for the different algorithms? Would it make sense to simply add the eltypes to the already existing tests? This also relates to the GPU tests, @kshyatt might be interested in this as well.
I left some other comments throughout the code, but overall this looks like an amazing addition.
Co-authored-by: Lukas Devos <[email protected]>
Co-authored-by: Lukas Devos <[email protected]>
|
Re the test duplications, I think it could well make sense to do something similar to what |
|
WRT the tests, if |
Does this mean that copies are happening where they shouldn't? What happens if you use |
GenericLinearAlgebra supports the non-symmetric eigenvalue decomposition only when BigFloats aren't being used. For non-symmetric BigFloat matrices it throws an explicit error. In that regard, I would be fine with splitting this into two extensions.
The
I'll take a look whether we can support them here. Probably the higher level factorizations should be fine, but things like the Schur decomposition or |
use Hermitian() small cleanup
From GLA to GS, since eig using GenericSchur and not GenericLinearAlgebra
| m, n = size(A) | ||
| k = min(m, n) | ||
| computeR = length(R) > 0 | ||
| Q̃, R̃ = qr(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 can definitely be improved. GenericLinearAlgebra.jl has both a qrUnblocked! and a qrBlocked!. They act similar to Lapack, i.e. after calling F = qrUnblocked!(A), the elements on and above the diagonal of A (with F.factors === A) encode R, whereas the elements below the diagonal of A as well as a new vector F.τ encode the Householder reflectors that encode Q. From this, you can reconstruct both qr_compact!, qr_full! as well as qr_null!.
However, all of this is quite cryptic if you are not familiar with these ancient LAPACK storage strategies.
|
I think I have now resolved all comments, apart from the comment from @Jutho about If there are any additional comments, please let me know. |
|
I'll take a look at these comments tomorrow. As for the allocations, I agree that the current implementation is suboptimal. My points was that this requires us indeed to intercept these allocations and change the tests (something also a little bit more annoying in the case of LQ, since we are using LQViaTransposedQR for this, and we have to intercept it internally), which is work that will just have to be reverted once the issues from the external packages are resolved. |
|
I had a look at GenericSchur.jl, which I was much less familiar with than GenericLinearAlgebra.jl. That seems to reimplement a whole lot of LAPACK functionality related to Schur and eigenvalue decompositions, and so it might be possible to write the wrappers for So I think it would definitely be good to split this PR into two parts corresponding to the two extensions. GenericSchur.jl seems to provide both a In case anyone is interested in reading more about the QR iteration method, Chapter 4 in https://people.inf.ethz.ch/arbenz/ewp/Lnotes/lsevp.pdf is really good. |
Co-authored-by: Jutho <[email protected]>
Co-authored-by: Jutho <[email protected]>
Co-authored-by: Jutho <[email protected]>
Name change some copying issues resolved
GS and GLA algorithms are now defined in the docs `GLA_QR_Householder` is now `GLA_HouseholderQR` to be consistent with the LAPACK algorithms
|
I've now taken care of the 4 TODOs and the other comments. I've renamed the algorithms to After a conversation with Jutho, we concluded that we think the best way forward is to resolve the two remaining points later. E.g.,
can be another PR where new algorithms are added, and
is now partly solved by using If anyone disagrees with this approach, or has some additional suggestions, please let me know. |
|
I hope you don't mind, but I just went in and added the implementation of some of the comments that had already been discussed above and probably got overlooked, and I also simplified some of the code (based on suggestions that were already made above). Some remarks for the implementations:
|
|
Would be good to get an additional review from @Jutho before merging, but this looks good to go for me. |
|
Aside from the small comments above, I am a bit torn about is about registering these methods as the On the one hand, they probably work for a larger set of types, such as On the other hand, especially with having in mind that we might have alternative However, without these defaults in place, you would not be able to compute a matrix factorization with I am however wondering what happens if you are |
|
I addressed the remainder of the comments since I was already busy anyways. Considering the package dependency being loaded, I think your assumption is true, if anyone has this as a dependency somewhere, the code will be available and the default algorithms will be registered. What is interesting though is that GenericLinearAlgebra is definitely doing quite strong type piracy on the regular LinearAlgebra methods, and is actually simply hijacking them. In any case, I don't think changing this in upcoming releases really matters too much, and even if this counts as a breaking change, it shouldn't really trickle too far downstream anyways. |
Not at all, thanks!
I agree with Lukas here. |
They are aware of this, and there is a PR to change it (JuliaLinearAlgebra/GenericLinearAlgebra.jl#147 ) but clearly that is not what people want, since indeed everyone wants the same call to just work using the fastest algorithm irrespective of the element type. |
|
Ok, I think this is ready so I will merge. |
* Bump v0.6 * rename `gaugefix` -> `fixgauge` * reduce unnecessary warnings * fix `copy_input` signatures in Mooncake tests * Add changelog to docs
Add an extension using GenericLinearAlgebra and GenericSchur to be able to deal with
BigFloats. Some comments are in order.qr_nullandlq_nullare not implemented.qr_fullis not unique, and in the tests, I only cover the columns ofQarising from theqr_compact. The same holds for the LQ decomposition.pivoted = falseandblocksize = 1are supported. The other options throw an explicit error.===to\approx, since they would otherwis fail. I don't know whether this has an easy solution, or whether this is something that can not be enforced in the generic case.LinearAlgebra.exp!. Since it might be cleaner to only define an extension for MatrixAlgebraKit and not for TensorKit, it might be beneficial to move the definition of exp! to MatrixAlgebraKit. If there are alternatives or suggestions, please let me know.