Skip to content

Package-dependent precompilation problem on master #28356

Closed
@ChrisRackauckas

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

bugIndicates an unexpected problem or unintended behaviorcompiler:precompilationPrecompilation of modules

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions