Skip to content

ForwardDiff does not work directly through ODEProblem #2667

@hersle

Description

@hersle

Auto-differentiating through remake(ODEProblem()) works, but not directly through ODEProblem():

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

@testset "ForwardDiff through ODEProblem with vs. without remake" begin
    @parameters P
    @variables x(t)
    sys = structural_simplify(ODESystem([D(x) ~ P], t, [x], [P]; name=:sys))
    
    function x_at_1(P; use_remake = false)
        if use_remake
            prob = ODEProblem(sys, [x => 0.0], (0.0, 1.0), [sys.P => NaN])
            prob = remake(prob; p = [sys.P => P])
        else
            prob = ODEProblem(sys, [x => 0.0], (0.0, 1.0), [sys.P => P])
        end
        return solve(prob)(1.0)
    end

    @test_nowarn ForwardDiff.derivative(P -> x_at_1(P; use_remake=true),  1.0) # passes
    @test_nowarn ForwardDiff.derivative(P -> x_at_1(P; use_remake=false), 1.0) # fails
end

The last test errors with

  MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1})

  Closest candidates are:
    (::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat
     @ Base rounding.jl:207
    (::Type{T})(::T) where T<:Number
     @ Core boot.jl:792
    Float64(::IrrationalConstants.Loghalf)
     @ IrrationalConstants C:\Users\herma\.julia\packages\IrrationalConstants\vp5v4\src\macro.jl:112
    ...

  Stacktrace:
    [1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1})
      @ Base .\number.jl:7
    [2] symconvert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1})
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\parameter_buffer.jl:2
    [3] ModelingToolkit.MTKParameters(sys::ODESystem, p::Dict{SymbolicUtils.BasicSymbolic{Real}, ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1}}, u0::Vector{Pair{Num, Float64}}; tofloat::Bool, use_union::Bool)       
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\parameter_buffer.jl:114
    [4] ModelingToolkit.MTKParameters(sys::ODESystem, p::Dict{SymbolicUtils.BasicSymbolic{Real}, ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1}}, u0::Vector{Pair{Num, Float64}})
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\parameter_buffer.jl:13
    [5] process_DEProblem(constructor::Type, sys::ODESystem, u0map::Vector{Pair{Num, Float64}}, parammap::Vector{Pair{Num, ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1}}}; 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, use_union::Bool, tofloat::Bool, symbolic_u0::Bool, u0_constructor::typeof(identity), guesses::Dict{Any, Any}, t::Float64, warn_initialize_determined::Bool, build_initializeprob::Bool, kwargs::@Kwargs{check_length::Bool})
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:942
    [6] process_DEProblem
      @ C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:834 [inlined]
    [7] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair{Num, Float64}}, tspan::Tuple{Float64, Float64}, parammap::Vector{Pair{Num, ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1}}}; callback::Nothing, check_length::Bool, warn_initialize_determined::Bool, kwargs::@Kwargs{})
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:1085
    [8] (ODEProblem{true, SciMLBase.AutoSpecialize})(sys::ODESystem, u0map::Vector{Pair{Num, Float64}}, tspan::Tuple{Float64, Float64}, parammap::Vector{Pair{Num, ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1}}})    
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:1075
    [9] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any}; kwargs::@Kwargs{})
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:1062
   [10] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any})
      @ ModelingToolkit C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:1061
   [11] #ODEProblem#755
      @ C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:1051 [inlined]
   [12] ODEProblem
      @ C:\Users\herma\.julia\packages\ModelingToolkit\kByuD\src\systems\diffeqs\abstractodesystem.jl:1050 [inlined]
   [13] (::var"#x_at_1#23"{var"#x_at_1#16#24"{ODESystem, Num}})(P::ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1}; use_remake::Bool)     
      @ Main C:\Users\herma\Dropbox\School\UIO\Research\boltzmann\bug.jl:17    
   [14] (::var"#22#30")(P::ForwardDiff.Dual{ForwardDiff.Tag{var"#22#30", Float64}, Float64, 1})
      @ Main C:\Users\herma\Dropbox\School\UIO\Research\boltzmann\bug.jl:23    
   [15] derivative
      @ C:\Users\herma\.julia\packages\ForwardDiff\PcZ48\src\derivative.jl:14 [inlined]
    ...

Could it be unified to work in both ways?

I'm on a fresh updated master branch with ] status

  [0c46a032] DifferentialEquations v7.13.0
  [f6369f11] ForwardDiff v0.10.36
  [961ee093] ModelingToolkit v9.12.1 `https://github.com/SciML/ModelingToolkit.jl.git#master`
  [1dea7af3] OrdinaryDiffEq v6.74.1

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