Hi, im trying to make a fast evaluation of the value, first and second derivative, in the least amount of forward passes as possible. i’m using at the moment this function:
using DiffResults, StaticArrays, ForwardDiff
function f∂f∂2f(f,x::T) where T
_f(z) = f(only(z))
x_vec = SVector(x)
∂result = DiffResults.HessianResult(x_vec)
_∂f = ForwardDiff.hessian!(∂result, _f,x_vec)
fx = DiffResults.value(_∂f)
∂f∂x = only(DiffResults.gradient(_∂f))
∂²f∂²x = only(DiffResults.hessian(_∂f))
return fx,∂f∂x,∂²f∂²x
end
but, even as everything seems defined statically, this function allocates:
julia> @btime f∂f∂2f(sin,$Ref(2.0)[])
78.189 ns (1 allocation: 96 bytes)
(0.9092974268256817, -0.4161468365471424, -0.9092974268256817)
the same version, but only obtaining the first derivative, doesn’t allocate:
function f∂f(f,x::T) where T
_f(z) = f(only(z))
x_vec = SVector(x)
∂result = DiffResults.GradientResult(x_vec)
_∂f = ForwardDiff.gradient!(∂result, _f,x_vec)
fx = DiffResults.value(_∂f)
∂f∂x = only(DiffResults.gradient(_∂f))
return fx,∂f∂x
end
>julia @btime f∂f(sin,$Ref(2.0)[])
16.116 ns (0 allocations: 0 bytes)
(0.9092974268256817, -0.4161468365471424)
any idea on how to improve the situation here?