-
Notifications
You must be signed in to change notification settings - Fork 149
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 several broadcast issues (fixes #197, #199, #200, #242) #274
Conversation
Codecov Report
@@ Coverage Diff @@
## master #274 +/- ##
==========================================
+ Coverage 90.66% 90.96% +0.29%
==========================================
Files 36 36
Lines 2658 2666 +8
==========================================
+ Hits 2410 2425 +15
+ Misses 248 241 -7
Continue to review full report at Codecov.
|
Sorry about the duplicate commits. I pulled from master and rebased on master after creating this PR, and ended up having several duplicate commits. |
A part of the reason I pushed several commits is that I thought I could address #198 as well by using Ultimately, I think we need to promote types element-by-element, as discussed in JuliaLang/julia#19669. Julia 0.6 seems to support this already (even though the mentioned issue is still open), but I haven't looked into how it does in detail. |
Very nice - thanks :) Does this preserve
(Sorry, don't have a REPL to check this out right now) |
Yes it does: julia> 1 .+ SVector(1,2)'
1×2 RowVector{Int64,SVector{2,Int64}}:
2 3
julia> SVector(1,2)' .* SVector(2,3)'
1×2 RowVector{Int64,SVector{2,Int64}}:
2 6 However, I didn't intend this behavior to be honest. |
I think now I know why my code does not disturb Whenever some operation is broadcasted between @inline broadcast(f, rowvecs::Union{Number,RowVector}...) =
RowVector(broadcast(transpose∘f, to_vecs(rowvecs...)...)) This basically strips all the _containertype(::Type{<:RowVector{<:Any,<:SVector}}) = StaticArray
@inline broadcast_sizes(a::RowVector{<:Any,<:SVector}, as...) = (Size(a), broadcast_sizes(as...)...) does not play any role in this procedure and preserves However, the added code plays role when an operation is broadcasted between |
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 makes sense to me, thanks for fixing things :-)
I've added a couple of comments for consideration of adding a few minor niceties.
test/broadcast.jl
Outdated
@test_broken @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 | ||
@test_broken @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 | ||
@test @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 | ||
@test @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 |
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.
Perhaps it makes sense to remove the issue reference from these individually, and instead describe the behaviour which is being tested in a short comment. (That comment could include the issue crossref instead.)
In my opinion the source code (including comments) should be the source of truth about design decisions and the reasons for testing given behaviour: the source is a living document, but issues become abandoned as soon as they're closed.
src/mapreduce.jl
Outdated
@@ -235,7 +235,7 @@ end | |||
@generated function _diff(::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D} | |||
N = length(S) | |||
Snew = ([n==D ? S[n]-1 : S[n] for n = 1:N]...) | |||
T = Base.promote_op(-, eltype(a), eltype(a)) | |||
T = Core.Inference.return_type(-, Tuple{eltype(a),eltype(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.
IIRC calling Inference.return_type
is considered a bit of a dirty trick by the core devs ;-) If used, it can change the behaviour of code depending on optimizations to the julia inference engine. (Is this the reason to avoid it? Perhaps there's more and someone can enlighten me?).
I know we do it in another couple of places in StaticArrays
, but I think we can avoid it here by doing something like
T = typeof(one(eltype(a)) - one(eltype(a)))
or some similar such trick?
The version for _mapreducedim
further up is more tricky, because it takes an arbitrary op
in the reduction. Unlike diff
, it's not clear that the data will be numeric or that calling one(eltype(a))
makes sense in that case.
I agree with @c42f on both points, and made changes accordingly. Thanks for the comments! |
Very nice, thanks :-) |
Thanks for merging! I thought this merge would automatically close the Issues mentioned in the PR title, but it closed only the first one. I closed the last one that I opened. Could you close the middle two? |
That's great news. :) Thanks for this. |
It seems that this PR hasn't been added to a release yet. I don't know how PRs to release are selected in general, but I'm curious if there are any reasons that prevent releasing this PR. One of my packages has several parts that can be simplified using the features implemented in this PR. |
Wow, it's been a while then! I guess we can do a release? The v0.7 compatibility stuff is only half done and has made the code uglier in some places, but the tests all pass on v0.6. |
That will be great for me. Also, is there an easy way to check if some PRs have been released or not? I just searched through the release descriptions for the PR numbers, but wonder if there is an easier way. According to my search, my other merged PRs, #263 and #255, don't seem released yet, either... |
I checked my dependency https://github.com/mschauer/Bridge.jl against master and all is fine as well. |
If there is anything I could help in order to create a release with this PR, please let me know. |
This PR fixes several issues raised for
broadcast
onSArray
. Specifically,SArray
andRowVec{<:Any,SVector}
to generate anSarray
(fixes Broadcast inconsistency with Base #197, fixes Broadcast should handle transpose ofStaticVector
#200, and fixes broadcast between SMatrix{M,N} and SMatrix{M,1} (or SMatrix{1,N}) doesn't work #242), andBase
's for zero-lengthSArary
(fixes Another broadcast inconsistency with Base #199).Base.promote_op
withCore.Inference.returnt_type
, because the former infers a wrong return type of an operation when the input arguments of the operation are abstract (see https://discourse.julialang.org/t/alternatives-to-base-promote-op-op-type-for-op-type/5289/6).