From 30aa369e634c7615d8ac014026e766486a6cb7cd Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Fri, 29 Jul 2022 18:01:41 -0600 Subject: [PATCH 01/10] no reduce --- src/componentarray.jl | 12 +++++++++--- src/utils.jl | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index ea09fa84..cb04a446 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -138,12 +138,18 @@ make_carray_args(::NamedTuple{(), Tuple{}}) = (Any[], FlatAxis()) make_carray_args(::Type{T}, ::NamedTuple{(), Tuple{}}) where {T} = (T[], FlatAxis()) function make_carray_args(nt) data, ax = make_carray_args(Vector, nt) - data = length(data)==1 ? [data[1]] : reduce(vcat, data) + data = length(data)==1 ? [data[1]] : eltype(data) == Any ? reduce(vcat, data) : data return (data, ax) end make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) function make_carray_args(A::Type{<:AbstractArray}, nt) - data, idx = make_idx([], nt, 0) + init = try + T = recursive_type(nt) + isa(T, Type) ? T[] : [] + catch + [] + end + data, idx = make_idx(init, nt, 0) return (A(data), Axis(idx)) end @@ -325,4 +331,4 @@ julia> sum(prod(ca[k]) for k in valkeys(ca)) k = Val.(keys(idxmap)) return :($k) end -valkeys(ca::ComponentVector) = valkeys(getaxes(ca)[1]) \ No newline at end of file +valkeys(ca::ComponentVector) = valkeys(getaxes(ca)[1]) diff --git a/src/utils.jl b/src/utils.jl index 1c84a256..37dc9336 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -42,3 +42,9 @@ recursive_length(a::AbstractArray{T,N}) where {T<:Number,N} = length(a) recursive_length(a::AbstractArray) = recursive_length.(a) |> sum recursive_length(nt::NamedTuple) = values(nt) .|> recursive_length |> sum recursive_length(::Union{Nothing, Missing}) = 1 + +# Find the highest element type +recursive_type(nt::NamedTuple) = mapreduce(recursive_type, promote_type, nt) +recursive_type(x::Vector{Any}) = mapreduce(recursive_type, promote_type, x) +recursive_type(x::Number) = typeof(x) +recursive_type(::AbstractArray{T,N}) where {T<:Number, N}= T From 6313e5cf89ae45d7174d0dce6b15c8e9b286e05e Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Fri, 29 Jul 2022 18:12:53 -0600 Subject: [PATCH 02/10] primitivetype --- src/componentarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index cb04a446..c1702ab8 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -145,7 +145,7 @@ make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) function make_carray_args(A::Type{<:AbstractArray}, nt) init = try T = recursive_type(nt) - isa(T, Type) ? T[] : [] + isprimitivetype(T) ? T[] : [] catch [] end From 64af25d34106c23d86fe9caa8838a63eb3de8661 Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sun, 31 Jul 2022 14:32:10 -0600 Subject: [PATCH 03/10] some changes --- src/componentarray.jl | 13 ++++++------- src/utils.jl | 10 ++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index c1702ab8..61efef40 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -138,21 +138,20 @@ make_carray_args(::NamedTuple{(), Tuple{}}) = (Any[], FlatAxis()) make_carray_args(::Type{T}, ::NamedTuple{(), Tuple{}}) where {T} = (T[], FlatAxis()) function make_carray_args(nt) data, ax = make_carray_args(Vector, nt) - data = length(data)==1 ? [data[1]] : eltype(data) == Any ? reduce(vcat, data) : data + data = length(data)==1 ? [data[1]] : data return (data, ax) end make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) function make_carray_args(A::Type{<:AbstractArray}, nt) - init = try - T = recursive_type(nt) - isprimitivetype(T) ? T[] : [] - catch - [] - end + T = recursive_eltype(nt) + init = _isprimitivetype(T) ? T[] : [] data, idx = make_idx(init, nt, 0) return (A(data), Axis(idx)) end +_isprimitivetype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isprimitivetype(T) +_isprimitivetype(T) = isprimitivetype(T) + # Builds up data vector and returns appropriate AbstractAxis type for each input type function make_idx(data, nt::NamedTuple, last_val) len = recursive_length(nt) diff --git a/src/utils.jl b/src/utils.jl index 37dc9336..e2de37c9 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -44,7 +44,9 @@ recursive_length(nt::NamedTuple) = values(nt) .|> recursive_length |> sum recursive_length(::Union{Nothing, Missing}) = 1 # Find the highest element type -recursive_type(nt::NamedTuple) = mapreduce(recursive_type, promote_type, nt) -recursive_type(x::Vector{Any}) = mapreduce(recursive_type, promote_type, x) -recursive_type(x::Number) = typeof(x) -recursive_type(::AbstractArray{T,N}) where {T<:Number, N}= T +recursive_eltype(nt::NamedTuple) = mapreduce(recursive_eltype, promote_type, nt) +recursive_eltype(x::Vector) = mapreduce(recursive_eltype, promote_type, x) +recursive_eltype(x::Dict) = mapreduce(recursive_eltype, promote_type, values(x)) +recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N}= T +recursive_eltype(x::Number) = typeof(x) +recursive_eltype(x) = Base.eltypeof(x) From 2f1b6f58fcc4fe82c14a854b665bb4474ef4569e Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sun, 31 Jul 2022 15:44:33 -0600 Subject: [PATCH 04/10] treat dict like nt --- src/componentarray.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index 61efef40..82f655fe 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -60,9 +60,9 @@ end # Entry from NamedTuple, Dict, or kwargs ComponentArray{T}(nt::NamedTuple) where T = ComponentArray(make_carray_args(T, nt)...) ComponentArray{T}(::NamedTuple{(), Tuple{}}) where T = ComponentArray(T[], (FlatAxis(),)) -ComponentArray(nt::NamedTuple) = ComponentArray(make_carray_args(nt)...) +ComponentArray(nt::Union{NamedTuple, AbstractDict}) = ComponentArray(make_carray_args(nt)...) ComponentArray(::NamedTuple{(), Tuple{}}) = ComponentArray(Any[], (FlatAxis(),)) -ComponentArray(d::AbstractDict) = ComponentArray(NamedTuple{Tuple(keys(d))}(values(d))) +#ComponentArray(d::AbstractDict) = ComponentArray(NamedTuple{Tuple(keys(d))}(values(d))) ComponentArray{T}(;kwargs...) where T = ComponentArray{T}((;kwargs...)) ComponentArray(;kwargs...) = ComponentArray((;kwargs...)) @@ -138,7 +138,7 @@ make_carray_args(::NamedTuple{(), Tuple{}}) = (Any[], FlatAxis()) make_carray_args(::Type{T}, ::NamedTuple{(), Tuple{}}) where {T} = (T[], FlatAxis()) function make_carray_args(nt) data, ax = make_carray_args(Vector, nt) - data = length(data)==1 ? [data[1]] : data + data = length(data)==1 ? [data[1]] : map(identity, data) return (data, ax) end make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) @@ -153,7 +153,7 @@ _isprimitivetype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isprimitivety _isprimitivetype(T) = isprimitivetype(T) # Builds up data vector and returns appropriate AbstractAxis type for each input type -function make_idx(data, nt::NamedTuple, last_val) +function make_idx(data, nt::Union{NamedTuple, Dict}, last_val) len = recursive_length(nt) kvs = [] lv = 0 From bbe2bfddc5dcf15f7a90d3f1be11de988bf8600d Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sun, 31 Jul 2022 15:46:14 -0600 Subject: [PATCH 05/10] abstractdict --- src/componentarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index 82f655fe..40163f83 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -153,7 +153,7 @@ _isprimitivetype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isprimitivety _isprimitivetype(T) = isprimitivetype(T) # Builds up data vector and returns appropriate AbstractAxis type for each input type -function make_idx(data, nt::Union{NamedTuple, Dict}, last_val) +function make_idx(data, nt::Union{NamedTuple, AbstractDict}, last_val) len = recursive_length(nt) kvs = [] lv = 0 From edc140b9c954181fd7b10603eeadf302ab628bad Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sun, 31 Jul 2022 15:48:27 -0600 Subject: [PATCH 06/10] delete comment --- src/componentarray.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index 40163f83..58f278aa 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -62,7 +62,6 @@ ComponentArray{T}(nt::NamedTuple) where T = ComponentArray(make_carray_args(T, n ComponentArray{T}(::NamedTuple{(), Tuple{}}) where T = ComponentArray(T[], (FlatAxis(),)) ComponentArray(nt::Union{NamedTuple, AbstractDict}) = ComponentArray(make_carray_args(nt)...) ComponentArray(::NamedTuple{(), Tuple{}}) = ComponentArray(Any[], (FlatAxis(),)) -#ComponentArray(d::AbstractDict) = ComponentArray(NamedTuple{Tuple(keys(d))}(values(d))) ComponentArray{T}(;kwargs...) where T = ComponentArray{T}((;kwargs...)) ComponentArray(;kwargs...) = ComponentArray((;kwargs...)) From 18c36c0683c5fd43afa82d4ffdbb5148f07a52f9 Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sun, 31 Jul 2022 16:33:00 -0600 Subject: [PATCH 07/10] simpler recursive_eltype --- src/utils.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index e2de37c9..7d0d129c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -48,5 +48,4 @@ recursive_eltype(nt::NamedTuple) = mapreduce(recursive_eltype, promote_type, nt) recursive_eltype(x::Vector) = mapreduce(recursive_eltype, promote_type, x) recursive_eltype(x::Dict) = mapreduce(recursive_eltype, promote_type, values(x)) recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N}= T -recursive_eltype(x::Number) = typeof(x) -recursive_eltype(x) = Base.eltypeof(x) +recursive_eltype(x) = typeof(x) From 6bb62654ca7f7e4b5a6454bdcb4ea2c3e5dad3a4 Mon Sep 17 00:00:00 2001 From: Shambles Date: Wed, 3 Aug 2022 14:17:35 -0600 Subject: [PATCH 08/10] Update componentarray.jl --- src/componentarray.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index 58f278aa..32b4d8f3 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -143,13 +143,13 @@ end make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) function make_carray_args(A::Type{<:AbstractArray}, nt) T = recursive_eltype(nt) - init = _isprimitivetype(T) ? T[] : [] + init = _isbitstype(T) ? T[] : [] data, idx = make_idx(init, nt, 0) return (A(data), Axis(idx)) end -_isprimitivetype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isprimitivetype(T) -_isprimitivetype(T) = isprimitivetype(T) +_isbitstype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isbitstype(T) +_isbitstype(T) = isbitstype(T) # Builds up data vector and returns appropriate AbstractAxis type for each input type function make_idx(data, nt::Union{NamedTuple, AbstractDict}, last_val) From 870670115652336c8e7b247035857fe09e24d5f7 Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sat, 6 Aug 2022 10:20:06 -0600 Subject: [PATCH 09/10] empty components --- src/componentarray.jl | 10 ++++++---- src/utils.jl | 9 +++++---- test/runtests.jl | 9 ++++++++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/componentarray.jl b/src/componentarray.jl index 32b4d8f3..453dc7ee 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -143,14 +143,11 @@ end make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) function make_carray_args(A::Type{<:AbstractArray}, nt) T = recursive_eltype(nt) - init = _isbitstype(T) ? T[] : [] + init = isbitstype(T) ? T[] : [] data, idx = make_idx(init, nt, 0) return (A(data), Axis(idx)) end -_isbitstype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isbitstype(T) -_isbitstype(T) = isbitstype(T) - # Builds up data vector and returns appropriate AbstractAxis type for each input type function make_idx(data, nt::Union{NamedTuple, AbstractDict}, last_val) len = recursive_length(nt) @@ -238,6 +235,11 @@ end last_index(x) = last(x) last_index(x::ViewAxis) = last_index(viewindex(x)) last_index(x::AbstractAxis) = last_index(last(indexmap(x))) +function last_index(f::FlatAxis) + nt = indexmap(f) + length(nt) == 0 && return 0 + return last_index(last(nt)) +end # Reduce singleton dimensions remove_nulls() = () diff --git a/src/utils.jl b/src/utils.jl index 7d0d129c..2926ee5e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -42,10 +42,11 @@ recursive_length(a::AbstractArray{T,N}) where {T<:Number,N} = length(a) recursive_length(a::AbstractArray) = recursive_length.(a) |> sum recursive_length(nt::NamedTuple) = values(nt) .|> recursive_length |> sum recursive_length(::Union{Nothing, Missing}) = 1 +recursive_length(nt::NamedTuple{(), Tuple{}}) = 0 # Find the highest element type -recursive_eltype(nt::NamedTuple) = mapreduce(recursive_eltype, promote_type, nt) -recursive_eltype(x::Vector) = mapreduce(recursive_eltype, promote_type, x) -recursive_eltype(x::Dict) = mapreduce(recursive_eltype, promote_type, values(x)) -recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N}= T +recursive_eltype(nt::NamedTuple) = isempty(nt) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, nt) +recursive_eltype(x::Vector{Any}) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, x) +recursive_eltype(x::Dict) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, values(x)) +recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N} = T recursive_eltype(x) = typeof(x) diff --git a/test/runtests.jl b/test/runtests.jl index 740aea6f..0e0c053a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -112,6 +112,13 @@ end # Issue #116 # Part 2: Arrays of arrays @test_throws Exception ComponentVector(a = [[3], [4, 5]], b = 1) + + # empty components + for T in [Int64, Int32, Float64, Float32, ComplexF64, ComplexF32] + @test ComponentArray(a = T[]) == ComponentVector{T}(a = T[]) + @test ComponentArray(a = T[], b = (;)) == ComponentVector{T}(a = T[], b = T[]) + end + @test ComponentArray(NamedTuple()) == ComponentVector{Any}() end @testset "Attributes" begin @@ -612,4 +619,4 @@ end @testset "GPU" begin include("gpu_tests.jl") -end \ No newline at end of file +end From 4ad240861b939321472035c2f009d848e3943152 Mon Sep 17 00:00:00 2001 From: MilkshakeForReal Date: Sat, 6 Aug 2022 11:34:54 -0600 Subject: [PATCH 10/10] more tests --- test/runtests.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 0e0c053a..fea49957 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -116,9 +116,12 @@ end # empty components for T in [Int64, Int32, Float64, Float32, ComplexF64, ComplexF32] @test ComponentArray(a = T[]) == ComponentVector{T}(a = T[]) + @test ComponentArray(a = T[], b = T[]) == ComponentVector{T}(a = T[], b = T[]) @test ComponentArray(a = T[], b = (;)) == ComponentVector{T}(a = T[], b = T[]) + @test ComponentArray(a = Any[one(Int32)], b=T[]) == ComponentVector{T}(a = [one(T)], b = T[]) end @test ComponentArray(NamedTuple()) == ComponentVector{Any}() + @test_broken ComponentArray(a=[]) end @testset "Attributes" begin