# Getting to zero allocations in NonlinearSolve.jl

**URL:** <https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123>\
**Category:** Performance\
**Tags:** nlsolve, nonlinearsolve\
**Created:** [November 26, 2024, 8:19pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123 "2024-11-26T20:19:34Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![rafaelbailo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafaelbailo/32/215573_2.png) [@rafaelbailo](https://discourse.julialang.org/u/rafaelbailo)\
**Post date:** [November 26, 2024, 8:19pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/1 "2024-11-26T20:19:34Z")

</div>

I am in the process of migrating some code from NLsolve.jl to NonlinearSolve.jl. I have written a simple Newton-Raphson test, but I cannot get the allocations down to zero; both `solve!` and `reinit!` allocate. Can this be improved?

```julia
using NonlinearSolve

N = 1000
u0 = rand(N)
f!(J, u, p) = @. J = (u - 1)

problem = NonlinearProblem{true}(f!, u0)
solver = NewtonRaphson(
  autodiff = AutoForwardDiff(;
    chunksize = NonlinearSolve.pickchunksize(problem.u0),
  ),
)
cache = init(problem, solver)

solve!(cache)
reinit!(cache)

println(@allocated solve!(cache))
println(@allocated reinit!(cache))

```

---

<div class="post-metadata">

**Author:** ![avikpal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avikpal/32/6550_2.png) [@avikpal](https://discourse.julialang.org/u/avikpal)\
**Post date:** [November 26, 2024, 9:39pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/2 "2024-11-26T21:39:57Z")

</div>

The caching API minimizes allocations but doesn’t make them go down to zero. The allocations in the above code would come from LU factorization IIRC.

---

<div class="post-metadata">

**Author:** ![avikpal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avikpal/32/6550_2.png) [@avikpal](https://discourse.julialang.org/u/avikpal)\
**Post date:** [November 26, 2024, 9:41pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/3 "2024-11-26T21:41:32Z")

</div>

Zero allocations is only possible for StaticArrays but that wouldn’t be performant for such large arrays

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 26, 2024, 10:07pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/4 "2024-11-26T22:07:26Z")

</div>

> [@avikpal](#):
>
> The caching API minimizes allocations but doesn’t make them go down to zero. The allocations in the above code would come from LU factorization IIRC.

may i ask why the LU factorization allocates? in theory, an LU factorization only requires to allocate 1 matrix and 1 Integer vector.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [November 28, 2024, 10:54am UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/5 "2024-11-28T10:54:50Z")

</div>

Julia interface for mutating LU accepts only a matrix and allocates a new permutation vector each time.

---

<div class="post-metadata">

**Author:** ![fastwave](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fastwave/32/14725_2.png) [@fastwave](https://discourse.julialang.org/u/fastwave)\
**Post date:** [November 28, 2024, 11:38am UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/6 "2024-11-28T11:38:05Z")

</div>

If worried about allocations, [GitHub - DynareJulia/FastLapackInterface.jl](https://github.com/DynareJulia/FastLapackInterface.jl) allows you to pre-allocate temporaries and reuse them…

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 28, 2024, 4:40pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/7 "2024-11-28T16:40:18Z")

</div>

It’s quite a bit slower though in many cases.

---

<div class="post-metadata">

**Author:** ![fastwave](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fastwave/32/14725_2.png) [@fastwave](https://discourse.julialang.org/u/fastwave)\
**Post date:** [November 28, 2024, 6:43pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/8 "2024-11-28T18:43:58Z")

</div>

Hi Chris, would you know by any chance if [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) supports pre-allocation? At least for the native julia backend?

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 28, 2024, 9:21pm UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/9 "2024-11-28T21:21:44Z")

</div>

> <https://github.com/JuliaLang/LinearAlgebra.jl/pull/1125>
>
> when performing LU factorizations, a \`Vector{BlasInt}\` is allocated each time. i…n conjuction with a matrix \`A\`. \`lu!\` allows reusing a matrix, but it still allocates the vector. This PR allows passing \`ipiv\` as an input to \`lu!\`, so no allocations are performed, if required.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 29, 2024, 6:05am UTC](https://discourse.julialang.org/t/getting-to-zero-allocations-in-nonlinearsolve-jl/123123/10 "2024-11-29T06:05:30Z")

</div>

> [@fastwave](#):
>
> Hi Chris, would you know by any chance if [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) supports pre-allocation? At least for the native julia backend?

If you use the `init` interface it will allocate all caches required for `solve!`, as described in

> **[Linear Solve with Caching Interface · LinearSolve.jl](https://docs.sciml.ai/LinearSolve/stable/tutorials/caching_interface/)**
>
> Documentation for LinearSolve.jl.
