# Passing views to function without allocation

**URL:** <https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992>\
**Category:** New to Julia\
**Created:** [December 17, 2020, 4:30pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992 "2020-12-17T16:30:59Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jae-Mo\_Lihm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jae-mo_lihm/32/20145_2.png) [@Jae-Mo\_Lihm](https://discourse.julialang.org/u/Jae-Mo_Lihm)\
**Post date:** [December 17, 2020, 4:30pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/1 "2020-12-17T16:30:59Z")

</div>

I want to perform matrix vector multiplication of size (N^2, M) \* (M), and then reshape the output vector of size (N^2) to a (N, N) matrix.

To do this without allocation, I tried using 1d view of the matrix.  
Directly calling `mul!` with views indeed did not allocate, but when I called `mul!` inside a function, allocation occurs.

Why is this? Is there a way to keep using view inside the function without allocation?

I would also appreciate if there are better ways to achieve my goal of doing matrix vector multiplication and then reshaping the output vector to a matrix.

```julia
N = 50
M = 100
a1 = zeros(N*N)
a2 = zeros(N, N)
b = rand(N*N, M)
c = rand(M)

function test1!(a1, b, c)
    mul!(a1, b, c)
end
function test2!(a2, b, c)
    mul!((@view a2[:]), b, c)
end
@btime mul!($a1, $b, $c)
@btime mul!($(@view a2[:]), $b, $c)
@btime test1!($a1, $b, $c)
@btime test2!($a2, $b, $c)

```

Output:

```julia
53.083 μs (0 allocations: 0 bytes)
53.100 μs (0 allocations: 0 bytes)
53.023 μs (0 allocations: 0 bytes)
53.280 μs (2 allocations: 80 bytes)

```

EDIT: Following suggestions from the replies, I tried `reshape(a2, :)` and `vec(a2)`, but both still allocate.

```julia
function test3!(a2, b, c)
    mul!(reshape(a2, :), b, c)
end
function test4!(a2, b, c)
    mul!(vec(a2), b, c)
end
@btime mul!(reshape($a2, :), $b, $c)
@btime mul!($vec(a2), $b, $c)
@btime test3!($a2, $b, $c)
@btime test4!($a2, $b, $c)

```

Output:

```julia
53.223 μs (2 allocations: 80 bytes)
53.178 μs (2 allocations: 80 bytes)
53.303 μs (2 allocations: 80 bytes)
53.144 μs (2 allocations: 80 bytes)

```

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [December 17, 2020, 4:37pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/2 "2020-12-17T16:37:42Z")

</div>

This isn’t an answer to your question, but could you use `reshape` on `a2` instead of a `@view`?

---

<div class="post-metadata">

**Author:** ![Jae-Mo\_Lihm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jae-mo_lihm/32/20145_2.png) [@Jae-Mo\_Lihm](https://discourse.julialang.org/u/Jae-Mo_Lihm)\
**Post date:** [December 17, 2020, 4:41pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/3 "2020-12-17T16:41:40Z")

</div>

Do you mean the following?

```julia
function test3!(a2, b, c)
    mul!(reshape(a2, :), b, c)
end
@btime mul!(reshape($a2, :), $b, $c)
@btime test3!($a2, $b, $c)

```

Both work, but still allocate.

```julia
53.223 μs (2 allocations: 80 bytes)
53.178 μs (2 allocations: 80 bytes)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 17, 2020, 4:53pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/4 "2020-12-17T16:53:12Z")

</div>

What happens if you use `vec` instead of `view` or `reshape`?

---

<div class="post-metadata">

**Author:** ![Jae-Mo\_Lihm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jae-mo_lihm/32/20145_2.png) [@Jae-Mo\_Lihm](https://discourse.julialang.org/u/Jae-Mo_Lihm)\
**Post date:** [December 17, 2020, 4:57pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/5 "2020-12-17T16:57:24Z")

</div>

It still allocates.

```julia
function test4!(a2, b, c)
    mul!(vec(a2), b, c)
end
@btime mul!($vec(a2), $b, $c)
@btime test4!($a2, $b, $c)

```

```julia
53.303 μs (2 allocations: 80 bytes)
53.144 μs (2 allocations: 80 bytes)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 17, 2020, 5:03pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/6 "2020-12-17T17:03:01Z")

</div>

Yeah, I guess you have to pay for the construction of the `view` wrapper in this case.

The reason you don’t get allocations here

> [@Jae-Mo\_Lihm](#):
>
> `@btime mul!($(@view a2[:]), $b, $c)`

is that you create the view _first_, before splicing it into the benchmark expression.

Try

```julia
@btime mul!(@view ($a2)[:], $b, $c)

```

instead. This is a fairer comparison.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 17, 2020, 5:08pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/7 "2020-12-17T17:08:18Z")

</div>

This isn’t right either. Here you are interpolating in the function `vec`, and not interpolating the `a2` variable at all.

> [@Jae-Mo\_Lihm](#):
>
> `@btime mul!($vec(a2), $b, $c)`

It should be

```julia
@btime mul!(vec($a2), $b, $c)

```

---

<div class="post-metadata">

**Author:** ![Jae-Mo\_Lihm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jae-mo_lihm/32/20145_2.png) [@Jae-Mo\_Lihm](https://discourse.julialang.org/u/Jae-Mo_Lihm)\
**Post date:** [December 17, 2020, 5:13pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/8 "2020-12-17T17:13:12Z")

</div>

I see. Thanks.  
Both `@btime mul!(view($a2, :), $b, $c)` and `@btime mul!(vec($a2), $b, $c)` allocates `53.279 μs (2 allocations: 80 bytes)`.

So, `vec`, `view`, and `reshape` all allocates some memory.

Then, my question is: Is there any way to pass 1d view of a matrix (or something similar) to `mul!` without allocating any memory?  
(Maybe I am so used to Fortran…)

Is [https://github.com/JuliaArrays/UnsafeArrays.jl](https://github.com/JuliaArrays/UnsafeArrays.jl) relevant to this use case?  
I was reluctant to use it because it says UnsafeArrays.jl would be unnecessary after v1.5, which is what I am using (v1.5.3).

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 17, 2020, 5:21pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/9 "2020-12-17T17:21:42Z")

</div>

I’m afraid I cannot answer that. It’s not clear to me exactly when allocations will be elided or not. Is this a significant issue? Does it impact performance?

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [December 17, 2020, 7:09pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/10 "2020-12-17T19:09:08Z")

</div>

May be `UnsafeArrays` is still an option? This is in Julia 1.5.0.

```julia
using UnsafeArrays
N = 50;
M = 100;
a1 = zeros(N*N);
a2 = zeros(N, N);
b = rand(N*N, M);
c = rand(M);

function test2!(a2, b, c)
    mul!(uview(a2,:), b, c)
end

@btime test2!($a2, $b, $c);
  46.500 μs (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![Jae-Mo\_Lihm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jae-mo_lihm/32/20145_2.png) [@Jae-Mo\_Lihm](https://discourse.julialang.org/u/Jae-Mo_Lihm)\
**Post date:** [December 18, 2020, 3:12am UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/11 "2020-12-18T03:12:35Z")

</div>

Thank you all for the answers!

The allocation does not change the performance significantly, I just asked out of curiosity.

It seems `uview` of `UnsafeArrays` is the answer to my question. Thanks!

---

<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:** [December 18, 2020, 4:34am UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/12 "2020-12-18T04:34:17Z")

</div>

This really isn’t views; it’s the reshape (which implicitly happens when `view`’ing with linear indexing). This is because reshapes of `Array` are handled in C. Use a Julia-native reshape and it gives you what you want:

```julia
julia> @btime mul!(reshape(view($a2, :, :), :), $b, $c); # reshape of a view
  11.295 μs (0 allocations: 0 bytes)

julia> @btime mul!(Base.ReshapedArray($a2, (length($a2),), ()), $b, $c);
  11.114 μs (0 allocations: 0 bytes)

```

We should make the `ReshapedArray` constructor easier to use (and export it).

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [December 18, 2020, 2:07pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/13 "2020-12-18T14:07:41Z")

</div>

Rather than yet another way to make this reshape, any reason we can’t make `vec(a2)`, `view(a2, :)` and `reshape(a2, :)` behave like this?

---

<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:** [December 18, 2020, 2:27pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/14 "2020-12-18T14:27:42Z")

</div>

It’s unfortunately breaking.

[https://github.com/JuliaLang/julia/issues/24237](https://github.com/JuliaLang/julia/issues/24237)

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [December 18, 2020, 7:12pm UTC](https://discourse.julialang.org/t/passing-views-to-function-without-allocation/51992/15 "2020-12-18T19:12:35Z")

</div>

I see… There’s no reason however why `vec(a2)` , `view(a2, :)` and `reshape(a2, :)` _have to_ allocate, right? A future `Array` type implemented in Julia could avoid the allocation while staying backward compatible (or am I missing something?).
