# Resize! and multidimensional arrays

**URL:** <https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 6, 2020, 7:38am UTC](https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842 "2020-10-06T07:38:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [October 6, 2020, 7:38am UTC](https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842/1 "2020-10-06T07:38:19Z")

</div>

### Background

We want to make use of adaptive mesh refinement (AMR) for our hyperbolic PDE solver package [Trixi.jl](https://github.com/trixi-framework/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](https://github.com/JuliaLang/julia/issues/37900).

### Alternatives

One option might be to use [ElasticArrays.jl](https://github.com/JuliaArrays/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](https://github.com/chriselrod/PaddedMatrices.jl), see [multiply\_dimensionwise: mortars etc. · Issue #166 · trixi-framework/Trixi.jl · GitHub](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
  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
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](https://github.com/mateuszbaran/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?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [October 6, 2020, 8:39am UTC](https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842/2 "2020-10-06T08:39:24Z")

</div>

Dumb question: why does your algorithm have to be in-place?

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [October 6, 2020, 8:49am UTC](https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842/3 "2020-10-06T08:49:04Z")

</div>

That’s not a dump question at all. In the past, we’ve just created new `Array`s when doing AMR and that was totally okay for us. However, we want to make use of [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) etc. in the future. There, it’s only possible to `resize!` intermediate caches used for the time integration but not to set them to something completely new.

Of course, one could also argue that this is a restriction of OrdinaryDiffEq.jl and should be fixed there. On the other hand, we can reduce allocations and save runtime if we are able to re-use already allocated memory. For example, standard `Vector`s won’t allocate on every call to `resize!`, which makes this approach very efficient for us.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 6, 2020, 9:26am UTC](https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842/4 "2020-10-06T09:26:04Z")

</div>

> [@ranocha](#):
>
> needing to use `ElasticArray` doesn’t feel completely good to me

I still do not understand why. But in any case,

1. If you need to resize a lot, just allocate a “large enough” array and keep track of the dimensions you use at the momene. You can wrap this in a `struct` and implement [the `AbstractArray` interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array) very simply.

2. If you need to resize very infrequently, just copying over the data to a freshly allocated container should be reasonably cheap.

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [October 7, 2020, 9:37am UTC](https://discourse.julialang.org/t/resize-and-multidimensional-arrays/47842/5 "2020-10-07T09:37:44Z")

</div>

Thanks for investing your time to answer my questions. We will continue to discuss options internally and use some kind of wrappers of `Vector`s (as also done by ElasticArrays.jl).
