From 3db225f35b58a07fb5a2177a3fe3e5d03f105769 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Fri, 5 Jun 2020 10:41:51 -0400 Subject: [PATCH 1/6] AbstractVectorOfArray broadcast overload ```julia [ Info: Precompiling RecursiveArrayTools [731186ca-8d62-57ce-b412-fbd966d074cd] Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks. Exception: EXCEPTION_ACCESS_VIOLATION at 0x6690ec5e -- jl_subtype_env at /cygdrive/d/buildbot/worker/package_win64/build/src\subtype.c:1800 in expression starting at none:0 jl_subtype_env at /cygdrive/d/buildbot/worker/package_win64/build/src\subtype.c:1800 jl_subtype at /cygdrive/d/buildbot/worker/package_win64/build/src\subtype.c:1854 [inlined] jl_isa at /cygdrive/d/buildbot/worker/package_win64/build/src\subtype.c:2056 rewrap at .\compiler\typeutils.jl:8 [inlined] matching_cache_argtypes at .\compiler\inferenceresult.jl:132 InferenceResult at .\compiler\inferenceresult.jl:12 [inlined] InferenceResult at .\compiler\inferenceresult.jl:12 [inlined] typeinf_ext at .\compiler\typeinfer.jl:572 typeinf_ext at .\compiler\typeinfer.jl:605 jfptr_typeinf_ext_1.clone_1 at C:\Users\accou\AppData\Local\Programs\Julia\Julia-1.4.1\lib\julia\sys.dll (unknown line) jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1700 [inlined] jl_type_infer at /cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:213 jl_compile_method_internal at /cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:1887 _jl_invoke at /cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2153 [inlined] jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2322 _reformat_bt at .\error.jl:90 #catch_stack#49 at .\error.jl:149 catch_stack at .\error.jl:144 [inlined] catch_stack at .\error.jl:144 [inlined] _start at .\client.jl:486 jfptr__start_2087.clone_1 at C:\Users\accou\AppData\Local\Programs\Julia\Julia-1.4.1\lib\julia\sys.dll (unknown line) unknown function (ip: 00000000004017E1) unknown function (ip: 0000000000401BD6) unknown function (ip: 00000000004013DE) unknown function (ip: 000000000040151A) BaseThreadInitThunk at C:\WINDOWS\System32\KERNEL32.DLL (unknown line) RtlUserThreadStart at C:\WINDOWS\SYSTEM32\ntdll.dll (unknown line) Allocations: 5137387 (Pool: 5136723; Big: 664); GC: 3 ``` --- src/vector_of_array.jl | 85 +++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 8a5dd1f0..18d983db 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -147,27 +147,68 @@ end VA.t,VA.u end -# Broadcast - -#add_idxs(x,expr) = expr -#add_idxs{T<:AbstractVectorOfArray}(::Type{T},expr) = :($(expr)[i]) -#add_idxs{T<:AbstractArray}(::Type{Vector{T}},expr) = :($(expr)[i]) -#= -@generated function Base.broadcast!(f,A::AbstractVectorOfArray,B...) - exs = ((add_idxs(B[i],:(B[$i])) for i in eachindex(B))...) - :(for i in eachindex(A) - broadcast!(f,A[i],$(exs...)) - end) -end - -@generated function Base.broadcast(f,B::Union{Number,AbstractVectorOfArray}...) - arr_idx = 0 - for (i,b) in enumerate(B) - if b <: ArrayPartition - arr_idx = i - break +## broadcasting + +struct VectorOfArrayStyle{Style <: Broadcast.BroadcastStyle} <: Broadcast.AbstractArrayStyle{Any} end +VectorOfArrayStyle(::S) where {S} = VectorOfArrayStyle{S}() +VectorOfArrayStyle(::S, ::Val{N}) where {S,N} = VectorOfArrayStyle(S(Val(N))) +VectorOfArrayStyle(::Val{N}) where N = VectorOfArrayStyle{Broadcast.DefaultArrayStyle{N}}() + +# promotion rules +@inline function Broadcast.BroadcastStyle(::VectorOfArrayStyle{AStyle}, ::VectorOfArrayStyle{BStyle}) where {AStyle, BStyle} + VectorOfArrayStyle(Broadcast.BroadcastStyle(AStyle(), BStyle())) +end +Broadcast.BroadcastStyle(::VectorOfArrayStyle{Style}, ::Broadcast.DefaultArrayStyle{0}) where Style<:Broadcast.BroadcastStyle = VectorOfArrayStyle{Style}() +Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() + +function Broadcast.BroadcastStyle(::Type{AbstractVectorOfArray{T,S}}) where {T, N} + VectorOfArrayStyle(Broadcast.result_style(Broadcast.BroadcastStyle(T))) +end + +@inline function Base.copy(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}) where Style + N = narrays(bc) + VectorOfArray(map(1:N) do i + copy(unpack_voa(bc, i)) + end) +end + +@inline function Base.copyto!(dest::AbstractVectorOfArray, bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}) where Style + N = narrays(bc) + @inbounds for i in 1:N + copyto!(dest[i], unpack_voa(bc, i)) end - end - :(A = similar(B[$arr_idx]); broadcast!(f,A,B...); A) + dest end -=# + +## broadcasting utils + +""" + narrays(A...) + +Retrieve number of arrays in the AbstractVectorOfArrays of a broadcast +""" +narrays(A) = 0 +narrays(A::AbstractVectorOfArray) = length(A) +narrays(bc::Broadcast.Broadcasted) = _narrays(bc.args) +narrays(A, Bs...) = common_length(narrays(A), _narrays(Bs)) + +common_length(a, b) = + a == 0 ? b : + (b == 0 ? a : + (a == b ? a : + throw(DimensionMismatch("number of arrays must be equal")))) + +@inline _narrays(args::Tuple) = common_length(narrays(args[1]), _narrays(Base.tail(args))) +_narrays(args::Tuple{Any}) = _narrays(args[1]) +_narrays(args::Tuple{}) = 0 + +# drop axes because it is easier to recompute +@inline unpack_voa(bc::Broadcast.Broadcasted{Style}, i) where Style = Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) +@inline unpack_voa(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}, i) where Style = Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) +unpack_voa(x,::Any) = x +unpack_voa(x::AbstractVectorOfArray, i) = x[i] +unpack_voa(x::AbstractArray{T,N}, i) where {T,N} = @view x[ntuple(x->Colon(),N-1)...,i] + +@inline unpack_args_voa(i, args::Tuple) = (unpack_voa(args[1], i), unpack_args_voa(i, Base.tail(args))...) +unpack_args_voa(i, args::Tuple{Any}) = (unpack_voa(args[1], i),) +unpack_args_voa(::Any, args::Tuple{}) = () From 229e61cf13d2a3b6bd7fa64daf762d1ea2aa04c7 Mon Sep 17 00:00:00 2001 From: Yingbo Ma Date: Fri, 5 Jun 2020 11:22:48 -0400 Subject: [PATCH 2/6] Fix function parameters --- src/vector_of_array.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 18d983db..7c66c58d 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -161,7 +161,7 @@ end Broadcast.BroadcastStyle(::VectorOfArrayStyle{Style}, ::Broadcast.DefaultArrayStyle{0}) where Style<:Broadcast.BroadcastStyle = VectorOfArrayStyle{Style}() Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() -function Broadcast.BroadcastStyle(::Type{AbstractVectorOfArray{T,S}}) where {T, N} +function Broadcast.BroadcastStyle(::Type{AbstractVectorOfArray{T,S}}) where {T, S} VectorOfArrayStyle(Broadcast.result_style(Broadcast.BroadcastStyle(T))) end From 1a0fcfd6c6a61c5f2ddfb5d702500e65b33f355f Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Fri, 5 Jun 2020 15:24:19 -0400 Subject: [PATCH 3/6] close --- src/vector_of_array.jl | 9 +++++++-- test/basic_indexing.jl | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 7c66c58d..34cf990b 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -161,12 +161,16 @@ end Broadcast.BroadcastStyle(::VectorOfArrayStyle{Style}, ::Broadcast.DefaultArrayStyle{0}) where Style<:Broadcast.BroadcastStyle = VectorOfArrayStyle{Style}() Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() -function Broadcast.BroadcastStyle(::Type{AbstractVectorOfArray{T,S}}) where {T, S} +function Broadcast.BroadcastStyle(::Type{<:AbstractVectorOfArray{T,S}}) where {T, S} VectorOfArrayStyle(Broadcast.result_style(Broadcast.BroadcastStyle(T))) end @inline function Base.copy(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}) where Style N = narrays(bc) + @show "here" + x = unpack_voa(bc, 1) + @show x + @show copy(x) VectorOfArray(map(1:N) do i copy(unpack_voa(bc, i)) end) @@ -198,6 +202,7 @@ common_length(a, b) = (a == b ? a : throw(DimensionMismatch("number of arrays must be equal")))) +_narrays(args::AbstractVectorOfArray) = length(args) @inline _narrays(args::Tuple) = common_length(narrays(args[1]), _narrays(Base.tail(args))) _narrays(args::Tuple{Any}) = _narrays(args[1]) _narrays(args::Tuple{}) = 0 @@ -206,7 +211,7 @@ _narrays(args::Tuple{}) = 0 @inline unpack_voa(bc::Broadcast.Broadcasted{Style}, i) where Style = Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) @inline unpack_voa(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}, i) where Style = Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) unpack_voa(x,::Any) = x -unpack_voa(x::AbstractVectorOfArray, i) = x[i] +unpack_voa(x::AbstractVectorOfArray, i) = x.u[i] unpack_voa(x::AbstractArray{T,N}, i) where {T,N} = @view x[ntuple(x->Colon(),N-1)...,i] @inline unpack_args_voa(i, args::Tuple) = (unpack_voa(args[1], i), unpack_args_voa(i, Base.tail(args))...) diff --git a/test/basic_indexing.jl b/test/basic_indexing.jl index c7a06824..ec4b6cd2 100644 --- a/test/basic_indexing.jl +++ b/test/basic_indexing.jl @@ -1,4 +1,4 @@ -using RecursiveArrayTools +using RecursiveArrayTools, Test # Example Problem recs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] @@ -86,3 +86,5 @@ v = VectorOfArray([zeros(20), zeros(10,10), zeros(3,3,3)]) v[CartesianIndex((2, 3, 2, 3))] = 1 @test v[CartesianIndex((2, 3, 2, 3))] == 1 @test v.u[3][2, 3, 2] == 1 + +v .* v From 5fdec8fb144da5bcb14b5729064c70e5569c4307 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Fri, 5 Jun 2020 15:31:34 -0400 Subject: [PATCH 4/6] almost done, tests are done, in-place is good --- src/vector_of_array.jl | 3 --- test/basic_indexing.jl | 11 ++++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 34cf990b..e5d6e0dc 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -167,10 +167,7 @@ end @inline function Base.copy(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}) where Style N = narrays(bc) - @show "here" x = unpack_voa(bc, 1) - @show x - @show copy(x) VectorOfArray(map(1:N) do i copy(unpack_voa(bc, i)) end) diff --git a/test/basic_indexing.jl b/test/basic_indexing.jl index ec4b6cd2..df45fbfb 100644 --- a/test/basic_indexing.jl +++ b/test/basic_indexing.jl @@ -87,4 +87,13 @@ v[CartesianIndex((2, 3, 2, 3))] = 1 @test v[CartesianIndex((2, 3, 2, 3))] == 1 @test v.u[3][2, 3, 2] == 1 -v .* v +v = VectorOfArray([rand(20), rand(10,10), rand(3,3,3)]) +w = v .* v +@test w isa VectorOfArray +@test w[1] isa Vector +@test w[1] == v[1] .* v[1] +@test w[2] == v[2] .* v[2] +@test w[3] == v[3] .* v[3] +x = copy(v) +x .= v .* v +@test all(x .== w) From b22f74f8efedc3e13b6b531f58ad64670df5451f Mon Sep 17 00:00:00 2001 From: Yingbo Ma Date: Fri, 5 Jun 2020 15:54:28 -0400 Subject: [PATCH 5/6] Move style computation to runtime --- src/vector_of_array.jl | 25 ++++++++++++------------- test/basic_indexing.jl | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index e5d6e0dc..8e1f12f7 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -149,23 +149,22 @@ end ## broadcasting -struct VectorOfArrayStyle{Style <: Broadcast.BroadcastStyle} <: Broadcast.AbstractArrayStyle{Any} end -VectorOfArrayStyle(::S) where {S} = VectorOfArrayStyle{S}() -VectorOfArrayStyle(::S, ::Val{N}) where {S,N} = VectorOfArrayStyle(S(Val(N))) -VectorOfArrayStyle(::Val{N}) where N = VectorOfArrayStyle{Broadcast.DefaultArrayStyle{N}}() +struct VectorOfArrayStyle <: Broadcast.AbstractArrayStyle{Any} end +VectorOfArrayStyle(::Any) = VectorOfArrayStyle() +VectorOfArrayStyle(::Any, ::Any) = VectorOfArrayStyle() # promotion rules -@inline function Broadcast.BroadcastStyle(::VectorOfArrayStyle{AStyle}, ::VectorOfArrayStyle{BStyle}) where {AStyle, BStyle} - VectorOfArrayStyle(Broadcast.BroadcastStyle(AStyle(), BStyle())) -end -Broadcast.BroadcastStyle(::VectorOfArrayStyle{Style}, ::Broadcast.DefaultArrayStyle{0}) where Style<:Broadcast.BroadcastStyle = VectorOfArrayStyle{Style}() -Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() +#@inline function Broadcast.BroadcastStyle(::VectorOfArrayStyle{AStyle}, ::VectorOfArrayStyle{BStyle}) where {AStyle, BStyle} +# VectorOfArrayStyle(Broadcast.BroadcastStyle(AStyle(), BStyle())) +#end +Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.BroadcastStyle) = VectorOfArrayStyle() +#Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() function Broadcast.BroadcastStyle(::Type{<:AbstractVectorOfArray{T,S}}) where {T, S} - VectorOfArrayStyle(Broadcast.result_style(Broadcast.BroadcastStyle(T))) + VectorOfArrayStyle() end -@inline function Base.copy(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}) where Style +@inline function Base.copy(bc::Broadcast.Broadcasted{VectorOfArrayStyle}) N = narrays(bc) x = unpack_voa(bc, 1) VectorOfArray(map(1:N) do i @@ -173,7 +172,7 @@ end end) end -@inline function Base.copyto!(dest::AbstractVectorOfArray, bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}) where Style +@inline function Base.copyto!(dest::AbstractVectorOfArray, bc::Broadcast.Broadcasted{VectorOfArrayStyle}) N = narrays(bc) @inbounds for i in 1:N copyto!(dest[i], unpack_voa(bc, i)) @@ -206,7 +205,7 @@ _narrays(args::Tuple{}) = 0 # drop axes because it is easier to recompute @inline unpack_voa(bc::Broadcast.Broadcasted{Style}, i) where Style = Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) -@inline unpack_voa(bc::Broadcast.Broadcasted{VectorOfArrayStyle{Style}}, i) where Style = Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) +@inline unpack_voa(bc::Broadcast.Broadcasted{VectorOfArrayStyle}, i) = Broadcast.Broadcasted(bc.f, unpack_args_voa(i, bc.args)) unpack_voa(x,::Any) = x unpack_voa(x::AbstractVectorOfArray, i) = x.u[i] unpack_voa(x::AbstractArray{T,N}, i) where {T,N} = @view x[ntuple(x->Colon(),N-1)...,i] diff --git a/test/basic_indexing.jl b/test/basic_indexing.jl index df45fbfb..198b47fb 100644 --- a/test/basic_indexing.jl +++ b/test/basic_indexing.jl @@ -96,4 +96,4 @@ w = v .* v @test w[3] == v[3] .* v[3] x = copy(v) x .= v .* v -@test all(x .== w) +@test x.u == w.u From d77105ab1ac63b8bb9cfc7881469d8d7e9fc16cb Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Fri, 5 Jun 2020 20:47:25 -0400 Subject: [PATCH 6/6] fix ambiguity --- src/vector_of_array.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 8e1f12f7..97527124 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -158,7 +158,7 @@ VectorOfArrayStyle(::Any, ::Any) = VectorOfArrayStyle() # VectorOfArrayStyle(Broadcast.BroadcastStyle(AStyle(), BStyle())) #end Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.BroadcastStyle) = VectorOfArrayStyle() -#Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() +Broadcast.BroadcastStyle(::VectorOfArrayStyle, ::Broadcast.DefaultArrayStyle{N}) where N = Broadcast.DefaultArrayStyle{N}() function Broadcast.BroadcastStyle(::Type{<:AbstractVectorOfArray{T,S}}) where {T, S} VectorOfArrayStyle()