-
Notifications
You must be signed in to change notification settings - Fork 38
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
Speedup matrix multiplications #129
base: master
Are you sure you want to change the base?
Conversation
69b4e4d
to
2915481
Compare
src/fillalgebra.jl
Outdated
*(x::ZerosMatrix, y::OnesMatrix) = mult_zeros(x, y) | ||
*(x::ZerosMatrix, y::FillMatrix) = mult_zeros(x, y) | ||
*(x::FillMatrix, y::ZerosMatrix) = mult_zeros(x, y) | ||
*(x::OnesMatrix, y::ZerosMatrix) = mult_zeros(x, y) |
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 think you are massively underestimating the number of ambiguities we need to take into account. For example we need to take into account AdjointAbsVec
, TransposeAbsVec
, AbstractTriangular
, Adjoint
, Transpose
, .... A somewhat more exhaustive list is here:
It's also a bad idea to overload Ones
and Fills
seperatly since that just means more ambiguities downstream. The following is better:
*(a::AbstractMatrix, b::AbstractFill{<:Any,2}) = fill_mul(a, b)
fill_mul(a, b::Ones) = ...
fill_mul(a, b::Zeros) = ...
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.
hopefully I addressed both concerns
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 there a chance that overloading something other than *
might be simpler, and avoid all ambiguities? They are pretty thorny, as every other package that tries to play the same game introduces new possibilities...
Without special handling, it will end up after similar
at some generic_mul!(C, A::Fill, B)
. Could one overload that instead?
Or maybe that's too late, since similar(::Filll)::Array
, but is there somewhere in the chain between *
and BLAS or whatever at which this could be caught?
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 issue is precisely what ArrayLayouts.jl is designed to avoid, and would also give us the mul!
variants. One option would be to make FillArrays.jl depend on ArrayLayouts.jl (it’s currently the other way around).
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.
Wait how does that work? Is this only if you call something special like ArrayLayouts.mul
or does it stick its fingers into ordinary A * B
?
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 would do AbstractFill <: LayoutArray
which then catches all the necessary *
ovverrides
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, got it. Overloading for one supertype stops all its children from stepping on each others' toes.
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.
although that's probably the right direction, It involves a lot of churn and the coordination of two packages, so I would merge this as it is for the time being
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 I agree.
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.
the coordination of two packages
FYI I wrote both packages so this isn't quite so bad. The only reason I haven't done this is FillArrays.jl is clean and simple, so needs a good reason to make it more complicated. I'm not sure we are there yet.
Codecov Report
@@ Coverage Diff @@
## master #129 +/- ##
==========================================
+ Coverage 91.36% 91.41% +0.05%
==========================================
Files 4 4
Lines 463 466 +3
==========================================
+ Hits 423 426 +3
Misses 40 40
Continue to review full report at Codecov.
|
dafc863
to
2766105
Compare
Now I'm testing that we have no ambiguity error when multiplying a fill by Adjoint / Transpose / Triangular / Symmetric. |
Please bump the minor version and I'll merge (needs to minor since new ambiguities counts as breaking) |
merge? |
Added a few more tests, lets see if they pass |
The tests I added picked up a ton of ambiguities. I think we also need similar tests for |
While multiplication of generic matrices by Zeros is already handled,
multiplication by Ones is not, while for Fill we only have right multiplication.
As you can from the benchmarks below, currently we have the follwing:
After this PR, we improve a lot on large matrices, but we have an hit on very small ones. I'm not sure what we should do here, maybe branch based on the input matrix size?
BEFORE this PR
AFTER this PR