Background
We want to make use of adaptive mesh refinement (AMR) for our hyperbolic PDE solver package Trixi.jl. For us, the most natural data layout is given by multidimensional arrays. To use AMR, we need to resize!
the last dimension of these arrays. Currently, multidimensional Array
s can not be resize!
ed and such a feature will not be implemented in the foreseeable future because of performance considerations.
Alternatives
One option might be to use ElasticArrays.jl. However, needing to use ElasticArray
doesn’t feel completely good to me, since we also want to experiment with other array types such as PaddedMatrices.jl, see https://github.com/trixi-framework/Trixi.jl/issues/166. Then, we would need to wrap an Array
inside something from PaddedMatrices.jl inside something from ElasticArrays.jl - or the other way round? Is that possible at all? If we go further, I fear this looks like it could easily explode.
We could try to use resize!
able Vector
s which we somehow wrap inside Trixi.jl as our multidimensional Array
s. The most straightforward approach I can think of fails:
julia> v = ones(6)
6-element Array{Float64,1}:
1.0
1.0
1.0
1.0
1.0
1.0
julia> function foo(v)
vm = reshape(v, (2, length(v)Ă·2))
vm[1, 2]
end
foo (generic function with 1 method)
julia> foo(v)
1.0
julia> v[3] = 5
5
julia> foo(v)
5.0
julia> resize!(v, 8)
ERROR: cannot resize array with shared data
Stacktrace:
[1] _growend! at ./array.jl:892 [inlined]
[2] resize!(::Array{Float64,1}, ::Int64) at ./array.jl:1085
[3] top-level scope at REPL[6]:1
It’s okay that resize!
doesn’t work when the data is shared.
Question 1: Is there a way to be able to use resize!
on a Vector
when the shared data went out of scope?
Instead, it looks like we need to use something like
julia> function foo(v)
vm = unsafe_wrap(Array{eltype(v), 2}, pointer(v), (2, length(v)Ă·2))
vm[1, 2]
end
That’s okay and works for us in the current approach. It will also allow us to wrap the Vector
with more type information on the sizes, e.g. using HybridArrays.jl. However, we need to take care, e.g. if we need to copy a given Vector
locally, wrap it as a multidimensional Array
- we must use GC.@preserve
.
Question 2: Is there a possibility to use something like that without having to GC.@preserve
copies of Vector
s which are only used indirectly via multidimensional wrapped versions afterwards?
Question 3: Is there a better alternative?