-
-
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 #18974 (promotion in sparse unary broadcast methods) #18975
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1635,3 +1635,12 @@ let | |
@test isa(abs.(A), SparseMatrixCSC) # representative for _unary_nz2nz_z2z class | ||
@test isa(exp.(A), Array) # representative for _unary_nz2nz_z2nz class | ||
end | ||
|
||
# Check that `broadcast` methods specialized for unary operations over | ||
# `SparseMatrixCSC`s determine a reasonable return element type. (Issue #18974.) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #19065 didn't have a test, should this be added? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, will prepare a short PR. Thanks for the reminder! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
let | ||
A = spdiagm(Int64(1):Int64(4)) | ||
@test isa(eltype(expm1.(A)), Float64) # representative for _unary_nz2nz_z2z class | ||
@test isa(eltype(exp.(A)), Float64) # representative for _unary_nz2nz_z2nz class | ||
@test isa(eltype(sin.(A)), Float64) # representative for _unary_nz2z_z2z class | ||
end |
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.
Wouldn't it be better to call
broadcast(f, A.nzval)
and just pass the resulting array? That way we re-use the type computations inbroadcast
(which are more sophisticated thanpromote_op
for non-empty arrays).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.
For
nz2nz_z2z
that would probably make sense. I think there was a different issue that discussed removing thenz2z_z2z
class.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.
Even for
nz2z_z2z
you could usebroadcast(f, A.nzval)
and filter out zeros. You could even do it in-place (with aresize!
at the end), without wasting much memory if the fraction of zeros introduced is small.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.
Great idea that. Another rewrite of sparse unary broadcast is on my agenda. Would you prefer to (1) merge this PR as an interim fix or (2) close this PR and incorporate a better fix for #18974 (specifically your suggestion) as part of that rewrite? Thanks!
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'd prefer to focus on fixing
broadcast
generally for sparse-matrix types, since an interim solution is not urgent.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.
@stevengj, I benchmarked two versions of your suggestion (for nz2nz_z2z-class unary operations). The overhead from calling
broadcast(f, view(A.nzval, 1:nnz(A)))
(and to a lesser degreebroadcast(f, A.nzval)
) seems substantial for small to moderate size sparse matrices. Thoughts? (Benchmarks below). Best!yields
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.
That's odd, when I've tried broadcast on any non-tiny array it's usually nearly as fast as a manual loop. Can you drill down to find the source of the slowdown?
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.
Drilling down a bit. What is your metric for tiny? Best! (Edit: I originally forgot to interpolate globals in the benchmarks below. Fixing that substantially decreased the performance gap. Perhaps something went amiss with the benchmarks above as well... (Edit edit: No, the benchmarks above were correct. Mystery elsewhere.))
yields
(Julia Commit 438d1ea (2016-10-22 07:39 UTC) / Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz)
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.
Mystery solved. Specialization on the type of the function being broadcast is not occurring:
yields
So with forced specialization this approach performs well, though using a view incurs some overhead. Should forcing specialization be necessary? Best!
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.
@JeffBezanson, this seems like undesirable behavior; I don't think we want
<:Function
to be necessary to get good performance in higher-order functions?