Skip to content

Autodiff fails mysteriously with well-defined nested defaults #2997

@hersle

Description

@hersle

I am very confused by this. On my computer, the example

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using ForwardDiff

pars = @parameters y0 mh Tγ0 Th0 h ργ0
vars = @variables x(t)
@named sys = ODESystem([D(x) ~ y0], t, vars, pars; defaults = [
    y0 => mh*3.1 / (2.3*Th0),
    mh => 123.4, # change to 123.3 and everything runs (???)
    Th0 => (4/11)^(1/3) * Tγ0,
    Tγ0 => (15/π^2 * ργ0 * (2*h)^2/7)^(1/4) / 5,
])
sys = structural_simplify(sys)

function x_at_0(θ)
    prob = ODEProblem(sys, [sys.x => 1.0], (0.0, 1.0), [sys.ργ0 => θ[1], sys.h => θ[2]])
    return prob.u0[1]
end

ForwardDiff.gradient(x_at_0, [0.3, 0.7])

(where all parameter defaults follow from ργ0 and h) unexpectedly fails with

ERROR: LoadError: MethodError: isequal(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(x_at_0), Float64}, Float64, 2}, ::Num) is ambiguous.

Candidates:
  isequal(x::ForwardDiff.Dual{Tx}, y::Real) where Tx
    @ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/dual.jl:144
  isequal(a::Number, b::Num)
    @ Symbolics ~/.julia/dev/SymBoltz/dev/Symbolics/src/num.jl:131

Possible fix, define
  isequal(::ForwardDiff.Dual{Tx}, ::Num) where Tx

Stacktrace:
  [1] ht_keyindex(h::Dict{Any, Any}, key::ForwardDiff.Dual{ForwardDiff.Tag{typeof(x_at_0), Float64}, Float64, 2})
    @ Base ./dict.jl:275
  [2] get
    @ ./dict.jl:524 [inlined]
  [3] #fast_substitute#246
    @ ~/.julia/dev/SymBoltz/dev/Symbolics/src/variable.jl:474 [inlined]
  [4] fixpoint_sub(x::SymbolicUtils.BasicSymbolic{Real}, dict::Dict{Any, Any}; operator::Type)
    @ Symbolics ~/.julia/dev/SymBoltz/dev/Symbolics/src/variable.jl:432
  [5] fixpoint_sub(x::SymbolicUtils.BasicSymbolic{Real}, dict::Dict{Any, Any})
    @ Symbolics ~/.julia/dev/SymBoltz/dev/Symbolics/src/variable.jl:426
  [6] (::ModelingToolkit.var"#126#134"{Dict{Any, Any}})(::Pair{Any, Any})
    @ ModelingToolkit ./none:0
  [7] iterate
    @ ./generator.jl:47 [inlined]
  [8] _all(f::Base.var"#384#386", itr::Base.Generator{Dict{Any, Any}, ModelingToolkit.var"#126#134"{Dict{Any, Any}}}, ::Colon)
    @ Base ./reduce.jl:1297
  [9] all
    @ ./reduce.jl:1283 [inlined]
 [10] Dict(kv::Base.Generator{Dict{Any, Any}, ModelingToolkit.var"#126#134"{Dict{Any, Any}}})
    @ Base ./dict.jl:111
 [11] MTKParameters(sys::ODESystem, p::Dict{…}, u0::Vector{…}; tofloat::Bool, use_union::Bool, t0::Float64)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/parameter_buffer.jl:109
 [12] process_DEProblem(constructor::Type, sys::ODESystem, u0map::Vector{…}, parammap::Vector{…}; implicit_dae::Bool, du0map::Nothing, version::Nothing, tgrad::Bool, jac::Bool, checkbounds::Bool, sparse::Bool, simplify::Bool, linenumbers::Bool, parallel::Symbolics.SerialForm, eval_expression::Bool, eval_module::Module, use_union::Bool, tofloat::Bool, symbolic_u0::Bool, u0_constructor::typeof(identity), guesses::Dict{…}, t::Float64, warn_initialize_determined::Bool, build_initializeprob::Bool, initialization_eqs::Vector{…}, fully_determined::Bool, check_units::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:845
 [13] process_DEProblem
    @ ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:766 [inlined]
 [14] (ODEProblem{})(sys::ODESystem, u0map::Vector{…}, tspan::Tuple{…}, parammap::Vector{…}; callback::Nothing, check_length::Bool, warn_initialize_determined::Bool, eval_expression::Bool, eval_module::Module, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:992
 [15] (ODEProblem{})(sys::ODESystem, u0map::Vector{…}, tspan::Tuple{…}, parammap::Vector{…})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:980
 [16] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:967
 [17] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:966
 [18] ODEProblem(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any}; kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:956
 [19] ODEProblem(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/K6okj/src/systems/diffeqs/abstractodesystem.jl:955
 [20] x_at_0::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(x_at_0), Float64}, Float64, 2}})
    @ Main ~/.julia/dev/SymBoltz/bug.jl:46
 [21] vector_mode_dual_eval!
    @ ~/.julia/packages/ForwardDiff/PcZ48/src/apiutils.jl:24 [inlined]
 [22] vector_mode_gradient(f::typeof(x_at_0), x::Vector{…}, cfg::ForwardDiff.GradientConfig{…})
    @ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:89
 [23] gradient(f::Function, x::Vector{…}, cfg::ForwardDiff.GradientConfig{…}, ::Val{…})
    @ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:19
 [24] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{…}, Float64, 2, Vector{…}})
    @ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:17
 [25] top-level scope
    @ ~/.julia/dev/SymBoltz/bug.jl:50
in expression starting at /home/hermasl/.julia/dev/SymBoltz/bug.jl:50

Strangely, if I change mh => 123.4 to mh => 123.3, the example runs as expected. Many other tiny tweaks also make it run.

Are you able to reproduce this? What could cause this?

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions