I’m trying to get rid of the memory allocations in jacobian!
. For this, I need to pass a cfg
argument with a pre-allocated JacobianConfig
to the function. According to the doc, its constructor expects to receive the function that will be differentiated. We can pass nothing
as the function, but it seems that it’s dangerous for perturbation confusions. I tried to read the related github issue but it was very hard to follow.
In my use case, I cannot pass the function to JacobianConfig
since I need a closure. And I need a closure because we cannot pass any argument other than y
and x
to the function to be differentiated. Here’s a MWE (here I need to also pass current u
value to f!
):
using ForwardDiff, BenchmarkTools
function f!(y, x, u)
y .= x .+ u
return nothing
end
function getJac!(A, y, config, x, u)
f_at_u! = (y, x) -> f!(y, x, u)
ForwardDiff.jacobian!(A, f_at_u!, y, x, config)
return nothing
end
A = zeros(2,2)
y = zeros(2)
x = ones(2)
u = ones(2)
myf! = nothing
config = ForwardDiff.JacobianConfig(myf!, y, x)
@btime getJac!($A, $y, $config, $x, $u)
A
results in 0 allocation as expected:
22.971 ns (0 allocations: 0 bytes)
2×2 Matrix{Float64}:
1.0 0.0
0.0 1.0
In simple words, what’s the consequence of passing nothing
to JacobianConfig
? If the code inside f!
would also rely on ForwardDiff.jl differentiation, is there any risk that the Jocabians get completely wrong?
Otherwise, is there any other way than passing nothing
to JacobianConfig
when we need closures like that?
Thanks for the help!