-
-
Notifications
You must be signed in to change notification settings - Fork 230
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
Type-instability arising from initial condition #1023
Comments
I just encountered a similar problem, however for MWE:
Output of
Further info: packages:
|
The type-instability for your ODE is resolved if the function is declared function main()
du0 = [1.0]
u0 = [0.0]
tspan = (0.0,20.0)
prob = SecondOrderODEProblem{true}(fun!,du0,u0,tspan)
sol = solve(prob, Tsit5())
end With this change, all types are now fully inferred: julia> @code_warntype main()
MethodInstance for main()
from main() @ Main REPL[3]:1
Arguments
#self#::Core.Const(main)
Locals
sol::ODESolution{Float64, 2, Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}}, ODEProblem{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}, SecondOrderODEProblem{true}}, Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.InterpolationData{DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}}, Nothing, OrdinaryDiffEq.Tsit5Cache{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, Nothing}, SciMLBase.DEStats, Nothing}
prob::ODEProblem{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}, SecondOrderODEProblem{true}}
tspan::Tuple{Float64, Float64}
u0::Vector{Float64}
du0::Vector{Float64}
Body::ODESolution{Float64, 2, Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}}, ODEProblem{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}, SecondOrderODEProblem{true}}, Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.InterpolationData{DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}}, Nothing, OrdinaryDiffEq.Tsit5Cache{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, Nothing}, SciMLBase.DEStats, Nothing}
1 ─ (du0 = Base.vect(1.0))
│ (u0 = Base.vect(0.0))
│ (tspan = Core.tuple(0.0, 20.0))
│ %4 = Core.apply_type(Main.SecondOrderODEProblem, true)::Core.Const(SecondOrderODEProblem{true})
│ %5 = Main.fun!::Core.Const(fun!)
│ %6 = du0::Vector{Float64}
│ %7 = u0::Vector{Float64}
│ (prob = (%4)(%5, %6, %7, tspan::Core.Const((0.0, 20.0))))
│ %9 = prob::ODEProblem{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}, SecondOrderODEProblem{true}}
│ %10 = Main.Tsit5()::Core.Const(Tsit5(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, thread = static(false),))
│ %11 = Main.solve(%9, %10)::ODESolution{Float64, 2, Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}}, ODEProblem{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}, SecondOrderODEProblem{true}}, Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.InterpolationData{DynamicalODEFunction{true, SciMLBase.FullSpecialize, ODEFunction{true, SciMLBase.FullSpecialize, typeof(fun!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, ODEFunction{true, SciMLBase.FullSpecialize, SciMLBase.var"#313#315", LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}}, Nothing, OrdinaryDiffEq.Tsit5Cache{ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, Nothing}, SciMLBase.DEStats, Nothing}
│ (sol = %11)
└── return %11 |
Ah thank you, I am sorry to have highjacked your issue. I really thought it's a similar problem. |
I have found a way to remove the type-instability. If I change the initial condition passed to prob2 = ODEProblem{false}(perturbation, 2.0, rspan, (n, K, sol1)) then the types are fully inferred. In retrospect, this should have been obvious. I was passing an However, I am surprised that Julia's compiler was unable to infer from the ODE and the other arguments that the initial condition needed to be promoted to a |
It should be possible. It is odd that promote_type just gives up here. |
Edit
The initial post is out of date. I initially thought that the type-instability came from the
ODESolution
being passed as an argument to another ODE. This was wrong.The type-instability actually came from the type of the initial condition. The initial condition was an
Int64
when it needed to be aFloat64
. This is still somewhat surprising, since I would expect Julia's compiler to know to promote the type of the initial condition based on the ODE.Describe the bug 🐞
Solving an ODE when passing an
ODESolution
as a parameter is type-unstable.Expected behavior
Julia's compiler should be able to fully infer the type of the final
ODESolution
.Minimal Reproducible Example 👇
The type-instability arises when an
ODESolution
is passed to an ODE as a parameterparam
. Here I include a minimal example of where I first came into contact with this behaviour.I first solve an ODE
structure!
and then pass itsODESolution
to another ODEperturbation
. All the types are fully inferred, except for the second solutionsol2
.Error & Stacktrace⚠️
When I examine the types, I find
Note that all the types are inferred correctly, until
sol2
, which isAny
.Environment (please complete the following information):
using Pkg; Pkg.status()
using Pkg; Pkg.status(; mode = PKGMODE_MANIFEST)
versioninfo()
Additional context
Although in my example, I use
sol1
to interpolate inperturbation
, I have verified that this is not the source of the instability. I can changeperturbation
toand the type-instability persists.
Also, in putting together my minimal example, I tried the following (simpler) code:
However, in this case, type-inference fails at
sol1
, whereas my above example fails atsol2
.Output:
The text was updated successfully, but these errors were encountered: