# Using \`view\` in 0.6 on a ragged array

**URL:** <https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982>\
**Category:** General Usage\
**Tags:** question\
**Created:** [July 20, 2017, 6:47pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982 "2017-07-20T18:47:13Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 20, 2017, 6:47pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/1 "2017-07-20T18:47:13Z")

</div>

I have noticed that a particular calculation in the [`MixedModels`](https://github.com/dmbates/MixedModels.jl) package unexpectedly allocates a lot of storage. The method in question is around lines 340 to 350 of `modelterms.jl`. The calculation involves the columns of a `k` by `n` matrix where `k << n` and a `PooledDataArray` which indicates which group the column is part of. There are `g` groups. In the code, the `n`-vector `A.f.refs` will contain the integers `1:g` where `g < n`.

The output value is a `g`-vector of `k` by `k` matrices called `d` in the code. These are zeroed out then each column is used in a rank-1 update of the corresponding element of `d`. Right now the loop is written

```julia
    for i in eachindex(refs)
        ## FIXME: A lot of allocation going on here
        BLAS.syr!('L', one(T), view(Az, :, i), d[refs[i]])
    end

```

Checking with --track-allocation shows considerable allocation in this loop (which is called many times on a large problem).

```julia
        0 for i in eachindex(refs)
        - ## FIXME: A lot of allocation going on here
1690606080 BLAS.syr!('L', one(T), view(Az, :, i), d[refs[i]])
        - end

```

I don’t understand where the allocation is coming from. I had thought that a view would be lightweight, especially a view of a column in a matrix.

Is there a better way of writing this so as to avoid all the allocation?

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 20, 2017, 7:15pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/2 "2017-07-20T19:15:22Z")

</div>

I thought I might be able to avoid the allocation problem by using an `unsafe_wrap` of an array even though it is, well, unsafe. But it actually made the problem worse

```julia
        0 refs = A.f.refs
        0 Apt = pointer(Az)
        0 @inbounds for i in eachindex(refs)
        - ## FIXME: A lot of allocation going on here
2817676800 BLAS.syr!('L', one(T), unsafe_wrap(Array, Apt, l), d[refs[i]])
        0 Apt += l * sizeof(T)
        - end

```

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 20, 2017, 7:42pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/3 "2017-07-20T19:42:39Z")

</div>

Actually, I think the “twice as bad” may be because I ran the fit twice and forgot to `Profile.clear_malloc_data()` after the first fit.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [July 20, 2017, 8:00pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/4 "2017-07-20T20:00:07Z")

</div>

Ideally `view` will be allocation-free some day, but for now the wrapper gets allocated in many cases ([https://github.com/JuliaLang/julia/issues/10899](https://github.com/JuliaLang/julia/issues/10899)). You can try the old ArrayViews package, where the unsafe contiguous view should manage to get optimized away… but it’s not gotten much love lately.

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 20, 2017, 8:05pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/5 "2017-07-20T20:05:20Z")

</div>

I think the problem was the calls to BLAS.syr! although I am not sure exactly why that would allocate. In any case, the calculation is so simple that I just replaced the high-level calls with explicit loops and that doesn’t allocate.

The reason that I don’t think it was the `view` call that was a problem is because I still had the problem with allocation after switching to `unsafe_wrap(Array, ...)`

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 20, 2017, 8:08pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/6 "2017-07-20T20:08:07Z")

</div>

Now it looks like

```julia
    refs = A.f.refs
    @inbounds for i in eachindex(refs)
        dri = d[refs[i]]
        for j in 1:l
            Aji = Az[j, i]
            for k in 1:l
                dri[k, j] += Aji * Az[k, i]
            end
        end
    end

```

---

<div class="post-metadata">

**Author:** ![Nitin\_Arora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nitin_arora/32/1174_2.png) [@Nitin\_Arora](https://discourse.julialang.org/u/Nitin_Arora)\
**Post date:** [July 21, 2017, 6:27am UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/7 "2017-07-21T06:27:58Z")

</div>

Instead of `view` , try using `unsafe_aview` from the `ArrayViews` package. As long as your code works with Abstract Arrays, this should be non allocating. I am using this until we get non allocating views in the base.

---

<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:** [July 21, 2017, 12:45pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/8 "2017-07-21T12:45:20Z")

</div>

I’ve noticed that the new inliner in Julia 0.7 seems more likely optimize out the construction of the SubArray, you could give that a try.

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 21, 2017, 2:53pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/9 "2017-07-21T14:53:34Z")

</div>

My current opinion is that it is not the call to `view` that is causing the allocations but rather `syr!`. Because of the Fortran calling sequence used by the BLAS, I think that all the integers passed to the BLAS subroutine need to be allocated. The ccall is

```julia
 ccall((@blasfunc($fname), $lib), Void,
     (Ptr{UInt8}, Ptr{BlasInt}, Ptr{$elty}, Ptr{$elty},
      Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}),
      &uplo, &n, &α, x,
      &stride(x, 1), A, &max(1,stride(A, 2)))

```

The point is that this is called many, many times with `n = 2`. Even trivial amounts of allocation within the call will add up.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [July 21, 2017, 3:41pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/10 "2017-07-21T15:41:11Z")

</div>

Pretty sure that passing integers to Fortran with `&` will not allocate.

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [July 21, 2017, 4:06pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/11 "2017-07-21T16:06:29Z")

</div>

I haven’t been able to find another explanation as the allocations persist even when replacing `view(...` by `unsafe_wrap(Array, ...`

As it is, this problem motivated me to rewrite the code to avoid the calls to `view` and `syr!` so I guess all is good in the end. The tools to check allocations and to profile execution have proven their worth again.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 21, 2017, 4:35pm UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/12 "2017-07-21T16:35:31Z")

</div>

`unsafe_wrap` allocate the array.

---

<div class="post-metadata">

**Author:** ![Nitin\_Arora](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nitin_arora/32/1174_2.png) [@Nitin\_Arora](https://discourse.julialang.org/u/Nitin_Arora)\
**Post date:** [July 22, 2017, 7:00am UTC](https://discourse.julialang.org/t/using-view-in-0-6-on-a-ragged-array/4982/13 "2017-07-22T07:00:40Z")

</div>

@dmbates did you try `unsafe_aview` ?
