# Why is LoopVectorization deprecated?

**URL:** <https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547>\
**Category:** Performance\
**Tags:** loopvectorization\
**Created:** [February 1, 2024, 2:13am UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547 "2024-02-01T02:13:46Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 15, 2024, 4:11pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/82 "2024-03-15T16:11:41Z")

</div>

The tests have been failing for a while. This, however, seems to be a regression:

> <https://github.com/JuliaSIMD/VectorizationBase.jl/issues/106>
>
> PkgEval report https://s3.amazonaws.com/julialang-reports/nanosoldier/pkgeval/by…\_hash/0520b80\_vs\_bd47eca/NaNStatistics.primary.log.
> 
> Happens in:
> 
> https://github.com/JuliaSIMD/VectorizationBase.jl/blob/cbf6789a17f3bd26bc555fc03423b877e740dee7/src/llvm\_intrin/memory\_addr.jl#L987-L995
> 
> This comes from LV.jl which is deprecated but it ends up here so not sure if it is relevant. Example stacktrace
> 
> \`\`\`
> \[83\] signal 11 (128): Segmentation fault
> in expression starting at /home/pkgeval/.julia/packages/PlmDCA/V28iv/test/testdca.jl:105
> macro expansion at /home/pkgeval/.julia/packages/VectorizationBase/xE5Tx/src/llvm\_intrin/memory\_addr.jl:997 \[inlined\]
> \_\_vload at /home/pkgeval/.julia/packages/VectorizationBase/xE5Tx/src/llvm\_intrin/memory\_addr.jl:997 \[inlined\]
> \_vload at /home/pkgeval/.julia/packages/VectorizationBase/xE5Tx/src/strided\_pointers/stridedpointers.jl:105 \[inlined\]
> macro expansion at /home/pkgeval/.julia/packages/LoopVectorization/7gWfp/src/reconstruct\_loopset.jl:1107 \[inlined\]
> \_turbo\_! at /home/pkgeval/.julia/packages/LoopVectorization/7gWfp/src/reconstruct\_loopset.jl:1107
> \`\`\`

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [March 31, 2024, 6:25pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/83 "2024-03-31T18:25:37Z")

</div>

Since I don’t see much movement on this, does anyone know if there are alternatives to LoopVectorization for the upcoming deprecation? I am really not looking forward to the upcoming performance drop on Julia 1.11 in some of my packages ☹

 ![Screenshot 2024-03-31 at 19.18.00](https://global.discourse-cdn.com/julialang/original/3X/2/8/28f591e3c076ac3d8facd6ee6c984432edcd002a.png)

(`@inbounds @simd` vs `@turbo` in one of my benchmarks)

Presumably there is some sort of future-proof alternative out there, with worse speeds than LV but still better than `@inbounds @simd`?

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [March 31, 2024, 7:46pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/84 "2024-03-31T19:46:18Z")

</div>

I was in a similar boat, but managed to circumvent the use of `turbo` by a full rewrite of my code (in such a way that threading loops through LoopVectorization was not possible anymore). I don’t think it is reasonable to expect this to be done by everyone who highly depends on it (like I did), so I imagine as the clock ticks closer and Julia v. 1.11 is released one of the following happens:

- People realize that `LoopVectorization.jl` is too big to fail, and it gets updated for 1.11
- Some parts of the eco-system version lock them to 1.10, going against Julia “philosophy” of always being quite easily upgradeable and gaining the new futures quickly (perhaps my personal understanding)
- `LoopVectorization.jl` is not updated, allowed to deprecate. This will leave people always wondering \* what if I had used @turbo? \* Until something new and improved comes out.

Personally I think this is quite an interesting dilemma for Julia as a community, since it has always been proposed as a language to write the fastest numerical codes etc. and suddenly one huge back-bone of achieving this is ripped out rather abruptly.

Sorry for not being able to provide any reasonable solution, but I hope it helps to know that a lot of us are in / have been in your position and I was worried as well when my code still heavily dependended on it.

Kind regards

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [March 31, 2024, 7:53pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/85 "2024-03-31T19:53:57Z")

</div>

Why are we focusing so much on Julia 1.11 for package development at the moment? Julia 1.11 is the beginning of a new development cycle for Julia with many large changes internally. We just had a feature freeze and most of my attention there is working on internals or making former internals work better. I expect to see performance regressions there in the near term across the board as we learn to adapt and optimize for the new architecture. It seems to be too early to be optimizing for Julia 1.11 when the dust has barely settled there. I’m waiting for a beta before I start thinking about package performance on 1.11+.

Julia 1.10 is a likely candidate for a LTS release for many reasons. From a pure performance perspective in the near term, I would be thinking about how to make packages work as well as possible on Julia 1.10.x until post-1.10 Julia is clearly superior for performance.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [April 1, 2024, 8:40am UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/86 "2024-04-01T08:40:47Z")

</div>

It also looks like LoopModels isn’t really active: [Branches · LoopModels/LoopModels · GitHub](https://github.com/LoopModels/LoopModels/branches) which is a bummer.

So, what other options are there for getting decent vectorization in Julia post-1.10? Maybe one option is to use SIMD.jl and vectorize things by hand?

I guess another is to even use JAX via PythonCall? Or even OpenXLA? I suppose you wouldn’t be able to write pure Julia code, but for the most expensive kernels perhaps it’s something to consider.

> [@mkitti](#):
>
> Why are we focusing so much on Julia 1.11 for package development at the moment? Julia 1.11 is the beginning of a new development cycle for Julia with many large changes internally.

I don’t know about others but this is the first Julia alpha since I’ve joined the community where I’m seeing 50%-80% drops in performance… (due to the LV deprecation) At worst it’s been like 5% in the past. The `@turbo`-ified loops are the bottleneck of my code.

So I’m trying to fix this early (seems like it will take more time than usual) before it slows down downstream applications of all my users on the latest Julia.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 1, 2024, 11:25am UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/87 "2024-04-01T11:25:54Z")

</div>

> [@MilesCranmer](#):
>
> `@inbounds @simd`

probably dummy suggestion: have you added `@fastmath` to the loop? LV, if I’m not mistaken, assumes it. (ps: can you share the code of the loop in question? It might be of interest of other people trying to solve similar regressions)

---

<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:** [April 1, 2024, 12:30pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/88 "2024-04-01T12:30:34Z")

</div>

I’m developing a library where the core is a simple loop that does a bunch of `sincos` calls. This is the main bottleneck, and without Loopvectorization.jl there’s going to be a 3-5x performance loss overall (guesstimate as of now). It’s pretty bad. There are some other, less important, places in the code where missing LV will bite, too.

This will be a long-term project, so looking ahead to 1.11 and beyond is reasonable, not sure I understand the argument of @mkitti that only 1.10 is relevant.

I hope it will be possible for me to get the speedup by hand, using SIMD.jl, so far `sin/cos` calls on vectors are disappointingly slow, though. The way forward is probably learning how LV does its magic. My case is pretty straightforward, so I’m relatively optimistic after all.

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [April 1, 2024, 1:01pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/89 "2024-04-01T13:01:36Z")

</div>

Please teach me how to do the magic after you learn the way 😀

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [April 1, 2024, 1:28pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/90 "2024-04-01T13:28:55Z")

</div>

Years ago I also tried to make my packages fast for CPU.

But these days I focus on GPU performance only.  
Many people in the scientific community have problems where GPUs speed things massively up (\>10x).  
So they use GPUs either remotely (e.g. Google Colab) or simply buy a cheap one (RTX 3060, 4060) because performance boost is huge.

Of course this is not applicable to all problems. But many problems where the runtimes is more than a couple of seconds, GPUs help a lot.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [April 1, 2024, 1:33pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/91 "2024-04-01T13:33:26Z")

</div>

In the department of the crazy ideas, could the needed parts of Julia 1.10 by made into an artifact to be used by LV on Julia \>= 1.11?

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [April 1, 2024, 2:38pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/92 "2024-04-01T14:38:14Z")

</div>

IMHO this approach is fine when computation suits GPU (branchless). The most obvious limitation is available RAM (VRAM) which is rather limited on a GPU compared to CPU.  
Apple hardware offers GPU with huge RAM capacity (up to 192 Go) for a relatively cheap price compared to NVidia. Unfortunately, KernelAbstractions.jl is not really usable for Apple hardware now.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [April 1, 2024, 3:49pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/93 "2024-04-01T15:49:55Z")

</div>

I would be very interested to see how you manage to convert your `@turbo` loops to vectorised versions manually, for my use as a reference. Maybe when you do, you could link the PR here? I’m sure it would be highly appreciated.

> [@roflmaostc](#):
>
> Of course this is not applicable to all problems. But many problems where the runtimes is more than a couple of seconds, GPUs help a lot.

For my use-case it’s not easy. Actually for most inputs the CPU will be faster. See [Native GPU support by MilesCranmer · Pull Request #65 · SymbolicML/DynamicExpressions.jl · GitHub](https://github.com/SymbolicML/DynamicExpressions.jl/pull/65) for my current attempt. For typical input size, an H100 GPU is not as fast as my MacBook Pro CPU, to give you a picture.

Anyways that’s a different discussion. I would strongly prefer to make CPU speeds fast with Julia without needing to switch hardware. My library is used much more by downstream users than myself so I need to make all possible hardware fast.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [April 1, 2024, 4:19pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/94 "2024-04-01T16:19:34Z")

</div>

> [@DNF](#):
>
> This will be a long-term project, so looking ahead to 1.11 and beyond is reasonable, not sure I understand the argument of @mkitti that only 1.10 is relevant.

I did not say Julia 1.11 is not relevant. I’m saying it is not the priority at the moment for improving package performance. There are other priorities with regard to Julia 1.11 itself that need to be addressed. I would rather have a solid foundation in Julia 1.11 rather than trying to build on top of one that is still under construction.

[Julia 1.10 will likely be the Long Term Support release when Julia 1.11 is released](https://discourse.julialang.org/t/new-julia-lts-are-many-using-the-current-julia-1-6-lts/93919/46). At that point, users will have a choice between Julia 1.10 and Julia 1.11, which both will be supported by patches. If that happens and Julia 1.10 is faster for you, by all means use Julia 1.10.

From my perspective, the higher priorities at the moment are as follows.

1. Security issues. The XZ backdoor is an acute problem. A chronic issue is mbedTLS long term support for Julia 1.10.
2. Julia 1.11 package compatibility for those using stable interfaces. For example, fixing libuv so that Cthulhu.jl’s of pipes during precompilation does not fail. [Bump Libuv by Keno · Pull Request #8347 · JuliaPackaging/Yggdrasil · GitHub](https://github.com/JuliaPackaging/Yggdrasil/pull/8347)
3. Improving Julia 1.11 performance and latency. For example, making sure that loading Pkg.jl version 1.11 does not invalidate code in the Julia 1.11 system image: [Pkg.BinaryPlatforms invalidates Base.BinaryPlatforms · Issue #3702 · JuliaLang/Pkg.jl · GitHub](https://github.com/JuliaLang/Pkg.jl/issues/3702)

As you can see there are still a bunch of moving pieces to make Julia 1.11 a viable release.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [April 1, 2024, 4:31pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/95 "2024-04-01T16:31:07Z")

</div>

> [@Ahmed\_Salih](#):
>
> Personally I think this is quite an interesting dilemma for Julia as a community, since it has always been proposed as a language to write the fastest numerical codes etc. and suddenly one huge back-bone of achieving this is ripped out rather abruptly.

This does not seem abrupt to me at all. Chris has provided a transition off ramp. You will still have long term support (3+ years) on Julia 1.10, which you can continue to use. You just will not have access to some new features at worse. Some of those new features are the very ones that break LoopVectorization such as fundamentally changing how Julia arrays work under the hood.

> [@Ahmed\_Salih](#):
>
> - Some parts of the eco-system version lock them to 1.10, going against Julia “philosophy” of always being quite easily upgradeable and gaining the new futures quickly (perhaps my personal understanding)

The main underlying philosophy here is semantic versioning. Your code should still run in future Julia 1.x versions and that remains true in this case. What is not guaranteed is that there performance will monotonically increase with successive Julia versions. Sometimes the underlying mechanisms need to change to make things better. Julia 1.11 is the beginning of another cycle. Performance may get worse before it gets better.

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [April 1, 2024, 5:50pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/96 "2024-04-01T17:50:25Z")

</div>

> [@mkitti](#):
>
> Your code should still run in future Julia 1.x versions and that remains true in this case.

In this case this is not true, right? LoopVectorization.jl does not run anymore. But because it used Julia internals which are not guaranteed to not change.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [April 1, 2024, 5:58pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/97 "2024-04-01T17:58:03Z")

</div>

Package pinning would fix this though, right? There are versions of LoopVectorization.jl that work on Julia 1.9 for example, so as long as you had the correct versions it will still work.

---

<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:** [April 1, 2024, 6:41pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/98 "2024-04-01T18:41:53Z")

</div>

> [@mkitti](#):
>
> I’m saying it is not the priority at the moment for improving package performance. There are other priorities with regard to Julia 1.11 itself that need to be addressed.

I’m not trying to influence the development of 1.11 one way or the other, nor to criticize the work being done or its prioritization. I’m simply reacting to the apparent attitude that this is not really a big deal. I’m not proposing anything “actionable”.

> [@mkitti](#):
>
> If that happens and Julia 1.10 is faster for you, by all means use Julia 1.10.

Unfortunately, while somewhat dreading the deprecation of LV, I am simultaneously eagerly awaiting the advances made towards compilation of executables, since my library must be distributed like that. It’s a dilemma.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [April 1, 2024, 7:03pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/99 "2024-04-01T19:03:30Z")

</div>

> [@mkitti](#):
>
> Sometimes the underlying mechanisms need to change to make things better.

I am sure there is a good reason but I confess I don’t feel this way when I stare at my 2-5x slower benchmarks 😕

I guess I just wish LV was somehow integrated into Julia standard library a long time ago so this wouldn’t happen, and any internal changes would be copied over regularly. Julia promises speed; good vectorization seems key to that promise.

Perhaps some of these major internal changes should have been paused from release until built-in Julia vectorization caught up to same ballpark as LV, since it’s evidently not yet close. (This also doesn’t seem like a niche use-case, no? Aren’t tons of people doing heavy vectorized array operations in Julia?)

I don’t see the argument about avoiding 1.11. I can do that personally, but my downstream users won’t do this. They will feel the slowness and not really know why. And I also don’t see 1.11-beta suddenly fixing this, given regular `@inbounds @simd` has never been as good as `@turbo`, and now `@turbo` is gone.

But this all being said I don’t want to be too pessimistic; like @DNF I am excited about the directions in static compilation. Just not sure they make up for the huge performance hits yet.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 1, 2024, 7:25pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/100 "2024-04-01T19:25:29Z")

</div>

> [@MilesCranmer](#):
>
> I don’t see the argument about avoiding 1.11. I can do that personally, but my downstream users won’t do this. They will feel the slowness and not really know why.

Well, this could easily be solved by taking upper bounds of the Julia version of a package in Project.toml serious and just don’t allow to install a package with a Julia version that is not mentioned in Project.toml as valid.

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [April 1, 2024, 10:39pm UTC](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547/101 "2024-04-01T22:39:58Z")

</div>

That is not a solution for Miles or his package users anyways, since then the users would be implicitly version locked to 1.10? I know from my self, that I have not in the past not upgraded Julia to stick to one package, the only time I remember actually considering not to upgrade, is in this case for the upcoming 1.11, since my work at the time would be meaningless without `LoopVectorization.jl` - it would become too slow to be practical.

I think there are a lot of valid points floating around, such as to get somewhere better one has to forego the best solution currently, but it is a bit scary for the eco-system as a whole when one package is deprecated and performance _tanks_ in multiple different packages from all kind of projects.

I think the stress would be a lot lower, if someone could show-case how to get near similar level of performance as `LoopVectorization` without using it - but I have not seen anyone do that yet.

[Previous page](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547.md?page=4)

[Next page](https://discourse.julialang.org/t/why-is-loopvectorization-deprecated/109547.md?page=6)
