# Getting ForwardDiff jacobian! to execute with zero allocations

**URL:** <https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503>\
**Category:** Performance\
**Tags:** performance, memory-allocation, forwarddiff\
**Created:** [December 3, 2021, 4:12am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503 "2021-12-03T04:12:41Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Anthony](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anthony/32/23968_2.png) [@Anthony](https://discourse.julialang.org/u/Anthony)\
**Post date:** [December 3, 2021, 4:12am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/1 "2021-12-03T04:12:42Z")

</div>

I’ve been trying (so far unsuccessfully) to figure out how to execute ForwardDiff’s jacobian! function such that it will not perform additional allocations once compiled. However, I’ve been unable to figure out how to accomplish this based on the documentation and advice from others (I found a number of outdated examples that don’t yield zero allocations for me, but they’re generally older versions).

I have a minimum viable example below. I would really appreciate advice on where these last few allocations are coming from, and perhaps more general suggestions on how to pinpoint their location.

```julia
using ForwardDiff

function f!(y, x)
    y[1] = x[1]^2
    y[2] = x[2] - x[3]
    y[3] = x[1] + x[2]
    y[4] = x[1] - x[3]^2
    nothing
end

function test_jacobian_allocs()
    x = ones(3)
    y = zeros(4)

    @time f!(y, x)
    @time f!(y, x)

    cfg = ForwardDiff.JacobianConfig(f!, y, x)
    result = Matrix{Float64}(undef, length(y), length(x))

    @time ForwardDiff.jacobian!(result, f!, y, x, cfg)
    @time ForwardDiff.jacobian!(result, f!, y, x, cfg)

    nothing
end

```

Running yields

```julia
julia> test_jacobian_allocs()
  0.000001 seconds
  0.000001 seconds
  2.564904 seconds (3.52 M allocations: 199.496 MiB, 4.63% gc time, 99.99% compilation time)
  0.000016 seconds (1 allocation: 96 bytes)

```

On another function which also has zero allocations (not the f! I made up here) the exact same code yields 2 allocations instead. I’m very confused about what’s going on!

ForwardDiff version is v0.10.23.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [December 3, 2021, 6:33am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/2 "2021-12-03T06:33:21Z")

</div>

`@code_warntype` reports a type instability here

```julia
cfg = ForwardDiff.JacobianConfig(f!, y, x)

```

So you probably need to specify something like

```julia
cfg = ForwardDiff.JacobianConfig(f!, y, x, ForwardDiff.Chunk{3}())

```

---

<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:** [December 3, 2021, 6:39am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/3 "2021-12-03T06:39:12Z")

</div>

i confirm, adding chunks on the config eliminates the allocations

---

<div class="post-metadata">

**Author:** ![Anthony](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anthony/32/23968_2.png) [@Anthony](https://discourse.julialang.org/u/Anthony)\
**Post date:** [December 3, 2021, 1:55pm UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/4 "2021-12-03T13:55:57Z")

</div>

Oh wow, that fixed it. I had previously tried `Chunks{length(x)}()` which I guess has the same problem. Thank you for the `@code_warntypes` tip!

---

<div class="post-metadata">

**Author:** ![Lisette\_de\_Bruin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lisette_de_bruin/32/51838_2.png) [@Lisette\_de\_Bruin](https://discourse.julialang.org/u/Lisette_de_Bruin)\
**Post date:** [April 8, 2024, 10:04am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/5 "2024-04-08T10:04:19Z")

</div>

I know that this is an old topic, but still worth a try.

I am trying the exact same thing, so find the Jacobian of a vector valued function with minimal memory allocations using ForwardDiff.jl. Below you see a minimal working example.

```julia
M = @SVector([10.0, 0.0, 0.0])

function f!(y, r, M)
    y[1] = M * r[3]/norm(r)
    y[2] = M * r[1]/norm(r)
    y[3] = M * r[2]/norm(r)
end

function curl_of_function(f!, r)
    out=zeros(3)
    
    config = ForwardDiff.JacobianConfig(f!, out, r, ForwardDiff.Chunk{3}())
    Jac = Matrix{Float64}(undef, length(out), length(r))

    ForwardDiff.jacobian!(Jac, f!, out, r, config)
    curl_x = Jac[3,2] - Jac[2,3]
    curl_y = Jac[1,3] - Jac[3,1]
    curl_z = Jac[2,1] - Jac[1,2]
    return @SVector[curl_x, curl_y, curl_z]
end

 @btime curl_of_function(f!, [2.0, 1.0, 0.0])

# 603.315 ns (7 allocations: 576 bytes)

```

Since I have to use this function many times in my code, I wish to reduce the memory allocations. I noticed that

```julia
@btime ForwardDiff.jacobian!($Jac, $f!, $out, $r, $config)

# 308.907 ns (0 allocations: 0 bytes)

```

Can I reduce the allocations of the total code?  
Thanks in advance!

---

<div class="post-metadata">

**Author:** ![Domenico\_Lahaye](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/domenico_lahaye/32/203728_2.png) [@Domenico\_Lahaye](https://discourse.julialang.org/u/Domenico_Lahaye)\
**Post date:** [April 8, 2024, 11:26am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/6 "2024-04-08T11:26:37Z")

</div>

How do you define the variable y prior to the call to f! ?

---

<div class="post-metadata">

**Author:** ![Lisette\_de\_Bruin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lisette_de_bruin/32/51838_2.png) [@Lisette\_de\_Bruin](https://discourse.julialang.org/u/Lisette_de_Bruin)\
**Post date:** [April 8, 2024, 11:35am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/7 "2024-04-08T11:35:20Z")

</div>

I don’t define the variable y prior to the call of f!

---

<div class="post-metadata">

**Author:** ![touste](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touste/32/10758_2.png) [@touste](https://discourse.julialang.org/u/touste)\
**Post date:** [April 8, 2024, 12:41pm UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/8 "2024-04-08T12:41:51Z")

</div>

Can you use static arrays all the way?  
This does not allocate:

```julia
const M = @SVector [10.0, 0.0, 0.0]

function f(r, M)
    return M .* r/norm(r)
end

function curl_of_function(f, r)
    Jac = ForwardDiff.jacobian(f, r)
    curl_x = Jac[3,2] - Jac[2,3]
    curl_y = Jac[1,3] - Jac[3,1]
    curl_z = Jac[2,1] - Jac[1,2]
    return @SVector[curl_x, curl_y, curl_z]
end

@btime curl_of_function(x->f(x, M), @SVector [2.0, 1.0, 0.0])

```

---

<div class="post-metadata">

**Author:** ![Lisette\_de\_Bruin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lisette_de_bruin/32/51838_2.png) [@Lisette\_de\_Bruin](https://discourse.julialang.org/u/Lisette_de_Bruin)\
**Post date:** [April 26, 2024, 9:12am UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/9 "2024-04-26T09:12:10Z")

</div>

Thanks for your answer. I am a little late, but I still have the following question: Now I can’t change the value of M. I want to be able to repeat this for different values of M.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [April 26, 2024, 12:35pm UTC](https://discourse.julialang.org/t/getting-forwarddiff-jacobian-to-execute-with-zero-allocations/72503/10 "2024-04-26T12:35:35Z")

</div>

Just avoid defining `M` as a `const` and it should work
