# LinearAlgebra.gemv! vs BLAS.gemv!

**URL:** <https://discourse.julialang.org/t/linearalgebra-gemv-vs-blas-gemv/107017>\
**Category:** General Usage\
**Tags:** linearalgebra\
**Created:** [December 1, 2023, 8:36pm UTC](https://discourse.julialang.org/t/linearalgebra-gemv-vs-blas-gemv/107017 "2023-12-01T20:36:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacob-roth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacob-roth/32/1862_2.png) [@jacob-roth](https://discourse.julialang.org/u/jacob-roth)\
**Post date:** [December 1, 2023, 8:36pm UTC](https://discourse.julialang.org/t/linearalgebra-gemv-vs-blas-gemv/107017/1 "2023-12-01T20:36:43Z")

</div>

I am trying to understand what julia uses in a call to `mul!` in the following example:

```julia
using LinearAlgebra
m,n = 10,5;
A = randn(m,n);
x = randn(n);
Ax = zeros(m);
@code_lowered mul!(Ax, A, x, true, false)
@code_lowered LinearAlgebra.gemv!('N', true, A, x, false, Ax)
@code_lowered BLAS.gemv!('N', true, A, x, false, Ax)
@code_llvm mul!(Ax, A, x, true, false)
@code_llvm LinearAlgebra.gemv!('N', true, A, x, false, Ax)
@code_llvm BLAS.gemv!('N', true, A, x, false, Ax)

```

```julia
julia> @code_lowered mul!(Ax, A, x, true, false)
CodeInfo(
1 ─ nothing
│ %2 = LinearAlgebra.gemv!(y, 'N', A, x, alpha, beta)
└── return %2
)
julia> @code_lowered @views LinearAlgebra.gemv!('N', true, A, x, false, Ax)
CodeInfo(
1 ─ nothing
│ %2 = Base.replace_ref_begin_end!(x)
│ %3 = Base._views(%2)
│ %4 = Base.esc(%3)
└── return %4
)
julia> @code_lowered @views BLAS.gemv!('N', true, A, x, false, Ax)
CodeInfo(
1 ─ nothing
│ %2 = Base.replace_ref_begin_end!(x)
│ %3 = Base._views(%2)
│ %4 = Base.esc(%3)
└── return %4
)
julia> LinearAlgebra.gemv! == LinearAlgebra.BLAS.gemv!
false

```

Repeating the above with `@code_llvm` instead of `@code_lowered` makes it seem that `mul!` calls `LinearAlgebra.gemv!` which is the same as `BLAS.gemv!` and `LinearAlgebra.BLAS.gemv!`. Is there a difference between `LinearAlgebra.gemv!` and `LinearAlgebra.BLAS.gemv!`? Guessing I have a simple misunderstanding for why `LinearAlgebra.gemv! == LinearAlgebra.BLAS.gemv!` is `false`.

---

<div class="post-metadata">

**Author:** ![palday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palday/32/12640_2.png) [@palday](https://discourse.julialang.org/u/palday)\
**Post date:** [December 1, 2023, 9:38pm UTC](https://discourse.julialang.org/t/linearalgebra-gemv-vs-blas-gemv/107017/2 "2023-12-01T21:38:58Z")

</div>

Your use of `@views` is messing up things a bit in your examination.

A simpler way to see that they’re not the same is:

```julia
julia> length(methods(BLAS.gemv!))
4

julia> length(methods(LinearAlgebra.gemv!))
9

```

---

<div class="post-metadata">

**Author:** ![jacob-roth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacob-roth/32/1862_2.png) [@jacob-roth](https://discourse.julialang.org/u/jacob-roth)\
**Post date:** [December 1, 2023, 9:53pm UTC](https://discourse.julialang.org/t/linearalgebra-gemv-vs-blas-gemv/107017/3 "2023-12-01T21:53:14Z")

</div>

Ah thanks, I messed up including `@views` in there. So now it is clear that `mul!` calls `LinearAlgebra.gemv!`. However, what is the difference between `BLAS.gemv!` and `LinearAlgebra.gemv!`? I see that `LinearAlgebra.BLAS.gemv! == BLAS.gemv!`.

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [December 1, 2023, 10:11pm UTC](https://discourse.julialang.org/t/linearalgebra-gemv-vs-blas-gemv/107017/4 "2023-12-01T22:11:50Z")

</div>

`LinearAlgebra.gemv!` is defined here: [https://github.com/JuliaLang/julia/blob/aef528d32a6291ce82452c3a1ff1fa56ccf17641/stdlib/LinearAlgebra/src/matmul.jl#L401-L478](https://github.com/JuliaLang/julia/blob/aef528d32a6291ce82452c3a1ff1fa56ccf17641/stdlib/LinearAlgebra/src/matmul.jl#L401-L478)

As you can see, it’s a wrapper that does some argument checks et cetera before calling `BLAS.gemv!`, or in some cases another BLAS function or generic matmul implementation. LinearAlgebra has a lot of somewhat interrelated delegation mechanisms to make everything work smoothly, but if your arrays are BLAS compatible you will eventually end up in a BLAS function.
