-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Fix type instability in generic matmul #14722
Conversation
LGTM |
The RootInt type in one of the tests doesn't have |
@@ -524,10 +525,11 @@ function _generic_matmatmul!{T,S,R}(C::AbstractVecOrMat{R}, tA, tB, A::AbstractV | |||
if tB == 'N' | |||
for i = 1:mA, j = 1:nB | |||
if isempty(A) || isempty(B) | |||
Ctmp = zero(R) | |||
z2 = zero(T)*zero(S) + zero(T)*zero(S) |
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.
If A or B is empty, maybe we could just skip the loop entirely and fill!(C, zero(R))
?
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 think this check can then be moved outside the transpose branches which will make the code a bit shorter and simpler.
I.e. check for non-emptiness and then use the elements of the arrays instead of the array element types? |
can this be tested against via |
On the zero issue, there's no mathematical reason to prevent defining |
Also make sure that intermediate values are promoted to the output type
f870d93
to
10d4d2c
Compare
Updated to:
|
A2 = rand(Float64, 6, 6) | ||
B2 = rand(Float64, 6, 6) | ||
A_mul_B!(C1, A1, B1) | ||
@test @allocated(A_mul_B!(C1, A1, B1)) == @allocated(A_mul_B!(C2, A2, B2)) |
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 fails when inlining is off https://build.julialang.org/builders/coverage_ubuntu14.04-x64/builds/404/steps/Run%20non-inlined%20tests/logs/stdio
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.
Bump! This is still blocking coverage. https://build.julialang.org/builders/coverage_ubuntu14.04-x64/builds/461/steps/Run%20non-inlined%20tests/logs/stdio
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.
Sorry, I totally missed this the first time around. Filed #17327 to revert the test. Will look into adding a benchmark instead tomorrow.
This test apparently breaks with inlining disabled.
Remove test for #14722 (type instability in generic matmul)
In JuliaLang/julia#14722, I fixed an issue where the inner loop was type-unstable. This benchmark ensures that doesn't regress.
In JuliaLang/julia#14722, I fixed an issue where the inner loop was type-unstable. This benchmark ensures that doesn't regress.
This test apparently breaks with inlining disabled.
For
C::AbstractVecOrMat{R}
,A::AbstractVecOrMat{T}
,B::AbstractVecOrMat{S}
, we were sometimes initializing the intermediate sum aszero(R)
, but it wouldn't stay that way ifR
was narrower thanT
andS
.This promotes the intermediate sums (
s
andCtmp
in the code) to the promotion ofR
andzero(T)*zero(S) + zero(T)*zero(S)
. Thus, forA_mul_B!(C::Matrix{Float32}, A::Matrix{Float64}, B::Matrix{Float64}
, the intermediate sums are Float64. The other possibility would be to enforce that the intermediate sums are the same type asR
(i.e. Float32 in this example) but it seemed more conservative to potentially use higher precision than lower precision.Before:
After: