Skip to content

Raise OrdinaryDiffEqCore floor to 4.11 for the lorenz_pref precompile workloads - #4080

Merged
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix-core-floor-lorenz-pref
Jul 30, 2026
Merged

Raise OrdinaryDiffEqCore floor to 4.11 for the lorenz_pref precompile workloads#4080
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix-core-floor-lorenz-pref

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

Please ignore until reviewed by @ChrisRackauckas.

Fixes #4079.

What broke

#4005 added a non-isbits AutoDePSpecialize precompile workload built on OrdinaryDiffEqCore.lorenz_pref / lorenz_pref_params, and wired it into the @compile_workload block of eight sublibraries — BDF, Default, LowStorageRK, Rosenbrock, SDIRK, SSPRK, Tsit5, Verner — without raising any of their OrdinaryDiffEqCore compat floors.

That commit bumped Core 4.10.0 -> 4.10.1, but 4.10.1 was never registered: General goes 4.10.0 -> 4.11.0. So the first released Core carrying lorenz_pref is 4.11.0, while the sublibraries went out declaring OrdinaryDiffEqCore = "4.10" (Tsit5, Verner, SSPRK, Rosenbrock, LowStorageRK) or "4.8" / "4.8.1" (BDF, SDIRK, Default).

Any environment that holds Core at 4.10.0 therefore resolves a combination that fails to precompile:

ERROR: LoadError: UndefVarError: `lorenz_pref` not defined in `OrdinaryDiffEqCore`

This is the same class as #2600 and #4078 — a Core symbol referenced from a precompile workload with a floor that predates the symbol.

Verification

Reproduced and confirmed locally (Julia 1.12.4), not inferred:

$ julia --project -e 'using Pkg
    Pkg.add(name="OrdinaryDiffEqTsit5", version="2.1.1")
    Pkg.add(name="OrdinaryDiffEqCore", version="4.10.0")'
$ julia --project -e 'using OrdinaryDiffEqTsit5'
ERROR: LoadError: UndefVarError: `lorenz_pref` not defined in `OrdinaryDiffEqCore`

Same Tsit5 with Core 4.11.0:

$ julia --project -e 'using OrdinaryDiffEqTsit5
    prob = ODEProblem((u,p,t)->1.01u, 1/2, (0.0,1.0))
    println(solve(prob, Tsit5()).u[end])'
1.3728004409033048

And with this branch's Tsit5 (OrdinaryDiffEqCore = "4.11") dev'd into an environment already holding Core 4.10.0, Pkg upgrades Core rather than resolving the broken pair:

  [bbf590c4] ↑ OrdinaryDiffEqCore v4.10.0 ⇒ v4.11.0
  [b1df2697] + OrdinaryDiffEqTsit5 v2.1.2
solve ok: 1.3728004409033048

Audit

Rather than patch only Tsit5, I checked out the registered Core trees for every 4.x release (4.0.0 through 4.11.0, mapped from General's git-tree-sha1 back to monorepo commits) and cross-referenced every qualified OrdinaryDiffEqCore.<name> access and every using/import OrdinaryDiffEqCore: ... name in all 50 sublibraries against its declared floor:

sublibrary old floor missing at floor first released in
BDF 4.8 AutoDePSpecialize, lorenz_p, lorenz_p_params 4.8.1
BDF 4.8 lorenz_pref, lorenz_pref_params 4.11.0
Default 4.8.1 lorenz_pref, lorenz_pref_params 4.11.0
LowStorageRK 4.10 lorenz_pref, lorenz_pref_params 4.11.0
Rosenbrock 4.10 lorenz_pref, lorenz_pref_params 4.11.0
SDIRK 4.8 AutoDePSpecialize, lorenz_p, lorenz_p_params 4.8.1
SDIRK 4.8 lorenz_pref, lorenz_pref_params 4.11.0
SSPRK 4.10 lorenz_pref, lorenz_pref_params 4.11.0
Tsit5 4.10 lorenz_pref, lorenz_pref_params 4.11.0
Verner 4.10 lorenz_pref, lorenz_pref_params 4.11.0

No other sublibrary references a Core name that is absent at its declared floor. All ten rows collapse to the same fix: floor 4.11.

Changes

OrdinaryDiffEqCore = "4.11" in all eight, plus a patch bump for the four whose current in-tree version is already registered:

  • Rosenbrock 2.6.1 → 2.6.2
  • SSPRK 2.2.1 → 2.2.2
  • Tsit5 2.1.1 → 2.1.2
  • Verner 2.2.1 → 2.2.2

BDF 2.4.1, SDIRK 2.8.2, Default 2.4.2 and LowStorageRK 3.2.2 are not yet registered, so their floors are corrected in place.

Metadata-only; the source in this repo is already correct.

Two follow-ups, not done here

  1. The already-registered broken versions stay broken. Tsit5 2.1.1, Verner 2.2.1, SSPRK 2.2.1 and Rosenbrock 2.6.1 are in General declaring "4.10". An environment pinned to Core 4.10.0 (the Colab case in OrdinaryDiffEqTsit5 v2.1.1 does not work with OrdinaryDiffEqCore v4.10.0 #4079) can still resolve back to them. The complete fix is a retroactive Compat.toml amendment in JuliaRegistries/General raising those four entries to 4.11. I have not opened that — General is outside the repos I act on without asking. Say the word and I'll prepare it.

  2. Nothing in CI catches this class. DowngradeSublibraries.yml lists OrdinaryDiffEqCore in its skip set, and it has to: every sublibrary's [sources] points OrdinaryDiffEqCore at ../OrdinaryDiffEqCore, so the in-tree Core is always what gets loaded and the declared floor is never exercised. Three occurrences now (OrdinaryDiffEqSymplecticRK v1.2.0 does not work with OrdinaryDiffEqCore v1.6.0 #2600, Release DelayDiffEq 6.1.1 and OrdinaryDiffEqDefault 2.4.2 with correct OrdinaryDiffEqCore floors #4078, OrdinaryDiffEqTsit5 v2.1.1 does not work with OrdinaryDiffEqCore v4.10.0 #4079). A job that, per sublibrary, resolves OrdinaryDiffEqCore at its declared floor from the registry and does nothing but using would have caught all three at PR time. Happy to write it as a separate PR.


Unrelated observation while testing: Pkg.instantiate() on any sublibrary currently fails on master, before this branch. In-tree Core requires SciMLBase = "3.40", but the newest registered NonlinearSolveBase (2.38.0) caps at SciMLBase = "3.37.0 - 3.39". General already carries a ["2.38.1 - 2"] SciMLBase = "3.37.0 - 3" entry, so this clears once NonlinearSolveBase 2.38.1 is registered. Pure ecosystem lag, nothing to do with this change — but it does mean I could not run the in-tree sublibrary test suites for this branch.

🤖 Generated with Claude Code

https://claude.ai/code/session_017ZqxphdTA1MydR1WXye9Jc

… workloads

SciML#4005 added a non-isbits precompile workload built on
OrdinaryDiffEqCore.lorenz_pref / lorenz_pref_params, and referenced it from
eight sublibraries' @compile_workload blocks without raising their
OrdinaryDiffEqCore floors. It bumped Core to 4.10.1, but 4.10.1 was never
registered — the next registered Core after 4.10.0 is 4.11.0 — so the first
released Core containing the symbols is 4.11.0.

Tsit5 2.1.1, Verner 2.2.1, SSPRK 2.2.1 and Rosenbrock 2.6.1 are all registered
declaring OrdinaryDiffEqCore = "4.10", so any environment holding Core at 4.10.0
resolves a combination that fails to precompile with

  UndefVarError: `lorenz_pref` not defined in `OrdinaryDiffEqCore`

Reproduced locally with OrdinaryDiffEqTsit5 2.1.1 + OrdinaryDiffEqCore 4.10.0;
the same pair with Core 4.11.0 precompiles and solves.

Audited every sublibrary's qualified OrdinaryDiffEqCore accesses and explicit
import lists against the registered Core trees for 4.0.0 - 4.11.0. Exactly
these eight are affected. BDF and SDIRK were additionally below the floor for
AutoDePSpecialize / lorenz_p / lorenz_p_params (first released in 4.8.1) under
their "4.8" bound; that is subsumed by 4.11. No other sublibrary references a
Core name absent at its declared floor.

Metadata-only; the source in this repo is already correct.

Fixes SciML#4079

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZqxphdTA1MydR1WXye9Jc
@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review July 30, 2026 13:26
@ChrisRackauckas
ChrisRackauckas merged commit 2111422 into SciML:master Jul 30, 2026
84 of 170 checks passed
ChrisRackauckas added a commit to JuliaRegistries/General that referenced this pull request Aug 1, 2026
…y versions (#162878)

Fix OrdinaryDiffEqCore floor for five OrdinaryDiffEq sublibrary releases

Tsit5 2.1.1, Verner 2.2.1, SSPRK 2.2.1, Rosenbrock 2.6.1 and Default 2.4.1 each
carry a PrecompileTools workload that references OrdinaryDiffEqCore.lorenz_pref
and lorenz_pref_params. Those names first exist in OrdinaryDiffEqCore 4.11.0,
but the five versions were registered allowing 4.10.0 (4.8.0 for Default), so
any environment holding OrdinaryDiffEqCore below 4.11.0 resolves a combination
that cannot precompile:

  ERROR: LoadError: UndefVarError: `lorenz_pref` not defined in `OrdinaryDiffEqCore`

Upstream fixed the floor going forward in SciML/OrdinaryDiffEq.jl#4080, and the
successor releases (Tsit5 2.1.2, Verner 2.2.2, SSPRK 2.2.2, Rosenbrock 2.6.2,
Default 2.4.2) are already registered with OrdinaryDiffEqCore = "4.11.0 - 4".
That does not help an environment pinned to OrdinaryDiffEqCore 4.10.0, which
still resolves back to the older, broken entries — so the bound needs correcting
retroactively as well.

Raises OrdinaryDiffEqCore to "4.11.0 - 4" for exactly those five versions. Each
is a single-version key already, so this is a one-line change per package.

Verified against a local copy of the registry carrying this patch: an
environment holding OrdinaryDiffEqCore 4.10.0 now resolves OrdinaryDiffEqTsit5
2.1.0 (which predates the workload) and precompiles and solves, instead of
selecting the broken 2.1.1; an unconstrained environment resolves 2.1.2 with
OrdinaryDiffEqCore 4.11.0 as before. Confirmed the edited files are semantically
identical to a full RegistryTools.Compress round-trip apart from the intended
bounds.

Not affected, and deliberately left alone: BDF 2.4.0, SDIRK 2.8.1 and
LowStorageRK 3.2.1 do not contain the workload.

Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OrdinaryDiffEqTsit5 v2.1.1 does not work with OrdinaryDiffEqCore v4.10.0

2 participants