Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is remakeing an ODEProblem with a symbolic map of u0 or p type-stable? #2652

Closed
jonathanfischer97 opened this issue Apr 16, 2024 · 5 comments
Labels
question Further information is requested

Comments

@jonathanfischer97
Copy link

I have an ODEProblem that is initialized with the types of both u0 and p as Vector{Float64}.

When I remake with the same types, the output of @code_warntype seems to indicate the compiler knows the type of the returned ODEProblem:

>julia @code_warntype remake(odeproblem, u0 = zeros(12))


MethodInstance for Core.kwcall(::@NamedTuple{u0::Vector{Float64}}, ::typeof(remake), ::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem})
  from kwcall(::NamedTuple, ::typeof(remake), prob::ODEProblem) @ SciMLBase ~/.julia/dev/SciMLBase/src/remake.jl:83
Arguments
  _::Core.Const(Core.kwcall)
  @_2::@NamedTuple{u0::Vector{Float64}}
  @_3::Core.Const(SciMLBase.remake)
  prob::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem}
Locals
  f::Union{}
  u0::Union{}
  tspan::Union{}
  p::Union{}
  kwargs::Union{}
  interpret_symbolicmap::Union{}
  use_defaults::Union{}
  _kwargs...::Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}
  @_13::Union{Missing, Bool, Vector{Float64}}
Body::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem}
1 ──       Core.NewvarNode(:(f))
│          Core.NewvarNode(:(u0))
│          Core.NewvarNode(:(tspan))
│          Core.NewvarNode(:(p))
│          Core.NewvarNode(:(kwargs))
│          Core.NewvarNode(:(interpret_symbolicmap))
│          Core.NewvarNode(:(use_defaults))
│          Core.NewvarNode(:(_kwargs...))
│          Core.NewvarNode(:(@_13))
│    %10 = Core.isdefined(@_2, :f)::Core.Const(false)
└───       goto #3 if not %10
2 ──       Core.Const(:(@_13 = Core.getfield(@_2, :f)))
└───       Core.Const(:(goto %15))
3 ┄─       (@_13 = SciMLBase.missing)
│    %15 = @_13::Core.Const(missing)
│    %16 = Core.isdefined(@_2, :u0)::Core.Const(true)
└───       goto #5 if not %16
4 ──       (@_13 = Core.getfield(@_2, :u0))
└───       goto #6
5 ──       Core.Const(:(@_13 = SciMLBase.missing))
6 ┄─ %21 = @_13::Vector{Float64}%22 = Core.isdefined(@_2, :tspan)::Core.Const(false)
└───       goto #8 if not %22
7 ──       Core.Const(:(@_13 = Core.getfield(@_2, :tspan)))
└───       Core.Const(:(goto %27))
8 ┄─       (@_13 = SciMLBase.missing)
│    %27 = @_13::Core.Const(missing)
│    %28 = Core.isdefined(@_2, :p)::Core.Const(false)
└───       goto #10 if not %28
9 ──       Core.Const(:(@_13 = Core.getfield(@_2, :p)))
└───       Core.Const(:(goto %33))
10 ┄       (@_13 = SciMLBase.missing)
│    %33 = @_13::Core.Const(missing)
│    %34 = Core.isdefined(@_2, :kwargs)::Core.Const(false)
└───       goto #12 if not %34
11 ─       Core.Const(:(@_13 = Core.getfield(@_2, :kwargs)))
└───       Core.Const(:(goto %39))
12 ┄       (@_13 = SciMLBase.missing)
│    %39 = @_13::Core.Const(missing)
│    %40 = Core.isdefined(@_2, :interpret_symbolicmap)::Core.Const(false)
└───       goto #14 if not %40
13 ─       Core.Const(:(@_13 = Core.getfield(@_2, :interpret_symbolicmap)))
└───       Core.Const(:(goto %45))
14 ┄       (@_13 = true)
│    %45 = @_13::Core.Const(true)
│    %46 = Core.isdefined(@_2, :use_defaults)::Core.Const(false)
└───       goto #16 if not %46
15 ─       Core.Const(:(@_13 = Core.getfield(@_2, :use_defaults)))
└───       Core.Const(:(goto %51))
16 ┄       (@_13 = false)
│    %51 = @_13::Core.Const(false)
│    %52 = (:f, :u0, :tspan, :p, :kwargs, :interpret_symbolicmap, :use_defaults)::Core.Const((:f, :u0, :tspan, :p, :kwargs, :interpret_symbolicmap, :use_defaults))
│    %53 = Core.apply_type(Core.NamedTuple, %52)::Core.Const(NamedTuple{(:f, :u0, :tspan, :p, :kwargs, :interpret_symbolicmap, :use_defaults)})
│    %54 = Base.structdiff(@_2, %53)::Core.Const(NamedTuple())
│          (_kwargs... = Base.pairs(%54))
│    %56 = SciMLBase.:(var"#remake#645")(%15, %21, %27, %33, %39, %45, %51, _kwargs..., @_3, prob)::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem}
└───       return %56

However, when I take advantage of the symbolic indexing, it seems to be unable to infer that the returned ODEProblem will still have a uType of Vector{Float64}

  • Compared the previous output, the uType of the ODEProblem is where _A here, where previously the concrete type Vector{Float64} was inferred.
  • From my understanding of remakes internals, this should be inferrable, as the u0 symbolic map with type Vector{Pair{Symbol, Float64}} is intercepted and processed into the a Vector{Float64} internally before actual reconstruction of the ODEProblem
>julia @code_warntype remake(odeprob, u0 = [:A => 1.0])

MethodInstance for Core.kwcall(::@NamedTuple{u0::Vector{Pair{Symbol, Float64}}}, ::typeof(remake), ::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem})
  from kwcall(::NamedTuple, ::typeof(remake), prob::ODEProblem) @ SciMLBase ~/.julia/dev/SciMLBase/src/remake.jl:83
Arguments
  _::Core.Const(Core.kwcall)
  @_2::@NamedTuple{u0::Vector{Pair{Symbol, Float64}}}
  @_3::Core.Const(SciMLBase.remake)
  prob::ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem}
Locals
  f::Union{}
  u0::Union{}
  tspan::Union{}
  p::Union{}
  kwargs::Union{}
  interpret_symbolicmap::Union{}
  use_defaults::Union{}
  _kwargs...::Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}
  @_13::Union{Missing, Bool, Vector{Pair{Symbol, Float64}}}
Body::ODEProblem{_A, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem} where _A
1 ──       Core.NewvarNode(:(f))
│          Core.NewvarNode(:(u0))
│          Core.NewvarNode(:(tspan))
│          Core.NewvarNode(:(p))
│          Core.NewvarNode(:(kwargs))
│          Core.NewvarNode(:(interpret_symbolicmap))
│          Core.NewvarNode(:(use_defaults))
│          Core.NewvarNode(:(_kwargs...))
│          Core.NewvarNode(:(@_13))
│    %10 = Core.isdefined(@_2, :f)::Core.Const(false)
└───       goto #3 if not %10
2 ──       Core.Const(:(@_13 = Core.getfield(@_2, :f)))
└───       Core.Const(:(goto %15))
3 ┄─       (@_13 = SciMLBase.missing)
│    %15 = @_13::Core.Const(missing)
│    %16 = Core.isdefined(@_2, :u0)::Core.Const(true)
└───       goto #5 if not %16
4 ──       (@_13 = Core.getfield(@_2, :u0))
└───       goto #6
5 ──       Core.Const(:(@_13 = SciMLBase.missing))
6 ┄─ %21 = @_13::Vector{Pair{Symbol, Float64}}%22 = Core.isdefined(@_2, :tspan)::Core.Const(false)
└───       goto #8 if not %22
7 ──       Core.Const(:(@_13 = Core.getfield(@_2, :tspan)))
└───       Core.Const(:(goto %27))
8 ┄─       (@_13 = SciMLBase.missing)
│    %27 = @_13::Core.Const(missing)
│    %28 = Core.isdefined(@_2, :p)::Core.Const(false)
└───       goto #10 if not %28
9 ──       Core.Const(:(@_13 = Core.getfield(@_2, :p)))
└───       Core.Const(:(goto %33))
10 ┄       (@_13 = SciMLBase.missing)
│    %33 = @_13::Core.Const(missing)
│    %34 = Core.isdefined(@_2, :kwargs)::Core.Const(false)
└───       goto #12 if not %34
11 ─       Core.Const(:(@_13 = Core.getfield(@_2, :kwargs)))
└───       Core.Const(:(goto %39))
12 ┄       (@_13 = SciMLBase.missing)
│    %39 = @_13::Core.Const(missing)
│    %40 = Core.isdefined(@_2, :interpret_symbolicmap)::Core.Const(false)
└───       goto #14 if not %40
13 ─       Core.Const(:(@_13 = Core.getfield(@_2, :interpret_symbolicmap)))
└───       Core.Const(:(goto %45))
14 ┄       (@_13 = true)
│    %45 = @_13::Core.Const(true)
│    %46 = Core.isdefined(@_2, :use_defaults)::Core.Const(false)
└───       goto #16 if not %46
15 ─       Core.Const(:(@_13 = Core.getfield(@_2, :use_defaults)))
└───       Core.Const(:(goto %51))
16 ┄       (@_13 = false)
│    %51 = @_13::Core.Const(false)
│    %52 = (:f, :u0, :tspan, :p, :kwargs, :interpret_symbolicmap, :use_defaults)::Core.Const((:f, :u0, :tspan, :p, :kwargs, :interpret_symbolicmap, :use_defaults))
│    %53 = Core.apply_type(Core.NamedTuple, %52)::Core.Const(NamedTuple{(:f, :u0, :tspan, :p, :kwargs, :interpret_symbolicmap, :use_defaults)})
│    %54 = Base.structdiff(@_2, %53)::Core.Const(NamedTuple())
│          (_kwargs... = Base.pairs(%54))
│    %56 = SciMLBase.:(var"#remake#645")(%15, %21, %27, %33, %39, %45, %51, _kwargs..., @_3, prob)::ODEProblem{_A, Tuple{Float64, Float64}, true, Vector{Float64}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#k#503"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x295d7af7, 0x6bfba1bb, 0xa3f18ec4, 0xf5e4f686, 0x67200657), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x3d5d5488, 0xd96e28b2, 0x7ac546e4, 0x33e69fc7, 0x7b6eed4b), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#___jac#509"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xdd49eba6, 0xcfd486f5, 0xb9c76f03, 0x8f02bafd, 0xc80c2536), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x2e052f62, 0xcdd690bb, 0x7123df94, 0x6803aacb, 0x1ea8e979), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#678#generated_observed#513"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}, Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol, Symbol}, @NamedTuple{maxiters::Float64, verbose::Bool, saveat::Float64}}, SciMLBase.StandardODEProblem} where _A
└───       return %56

Am I missing anything or is this a known issue?

I discovered this when profiling my optimization code and seeing a large fraction of runtime dispatches surrounding my objective function, which calls remake with a symbolic map.

@jonathanfischer97 jonathanfischer97 added the question Further information is requested label Apr 16, 2024
@ChrisRackauckas
Copy link
Member

No, no symbolic map will be. That's just not possible. But setu and setp functions generate inferred things because it performs the symbolic parts in advance. remake is preserved as simple and high level

@jonathanfischer97
Copy link
Author

Thanks for answer Chris.

Could I ask as well if remake with symbolic maps are meant to be used in tight loops, like an optimization objective function?

Or would that call for a more performant but bespoke implementation?

More generally, is symbolic indexing in ModelingToolkit/SciMl intended for internal code and performance, or just for interactivity/flexibility (i.e plotting different ODESolution vars)?

@SebastianM-C
Copy link
Contributor

See https://docs.sciml.ai/ModelingToolkit/stable/examples/remake/ and specifically https://docs.sciml.ai/ModelingToolkit/stable/examples/remake/#Re-creating-the-problem for ways in which updating parameters can be done in a tight loop.

There are also some type stability improvements in #2613

@jonathanfischer97
Copy link
Author

Thanks for the pointers @SebastianM-C , I hadn't seen these docs before.

Final question: what is the idiomatic/performant way to access observed variables from an ODESolution?

In my loss function, I extract sol[:A] (where :A is an observed quantity), but have noticed that the return type of this indexing isn't inferred.

@SebastianM-C
Copy link
Contributor

I'd recommend checking out SymbolicIndexingInterface.jl for that. You'd want to save getsyms=getu(prob, syms) outside of the loop and then use the function that it gives you inside (i.e. getsyms(sol)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants