Allocation on ForwardDiff + DiffResults + StaticArrays

Im hunting down an allocation on DiffResults + ForwardDiff + StaticArrays. this is the MWE:

using ForwardDiff, DiffResults, StaticArrays, BenchmarkTools
fff(v1,v2) = sin(v1)+cos(v2)+exp(v1+log(v2+cos(v1)))
function ∂test(a1,a2)
    f(x) = fff(first(x),last(x))
    T = promote_type(typeof(a1),typeof(a2))
    _a1 = T(a1)
    _a2 = T(a2)
    a_vec =   SVector(_a1,_a2)
    ∂result = DiffResults.GradientResult(a_vec)
    _∂f =  ForwardDiff.hessian!(∂result, f,a_vec)
    val_f =  DiffResults.value(_∂f)
    val_∂f = DiffResults.gradient(_∂f)
    return (val_f,val_∂f)
endfunction ∂2test(a1,a2)
    f(x) = fff(first(x),last(x))
    T = promote_type(typeof(a1),typeof(a2))
    _a1 = T(a1)
    _a2 = T(a2)
    a_vec =   SVector(_a1,_a2)
    ∂result = DiffResults.HessianResult(a_vec)
    _∂f =  ForwardDiff.hessian!(∂result, f,a_vec)
    val_f =  DiffResults.value(_∂f)
    val_∂f = DiffResults.gradient(_∂f)
    val_∂2f = DiffResults.hessian(_∂f)
    return (val_f,val_∂f,val_∂2f)
end

@btime ∂test(0.4,0.4)
@btime ∂2test(0.4,0.4)

∂test doesn’t allocate, but ∂2test does. any ideas on what’s happening?
im almost sure the problem is on ForwardDiff.hessian! , but it worked fine with gradient! , does it need to specify a ForwardDiff.Chunk? is necesary a HessianConfig in the case of StaticArrays ?
in the real use case, fff has more arguments and dispatches (but the test functions always fixes two of those arguments)

I think your first function doesn’t run (you need a HessianResult for a Hessian).

I can confirm that this is happening, but I have not been able to solve it even with an explicit config. If you don’t get a more useful reply here, consider opening an issue for ForwardDiff.

1 Like

Cf

https://github.com/JuliaDiff/ForwardDiff.jl/pull/315

Something similar for Hessian may help resolve this.

1 Like