# Odd behavior with mul!() and @view

**URL:** <https://discourse.julialang.org/t/odd-behavior-with-mul-and-view/108606>\
**Category:** General Usage\
**Created:** [January 10, 2024, 4:55am UTC](https://discourse.julialang.org/t/odd-behavior-with-mul-and-view/108606 "2024-01-10T04:55:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnb/32/44115_2.png) [@johnb](https://discourse.julialang.org/u/johnb)\
**Post date:** [January 10, 2024, 4:55am UTC](https://discourse.julialang.org/t/odd-behavior-with-mul-and-view/108606/1 "2024-01-10T04:55:50Z")

</div>

I’m trying to use mul!() to perform low-memory multiplications on subsets of larger matrices using code. My actual code loops through many slices of smaller views of a large matrix (large set of ODEs chunked for easier understanding), but I’ve reduced the problem to the MWE below.

Is there a way to obtain the same results between the two methods? For reference, I’m using Julia 1.10.

```julia
n = 10
m = 8
out = zeros(n, m)
A = ones(n,n)
b = ones(n)
out2 = @view out[:,3:4]
#Method 1 (returns incorrect zero vector)
mul!(out2[:,1], A, b)
#returns out2[:, 1] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

#Method 2 (returns correct nonzero vector)
out2[:,1] = A*b
@show out2[:,1]
#returns out2[:, 1] = [10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0]

```

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [January 10, 2024, 5:02am UTC](https://discourse.julialang.org/t/odd-behavior-with-mul-and-view/108606/2 "2024-01-10T05:02:53Z")

</div>

Method 1 lowers to `getindex` i.e. makes another slice. Method 2 lowers to `setindex!`

```julia
julia> Meta.@lower mul!(out2[:,1], A, b)
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope`
1 ─ %1 = Base.getindex(out2, :, 1)
│ %2 = A
│ %3 = mul!(%1, %2, b)
└── return %3
))))

julia> Meta.@lower out2[:,1] = A*b
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope`
1 ─ %1 = A * b
│ Base.setindex!(out2, %1, :, 1)
└── return %1
))))

```

what is the motivation for using `mul!` specifically rather than `*` ? also I think if you use another `view` this will work as intended

```julia
# equivalently, mul!(view(out2, :, 1), A, b)
julia> @views mul!(out2[:,1], A, b)
10-element view(::Matrix{Float64}, :, 3) with eltype Float64:
 10.0
 10.0
 10.0
 10.0
 10.0
 10.0
 10.0
 10.0
 10.0
 10.0

```

---

<div class="post-metadata">

**Author:** ![johnb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnb/32/44115_2.png) [@johnb](https://discourse.julialang.org/u/johnb)\
**Post date:** [January 10, 2024, 5:23am UTC](https://discourse.julialang.org/t/odd-behavior-with-mul-and-view/108606/3 "2024-01-10T05:23:54Z")

</div>

Your @views method 3 does work!

My motivation was to reduce memory usage since for this toy example, `mul!()` uses 112 bytes and `A*b` uses 160 bytes. As the matrices scale, and since this step is repeated many times my code runs, I thought it would be a more efficient way to do things. At m=n=10000, `mul!()` still only uses 112 bytes, but `A*b` uses 78.19KiB. However, they do seem to take about the same amount of time, and it’s not that much memory, so I’m not sure if I’m being silly. In any case, your solution works, and I’ll look more into the difference between setindex!() and getindex() so I understand them better.

Thanks!

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [January 10, 2024, 5:44am UTC](https://discourse.julialang.org/t/odd-behavior-with-mul-and-view/108606/4 "2024-01-10T05:44:21Z")

</div>

Just remember that slicing always makes a copy. That’s why

```julia
mul!(out2[:,1], A, b)

```

doesn’t work. You first create a copy of a part of `out2` and then pass that to `mul!` which happily overwrites it, but of course that does not change `out2`.

Note that on the left side of an assignment like in your version 2

```julia
out2[:,1] = A*b

```

we don’t create a copy to write to but write into `out2`. The left hand-side of an assignment is the only place where slicing does not create a copy.
