Skip to content
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

Specialize Base.similar for VectorOfArray with multidimensional parent #359

Merged
merged 10 commits into from
Feb 22, 2024
17 changes: 16 additions & 1 deletion src/vector_of_array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,16 @@
VectorOfArray{T, N + 1, typeof(vec)}(vec)
end

# allow multi-dimensional arrays as long as they're linearly indexed
# allow multi-dimensional arrays as long as they're linearly indexed.
# currently restricted to arrays whose elements are all the same type
function VectorOfArray(array::AbstractArray{AT}) where {T, N, AT <: AbstractArray{T, N}}
@assert IndexStyle(typeof(array)) isa IndexLinear

return VectorOfArray{T, N + 1, typeof(array)}(array)
end

Base.parent(vec::VectorOfArray) = vec.u

Check warning on line 167 in src/vector_of_array.jl

View check run for this annotation

Codecov / codecov/patch

src/vector_of_array.jl#L167

Added line #L167 was not covered by tests

function DiffEqArray(vec::AbstractVector{T},
ts::AbstractVector,
::NTuple{N, Int},
Expand Down Expand Up @@ -721,6 +724,18 @@
VectorOfArray([similar(VA[:, i], T) for i in eachindex(VA.u)])
end

# for VectorOfArray with multi-dimensional parent arrays of arrays where all elements are the same type
@inline function Base.similar(vec::VectorOfArray{

Check warning on line 728 in src/vector_of_array.jl

View check run for this annotation

Codecov / codecov/patch

src/vector_of_array.jl#L728

Added line #L728 was not covered by tests
jlchan marked this conversation as resolved.
Show resolved Hide resolved
T, N, AT}) where {T, N, AT <: AbstractArray{<:AbstractArray{T}}}
return VectorOfArray(similar(Base.parent(vec)))

Check warning on line 730 in src/vector_of_array.jl

View check run for this annotation

Codecov / codecov/patch

src/vector_of_array.jl#L730

Added line #L730 was not covered by tests
end

# special-case when the multi-dimensional parent array is just an AbstractVector (call the old method)
@inline function Base.similar(vec::VectorOfArray{

Check warning on line 734 in src/vector_of_array.jl

View check run for this annotation

Codecov / codecov/patch

src/vector_of_array.jl#L734

Added line #L734 was not covered by tests
ChrisRackauckas marked this conversation as resolved.
Show resolved Hide resolved
T, N, AT}) where {T, N, AT <: AbstractVector{<:AbstractArray{T}}}
return Base.similar(vec, eltype(vec))

Check warning on line 736 in src/vector_of_array.jl

View check run for this annotation

Codecov / codecov/patch

src/vector_of_array.jl#L736

Added line #L736 was not covered by tests
end

# fill!
# For DiffEqArray it ignores ts and fills only u
function Base.fill!(VA::AbstractVectorOfArray, x)
Expand Down
4 changes: 4 additions & 0 deletions test/basic_indexing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ foo!(u_matrix)
foo!(u_vector)
@test u_matrix ≈ u_vector

# test that, for VectorOfArray with multi-dimensional parent arrays,
# `similar` preserves the structure of the parent array
@test typeof(parent(similar(u_matrix))) == typeof(parent(u_matrix))

# test efficiency
num_allocs = @allocations foo!(u_matrix)
@test num_allocs == 0
Loading