-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
Summary
While working on #59215 and SciML/NonlinearSolve.jl#665 one issue keeps reoccurring:
MethodError(f=Base.Enums.namemap, args=(SciMLBase.ReturnCode.T,), world=0x0000000000009661)
In #59215 this already came up (and similarly at JuliaCon) once we moved the init
call from compile time to runtime (using OncePerProcess
), and now I have taken some time to get to the bottom of it.
I believe there is some issue with [EnumX.jl](https://github.com/fredrikekre/EnumX.jl)
and its interplay with trimming (note that ReturnCode
is based on EnumX.jl).
I have tried to isolate a minimum failing example, peeling away layers of indirection from init
and moving it as much as possible to compile time _prob
and _alg
). At this point, NonlinearSolve is mostly just setting up caches, and I don't think it should be messing with any enums or world ages still, leading me to believe there may be a bug in the juliac
implementation that's triggered here.
module TrimSimpleNonlinearSolve
using NonlinearSolveFirstOrder
using ADTypes: AutoForwardDiff
using LinearSolve: CholeskyFactorization
function f(u, p)
return (u .- p.λ) .^ 2
end
struct MyParams{T}
λ::T
end
const autodiff = AutoForwardDiff(; chunksize=1)
const alg = LevenbergMarquardt(; autodiff, linsolve=CholeskyFactorization())
const prob = NonlinearLeastSquaresProblem{false}(f, rand(2), MyParams(rand()))
const _prob = NonlinearSolveFirstOrder.DiffEqBase.get_concrete_problem(prob, false; u0=prob.u0, p=prob.p)
const _alg = NonlinearSolveFirstOrder.DiffEqBase.prepare_alg(alg, _prob.u0, _prob.p, _prob)
function minimize(x)
# inlined and simplified version of
# ````
# cache = init(prob, alg; p=MyParams(x))
# ````
# this takes us here: https://github.com/SciML/NonlinearSolve.jl/blob/b37b31b22a6650c773a4fdef8ca220f4e8815051/lib/NonlinearSolveFirstOrder/src/solve.jl#L123-L129
cache = NonlinearSolveFirstOrder.DiffEqBase.__init(_prob, _alg)
solve!(cache)
return cache.u
end
end # module TrimSimpleNonlinearSolve
with main.jl
using TrimSimpleNonlinearSolve
function @main(argv::Vector{String})::Cint
λ = try # currently calling from `julia` and as binary yields different `argv`...
parse(Float64, argv[1])
catch
parse(Float64, argv[2])
end
sol = TrimSimpleNonlinearSolve.minimize(λ)
println(Core.stdout, sum(sol))
return 0
end
This code runs just fine from the repl, and also works when we move the entire cache
statement to const
. However, like this it fails during trimming.
How to reproduce
git clone [email protected]:RomeoV/TrimSimpleNonlinearSolve.jl.git
cd TrimSimpleNonlinearSolve.jl
git checkout 160299f064c630402fc64d6fd96c4e9ab177a11e
juliaup override set 1.12
make
Other things I have tried
Since it seems just the methoderror is missing, I have tried to explicitly run stuff like Base.Enums.namemap(ReturnCode.T)
on the trimming path. However it doesn't seem to help. I am also wondering if perhaps the enum is evaluated in the wrong world age and therefore the method is not available anymore... however, I don't know how to debug this.
Closing this should enable closing #59215 and maybe SciML/NonlinearSolve.jl#665.