Description
Take this seemingly fine piece of code:
using InteractiveUtils
using OrdinaryDiffEq, StaticArrays
using DiffEqBase: __init
function loop(u, p, t)
σ = p[1]; ρ = p[2]; β = p[3]
du1 = σ*(u[2]-u[1])
du2 = u[1]*(ρ-u[3]) - u[2]
du3 = u[1]*u[2] - β*u[3]
return SVector{3}(du1, du2, du3)
end
struct DS{IIP, F, U, P}
f::F
u0::U
p::P
t0::eltype(U)
end
DS{IIP}(f,u0,p) where {IIP} =
DS{IIP, typeof(f), typeof(u0), typeof(p)}(f, u0, p, 0.0)
const DEFAULT_SOLVER = Vern9()
const DEFAULT_DIFFEQ_KWARGS = (abstol = 1e-9,
reltol = 1e-9, maxiters = typemax(Int))
_get_solver(a) = haskey(a, :alg) ? a[:alg] : DEFAULT_SOLVER
function integrator(ds::DS{iip}, u0 = ds.u0;
tfinal = Inf, diffeq...) where {iip}
u = u0
prob = ODEProblem{iip}(ds.f, u, (ds.t0, typeof(ds.t0)(tfinal)), ds.p)
(haskey(diffeq, :saveat) && tfinal == Inf) && error("Infinite solving!")
solver = _get_solver(diffeq)
integ = __init(prob, solver; DEFAULT_DIFFEQ_KWARGS...,
save_everystep = false, diffeq...)
return integ
end
u0 = rand(SVector{3})
ds = DS{false}(loop, u0, rand(3))
@show @which OrdinaryDiffEq.Vern9ConstantCache(Float64,Float64)
@show tinteg = integrator(ds, dt = 0.1)
Run it on OrdinaryDiffEq.jl branch precomment: https://github.com/JuliaDiffEq/OrdinaryDiffEq.jl/tree/precomment . This branch comments right up to the point of the problem, and at the function line that is a problem it replaces it with @which
:
https://github.com/JuliaDiffEq/OrdinaryDiffEq.jl/blob/precomment/src/solve.jl#L229
From there you get:
#= D:\OneDrive\Computer\Desktop\test.jl:76 =# @which(OrdinaryDiffEq.Vern9ConstantCache(Float64, Floa
t64)) = (::Type{OrdinaryDiffEq.Vern9ConstantCache})(::Type{T}, ::Type{T2}) where {T<:Union{Float32,
Float64}, T2<:Union{Float32, Float64}} in OrdinaryDiffEq at C:\Users\Chris\.julia\dev\OrdinaryDiffEq
\src\tableaus\verner_tableaus.jl:2400
(real(uBottomEltypeNoUnits), real(tTypeNoUnits)) = (Float64, Float64)
tinteg = integrator(ds, dt=0.1) = (::Type{OrdinaryDiffEq.Vern9ConstantCache})(::Type{T}, ::Type{T2})
where {T<:Union{Float32, Float64}, T2<:Union{Float32, Float64}} in OrdinaryDiffEq at C:\Users\Chris
\.julia\dev\OrdinaryDiffEq\src\tableaus\verner_tableaus.jl:2400
So aha I have isolated what is causing the issue and can cause it directly from the REPL? No.
OrdinaryDiffEq.Vern9ConstantCache(Float64,Float64)
That works from the REPL. So now go to postcomment which is one commit down from precomment. Here's the diff:
SciML/OrdinaryDiffEq.jl@e9d6b3d
So instead of calling @which
on that line, we just call it from inside of the package. Can't be too bad, right? Wrong: it never stops compiling. I added a flush
so that way it shows that for sure nothing gets printed and thus it is never ending compilation.
Now this may be related to the bigfloat precompilation PR since the only related commit is SciML/OrdinaryDiffEq.jl@b13d4d5 between OrdinaryDiffEq v4.7.0 and v4.6.0, yet it works on v4.6.0 and not on v4.7.0. But to make matters more confusing, the dispatch that it's actually calling is line 2400 which is https://github.com/JuliaDiffEq/OrdinaryDiffEq.jl/blob/master/src/tableaus/verner_tableaus.jl#L2399 which was not a dispatch which was changed beyond the removal of Base.@pure
. I hit it with Base.@pure
again and it doesn't compile, so it seems that the code which is actually called is unchanged between these two versions of OrdinaryDiffEq.jl yet the version change causes a precompilation issue. Then on the branch postthenrevert I revert that bigfloat change commit which only effects unrelated dispatches (since now I've tested Base.@pure
with/without separately) and... reverting the commit fixes the issue.
SciML/OrdinaryDiffEq.jl@24a2548
So my guess is that somehow the bigfloat precompilation in a separate dispatch is causing an infinite loop in the correct dispatch but I cannot pretend to understand why. I wonder if @JeffBezanson 's e0cf3db had something to do with this (it was supposed to fix bigfloat precompilation?).
In the meantime OrdinaryDiffEq.jl can just revert the tableau change, but that's gotta be the weirdest bug I've "isolated".
Activity