-
Notifications
You must be signed in to change notification settings - Fork 41
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
Generalize StructArray
's broadcast.
#215
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This is great! I've left a few comments: some are just about coding style, other about checking that we don't do unnecessary allocations. The example in the comment above is very nice. Btw, does |
Caused by displaying. If I add |
c4e7a03
to
a92bc41
Compare
2e2993f
to
f8c988e
Compare
What's the status of this work? Perhaps overlapping, what JuliaDiff/ChainRules.jl#644 would like is broadcasts like this: julia> function _tuplecast(f::F, args...) where {F}
bc = Broadcast.instantiate(Broadcast.broadcasted(f, args...))
return StructArrays.components(StructArray(bc))
end;
julia> _tuplecast(tuple, [1,2,3], [3,4,5])
([1, 2, 3], [3, 4, 5])
julia> _tuplecast(tuple, cu([1,2,3]), cu([3,4,5]))
ERROR: Scalar indexing is disallowed.
...julia
[9] iterate
@ ./broadcast.jl:261 [inlined]
[10] iterate(bc::Base.Broadcast.Broadcasted{JLArrays.JLArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(tuple), Tuple{JLArray{Int64, 1}, JLArray{Int64, 1}}})
@ Base.Broadcast ./broadcast.jl:255
[11] collect_structarray(itr::Base.Broadcast.Broadcasted{JLArrays.JLArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(tuple), Tuple{JLArray{Int64, 1}, JLArray{Int64, 1}}}; initializer::StructArrays.StructArrayInitializer{typeof(StructArrays.alwaysfalse), typeof(StructArrays.arrayof)})
@ StructArrays ~/.julia/packages/StructArrays/xGn32/src/collect.jl:39 There is now a GPUArraysCore.jl if this helps. |
I haven't paid attention to our GPU ecosystem for a long time. function _tuplecast(f::F, args...) where {F}
bc = Broadcast.instantiate(Broadcast.broadcasted(f, args...))
return StructArrays.components(copy(convert(Broadcasted{StructArrayStyle{BroadcastStyle(bc),ndims(bc)}}, bc)))
end |
Now the GPU patch is pending JuliaGPU/GPUArrays.jl#420. julia> a = @SMatrix [float(i) for i in 1:4, j in 1:4];
julia> b = @SMatrix [float(j) for i in 1:4, j in 1:4];
julia> s = StructArray{ComplexF64}((a , b))
4×4 StructArray(::SMatrix{4, 4, Float64, 16}, ::SMatrix{4, 4, Float64, 16}) with eltype ComplexF64 with indices SOneTo(4)×SOneTo(4):
1.0+1.0im 1.0+2.0im 1.0+3.0im 1.0+4.0im
2.0+1.0im 2.0+2.0im 2.0+3.0im 2.0+4.0im
3.0+1.0im 3.0+2.0im 3.0+3.0im 3.0+4.0im
4.0+1.0im 4.0+2.0im 4.0+3.0im 4.0+4.0im
julia> abs.(s)
4×4 SMatrix{4, 4, Float64, 16} with indices SOneTo(4)×SOneTo(4):
1.41421 2.23607 3.16228 4.12311
2.23607 2.82843 3.60555 4.47214
3.16228 3.60555 4.24264 5.0
4.12311 4.47214 5.0 5.65685
julia> log.(s) # Yes, this return a StructArray now!
4×4 StructArray(::SMatrix{4, 4, Float64, 16}, ::SMatrix{4, 4, Float64, 16}) with eltype ComplexF64 with indices SOneTo(4)×SOneTo(4):
0.346574+0.785398im 0.804719+1.10715im 1.15129+1.24905im 1.41661+1.32582im
0.804719+0.463648im 1.03972+0.785398im 1.28247+0.982794im 1.49787+1.10715im
1.15129+0.321751im 1.28247+0.588003im 1.44519+0.785398im 1.60944+0.927295im
1.41661+0.244979im 1.49787+0.463648im 1.60944+0.643501im 1.73287+0.785398im I think @mcabbott might be happy with this feature (As we might pass |
Now we drop dependency on |
4743976
to
2644c24
Compare
@piever Should be ready to review. The only concern is |
Thanks for pushing for all the downstream changes, I'll try to find time to review in the next few days.
I confess I'm not sure I 100% I understand what happens there. When exactly does the extra allocation happen for |
Yes, At present, since we drop the dependency, we have to have this Once we have more tools in |
Sorry it took me a long time to review this! It mostly looks good. The main worry is whether there is a performance hit in the general case due to the overload of Performance issues on things that didn't work before (like the case with |
44f18d5
to
cd32b53
Compare
This overloading is limited to
I have avoid possible nested combine_style_types(::StructArrayStyle{S}) where {S} = S() # avoid nested StructArrayStyle And #249 has been pull in to test it. |
We first call broadcast from `StaticArrays` then split the output. This should has no extra runtime overhead. But some type info might missing because the eltype change. I think there's no better ways as we don't want to depend on the full `StaticArrays`. We don't overloading `Size` and `similar_type` at present. as they are only used for `broadcast`. With this, we can move much less code to `StaticArraysCore`. The only downside is that SizedArray would be allocated twice. That's not idea, but we can't do any better if we don't depend on StaticArray or copy a lot of code from there.
Co-Authored-By: Pietro Vertechi <[email protected]>
Sorry for the delay between reviews! I confess some of the code is a bit over my head, but (other than the small comments above) it looks good to me! |
1. Update Project.toml. 2. test `backend`'s inferability. Co-Authored-By: Pietro Vertechi <[email protected]>
test/runtests.jl
Outdated
try | ||
d = StructArray{ComplexF64}((a.re .+ b.re .- c.re, a.im .+ b.im .- c.im)) | ||
@test typeof(a .+ b .- c) == typeof(d) | ||
catch | ||
@test_throws MethodError a .+ b .- c | ||
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.
This had escaped me before, but I'm wondering: could it be possible to be explicit here on which it is (correct result or method error) based on the input types?
Ideally one would want to explicitly test what one is getting, so I would suggest to remove the helper function _test_similar
and just write something like
if s2 in (s, s′, s″) && (s1 in (s, s′, s″) || s3 in (s, s′, s″))
# test method error
else
# test correct result
end
in the loop body.
(I'm not sure whether that's the correct criterion.)
only test each dest style once.
Perfect, thanks for bringing this over the finish line! |
Seperated from #211
The final goal is to enable GPU broadcast. (close #150)
GPU related:
broadcast
implement. Use style dispatch in broadcast(!) JuliaGPU/GPUArrays.jl#393GPUArrays.backend
toAdapts.jl
GPUArraysCore.jl