-
-
Notifications
You must be signed in to change notification settings - Fork 8
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
A_mul_B and all that jazz #57
Comments
If we get rid of these functions, am I right to assume we'll be pushing information into the type system using transpose types and conjugate types? |
I think that would depend quite strongly on how #42 is resolved. |
Because I develop iterative methods that require a lot of numerical linear algebra within each iteration, I want to be careful about reusing existing storage when possible. Hence I find these mutating functions to be worthwhile. I could always write them as direct calls to functions in the BLAS or LAPACK modules but this makes the code harder to read for those who didn't grow up needing to know Lapack calling sequences as I did. However, I would be amenable to hiding all these functions in the Base namespace and only exporting the non-mutating versions that are called when expressions like |
I think only export non-mutating versions is the right choice. What about the transposed multiply operators? Should those also not be exported by default? I would be ok with removing the For the stuff with lazy array views, we should wait until we get there, or else we will see a performance degradation. At that point, I would expect that we can get rid of the transposed multiply and divide operators. |
To me, it seems like it would be better to wait until we have a general tool for expressing mutating operations before removing these functions. |
I am only giving a |
Ok. That makes sense to me, although I'd think there's something to be said for keeping an eyesore around as a reminder that we need a cleaner solution. |
There is some value to eyesore, but keeping it around longer means more people use it thinking it is a supported API and makes it difficult to remove in the future. |
Very true. |
Time for an @Embarrassing macro? |
Yesterday I found out that
because
causing the transpose to be calculated before the multiplication. I think that @johnmyleswhite's proposal sounds like the right one. It could eliminate all the |
I believe the problem with the transpose type (which somebody else proposed before me and I just brought up again) is that we're not sure how to implement it for higher-order tensors. |
Another suggestion would be to follow more closely the BLAS approach and have a single function with additional arguments 'N', 'T' and 'C' specifying the multiplication pattern. This of course only shifts the problem to branching within the method, and probably calling all of the above functions anyway, but the advantage is that only a single function needs to be exported and documented. Occasionally I regret that the mutating multiplication functions in Julia do not more closely resemble the BLAS design, i.e. not only allow to store the result of the multiplication in a given array, but actually add the result to it. I guess there has been some thought in the BLAS design, and it would be great if Julia could generalise this functionality (i.e. matrices with no stride 1, different types of dense and sparse matrices, ...) without sacrificing the existing functionality. I know that gemm and gemv are available within Base.LinAlg.BLAS , but if you define a new type hierarchy, say AbstractLinearOperator, for sparse linear operators for use in an iterative linear solver or eigensolver, then you want to implement a method A_mul_B! for its concrete subtypes. If you would allow to actually add the result of the matrix vector multiplication to a given vector in this method, then you could also define a SumOfLinearOperators <: AbstractLinearOperator type, define + for any AbstractLinearOperator to return a SumOfLinearOperators which just keeps track of the different AbstractLinearOperator terms, and implements A_mul_B! for an input vector by calling A_mul_B! sequentially on all the terms, thereby adding the result and not having to create any copies. |
Getting rid of these is one of my top wishlist items. We can even have |
I just telling someone today how these methods are one of the main weak points of Julia's otherwise amazing design for linear algebra. |
JuliaLang/julia#6837 is step one, right? |
@andreasnoack Any update here? |
Not yet. I'll give an update on this after the weekend. |
I've pushed a version that eliminates all the However, this hurts compilation time significantly. With the new version, the |
Anything you could add to |
My impression is that precompilation is actaully slower that "normal" compilation so I'd expect that the total compile time would be longer although the time in the tests might be shorter. |
It would certainly also be helpful to understand the needs of the ML folks before taking a final call on many of the open linalg issues. That would put these improvements squarely past 1.0, and that may be ok. cc @MikeInnes |
I will link the CUBLAS wrappers. You can see that there's a fair bit of redundancy with Base; given that CUBLAS has an identical api to blas, ideally we'd just swap out the final That said it does work fine at present, and I expect that things will be improved with whatever changes are made – reducing the redundancy would just be icing. I think it's actually a bigger deal for AD, where we have to code a derivative for every |
Is there some way we can isolate Base from this change? The special lowering to these function names is an issue, but it would be possible to provide the fallbacks and then override them in the future, which would leave the unfortunate lowering hack but would allow this to be fixed in the future. |
Related: JuliaLang/julia#23424. |
Our options at this point are:
|
Noted. :) |
For what it's worth, I think this is more crucial than getting the indexing with associatives stuff sorted. The main action item there would simply be to iterate dictionaries by value. The most conservative potential change for 0.7 would be to just deprecate dict iteration altogether and force explicit choice of iteration by |
The more I think about it, the more I like the idea of requiring |
What does that have to do with A_mul_b and all that jazz? |
Because we're collectively prioritizing @andyferris's discretionary time and open-source efforts 😆 |
@StefanKarpinski I came to the same conclusion - if someone else wants to volunteer for a @JeffBezanson Getting even more off topic, I still feel the answer lies in what you want @vtjnash Yes, it's a bit convoluted how this conversation ended up here! 😄 |
Please take off-topic remarks elsewhere. This thread is about making implementations of A_mul_b better, not about making Associative worse. |
As explained, these are not off-topic and have to do with work prioritization which affects this issue. |
Linking this analysis of paths to addressing this issue by 1.0. Best! |
These functions have been removed 🎉 so I think we can close this. |
The purpose of this issue is to discuss the future of the dozens of functions in Julia that are slight variations of matrix multiplication, matrix division and backslash. I presume that the point was to have fine-grained control over the use of matrix variables and temporaries when needed. However, I don't understand why the availability of these functions is so inconsistent: is this intentional design or a consequence of organic growth with methods being implemented as needed?
List of all the functions (existing and plausibly existing in the future)
Here are the 3x3x3x2=54 possible functions that can be constructed out of A, its transpose At and its Hermitian conjugate Ac; and similarly for B, Bt and Bc; mul, rdiv and ldiv; and mutating and non-mutating variants. (
###
means that this function does not exist.)I'm rocking this boat because it's come up as a natural consequence of systematically making methods available for special matrix types.
Specific issues
2 Growth and proliferation. Do we foresee an eventual future where all 54-3=51 functions (omitting the synonyms for
*
,/
and\
) become defined and have methods implemented? There would a great many methods that would have to be implemented to cover all the possible types of matrices that currently exist.Ac
and
Bt
, for example; however, this is a somewhat rare but entirely plausible combination to operate on. Do we care?Base
without reason is not ideal, but conversely these functions form a coherent grouping for which it doesn't make sense to have some but not others.cc: @JeffBezanson @StefanKarpinski @andreasnoackjensen @dmbates @lindahua
The text was updated successfully, but these errors were encountered: