Skip to content

Can't compute ForwardDiff hessian #627

@bclyons12

Description

@bclyons12

I was testing the master version of Interpolations.jl on my code and ran into an error inside of an optimizer with autodifferentiation. It looks like I can't take the ForwardDiff.hessian of a 2D cubic spline interpolation any more. Below is a minimal example, which works fine on Interpolations.jl v0.15 but fails on master (for either ForwardDiff v0.10 or v1). It looks like some issue with nested Duals.

import Pkg; Pkg.activate(temp=true)
Pkg.add(name="Interpolations", rev="master")
Pkg.add(name="ForwardDiff")
import Interpolations, ForwardDiff

N = 11
x = range(1.0, 3.0, N)
y = range(-3.0, 3.0, N)
u = rand(N, N)
uitp = Interpolations.cubic_spline_interpolation((x, y), u; extrapolation_bc=Interpolations.Line())

f = x -> uitp(x[1], x[2])
x = [π/3, -π/2]

ForwardDiff.hessian(f, x)

which gives:

Activating new project at `[/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV](http://localhost:8888/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV)`
    Updating git-repo `[https://github.com/JuliaMath/Interpolations.jl.git`](https://github.com/JuliaMath/Interpolations.jl.git%60)
   Resolving package versions...
    Updating `[/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Project.toml](http://localhost:8888/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Project.toml)`
  [a98d9a8b] + Interpolations v0.16.0 `[https://github.com/JuliaMath/Interpolations.jl.git#master`](https://github.com/JuliaMath/Interpolations.jl.git#master%60)
    Updating `[/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Manifest.toml](http://localhost:8888/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Manifest.toml)`
  [79e6a3ab] + Adapt v4.3.0
  [13072b0f] + AxisAlgorithms v1.1.0
  [d360d2e6] + ChainRulesCore v1.25.1
  [34da2185] + Compat v4.16.0
  [a98d9a8b] + Interpolations v0.16.0 `[https://github.com/JuliaMath/Interpolations.jl.git#master`](https://github.com/JuliaMath/Interpolations.jl.git#master%60)
  [6fe1bfb0] + OffsetArrays v1.17.0
⌅ [aea7be01] + PrecompileTools v1.2.1
  [21216c6a] + Preferences v1.4.3
  [c84ed2f1] + Ratios v0.4.5
  [ae029012] + Requires v1.3.1
  [90137ffa] + StaticArrays v1.9.13
  [1e83bf80] + StaticArraysCore v1.4.3
  [efce3f68] + WoodburyMatrices v1.0.0
  [56f22d72] + Artifacts v1.11.0
  [ade2ca70] + Dates v1.11.0
  [8ba89e20] + Distributed v1.11.0
  [8f399da3] + Libdl v1.11.0
  [37e2e46d] + LinearAlgebra v1.11.0
  [a63ad114] + Mmap v1.11.0
  [de0858da] + Printf v1.11.0
  [9a3f8284] + Random v1.11.0
  [ea8e919c] + SHA v0.7.0
  [9e88b42a] + Serialization v1.11.0
  [1a1011a3] + SharedArrays v1.11.0
  [6462fe0b] + Sockets v1.11.0
  [2f01184e] + SparseArrays v1.11.0
  [fa267f1f] + TOML v1.0.3
  [cf7118a7] + UUIDs v1.11.0
  [4ec0a83e] + Unicode v1.11.0
  [e66e0078] + CompilerSupportLibraries_jll v1.1.1+0
  [4536629a] + OpenBLAS_jll v0.3.27+1
  [bea87d4a] + SuiteSparse_jll v7.7.0+0
  [8e850b90] + libblastrampoline_jll v5.11.0+0
        Info Packages marked with ⌅ have new versions available but compatibility constraints restrict them from upgrading. To see why use `status --outdated -m`
   Resolving package versions...
    Updating `[/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Project.toml](http://localhost:8888/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Project.toml)`
  [f6369f11] + ForwardDiff v1.0.1
    Updating `[/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Manifest.toml](http://localhost:8888/private/var/folders/nt/ct_lf2n94_1c21908mmbx55w0000gq/T/jl_n8v5VV/Manifest.toml)`
  [bbf7d656] + CommonSubexpressions v0.3.1
  [163ba53b] + DiffResults v1.1.0
  [b552c78f] + DiffRules v1.15.1
  [ffbed154] + DocStringExtensions v0.9.4
  [f6369f11] + ForwardDiff v1.0.1
  [92d709cd] + IrrationalConstants v0.2.4
  [692b3bcd] + JLLWrappers v1.7.0
  [2ab3a3ac] + LogExpFunctions v0.3.29
  [1914dd2f] + MacroTools v0.5.16
  [77ba4419] + NaNMath v1.1.3
  [276daf66] + SpecialFunctions v2.5.1
  [efe28fd5] + OpenSpecFun_jll v0.5.6+0
  [05823500] + OpenLibm_jll v0.8.5+0
MethodError: no method matching ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}(::Float64, ::ForwardDiff.Partials{2, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}})
The type `ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}` exists, but no method is defined for this combination of argument types when trying to construct it.

Closest candidates are:
  ForwardDiff.Dual{T, V, N}(::Number) where {T, V, N}
   @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/dual.jl:78](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/dual.jl#line=77)
  ForwardDiff.Dual{T, V, N}(::Any) where {T, V, N}
   @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/dual.jl:77](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/dual.jl#line=76)
  ForwardDiff.Dual{T, V, N}(::V, ::ForwardDiff.Partials{N, V}) where {T, V, N}
   @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/dual.jl:17](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/dual.jl#line=16)
  ...


Stacktrace:
  [1] apply_partials(x_dual::ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}, val::Float64)
    @ InterpolationsForwardDiffExt [~/.julia/packages/Interpolations/5GvP0/ext/InterpolationsForwardDiffExt.jl:19](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/Interpolations/5GvP0/ext/InterpolationsForwardDiffExt.jl#line=18)
  [2] _broadcast_getindex_evalf
    @ ./broadcast.jl:678 [inlined]
  [3] _broadcast_getindex
    @ ./broadcast.jl:651 [inlined]
  [4] (::Base.Broadcast.var"#17#18"{Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple}, Nothing, typeof(InterpolationsForwardDiffExt.apply_partials), Tuple{Tuple{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}}, Tuple{Float64, Float64}}}})(k::Int64)
    @ Base.Broadcast ./broadcast.jl:1102
  [5] ntuple
    @ ./ntuple.jl:49 [inlined]
  [6] copy
    @ ./broadcast.jl:1102 [inlined]
  [7] materialize
    @ ./broadcast.jl:872 [inlined]
  [8] maybe_clamp(::Interpolations.NeedsCheck, itp::Interpolations.BSplineInterpolation{Float64, 2, OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Interpolations.BSpline{Interpolations.Cubic{Interpolations.Line{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, xs::Tuple{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}})
    @ InterpolationsForwardDiffExt [~/.julia/packages/Interpolations/5GvP0/ext/InterpolationsForwardDiffExt.jl:12](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/Interpolations/5GvP0/ext/InterpolationsForwardDiffExt.jl#line=11)
  [9] maybe_clamp(itp::Interpolations.BSplineInterpolation{Float64, 2, OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Interpolations.BSpline{Interpolations.Cubic{Interpolations.Line{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, xs::Tuple{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}})
    @ Interpolations [~/.julia/packages/Interpolations/5GvP0/src/Interpolations.jl:450](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/Interpolations/5GvP0/src/Interpolations.jl#line=449)
 [10] ScaledInterpolation
    @ [~/.julia/packages/Interpolations/5GvP0/src/scaling/scaling.jl:81](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/Interpolations/5GvP0/src/scaling/scaling.jl#line=80) [inlined]
 [11] (::Interpolations.Extrapolation{Float64, 2, Interpolations.ScaledInterpolation{Float64, 2, Interpolations.BSplineInterpolation{Float64, 2, OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Interpolations.BSpline{Interpolations.Cubic{Interpolations.Line{Interpolations.OnGrid}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, Interpolations.BSpline{Interpolations.Cubic{Interpolations.Line{Interpolations.OnGrid}}}, Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}, Interpolations.BSpline{Interpolations.Cubic{Interpolations.Line{Interpolations.OnGrid}}}, Interpolations.Line{Nothing}})(::ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}, ::ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2})
    @ Interpolations [~/.julia/packages/Interpolations/5GvP0/src/extrapolation/extrapolation.jl:54](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/Interpolations/5GvP0/src/extrapolation/extrapolation.jl#line=53)
 [12] (::var"#1#2")(x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}})
    @ Main ./In[1]:12
 [13] vector_mode_dual_eval!
    @ [~/.julia/packages/ForwardDiff/Wq9Wb/src/apiutils.jl:24](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/apiutils.jl#line=23) [inlined]
 [14] vector_mode_gradient(f::var"#1#2", x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}}})
    @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/gradient.jl:98](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/gradient.jl#line=97)
 [15] gradient
    @ [~/.julia/packages/ForwardDiff/Wq9Wb/src/gradient.jl:20](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/gradient.jl#line=19) [inlined]
 [16] #107
    @ [~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl:17](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl#line=16) [inlined]
 [17] vector_mode_dual_eval!
    @ [~/.julia/packages/ForwardDiff/Wq9Wb/src/apiutils.jl:24](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/apiutils.jl#line=23) [inlined]
 [18] vector_mode_jacobian(f::ForwardDiff.var"#107#108"{var"#1#2", ForwardDiff.HessianConfig{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}}}}, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}}})
    @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/jacobian.jl:129](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/jacobian.jl#line=128)
 [19] jacobian
    @ [~/.julia/packages/ForwardDiff/Wq9Wb/src/jacobian.jl:22](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/jacobian.jl#line=21) [inlined]
 [20] hessian
    @ [~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl:18](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl#line=17) [inlined]
 [21] hessian(f::var"#1#2", x::Vector{Float64}, cfg::ForwardDiff.HessianConfig{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}, 2}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#1#2", Float64}, Float64, 2}}})
    @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl:15](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl#line=14)
 [22] hessian(f::var"#1#2", x::Vector{Float64})
    @ ForwardDiff [~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl:15](http://localhost:8888/lab/tree/FUSE/playground/~/.julia/packages/ForwardDiff/Wq9Wb/src/hessian.jl#line=14)
 [23] top-level scope
    @ In[1]:15

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugregressionFeatures that used to work but no longer work

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions