Skip to content

Raise ModelingToolkit downgrade floors#495

Merged
ChrisRackauckas merged 1 commit into
SciML:mainfrom
ChrisRackauckas-Claude:agent/raise-mtksl-minimums
Jul 21, 2026
Merged

Raise ModelingToolkit downgrade floors#495
ChrisRackauckas merged 1 commit into
SciML:mainfrom
ChrisRackauckas-Claude:agent/raise-mtksl-minimums

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

This PR should be ignored until reviewed by @ChrisRackauckas.

Summary

  • Raise the ModelingToolkit compatibility floor from 11 to 11.28.
  • Raise the ModelingToolkitBase compatibility floor from 1.1 to 1.49.

These are two independent downgrade boundaries. The Base floor prevents an incompatible ImplicitDiscreteSolve/OrdinaryDiffEqCore graph from loading; the ModelingToolkit floor includes the alias-elimination correction needed by the isothermal actuator model.

Root cause

With ModelingToolkitBase below 1.49, the downgrade graph can select ImplicitDiscreteSolve 2.1.1 with OrdinaryDiffEqCore 4.3. ImplicitDiscreteSolve then instantiates the two-parameter form of CommonControllerOptions against the older one-parameter definition, and package loading fails with too many parameters for type.

ModelingToolkitBase 1.49 is the first release whose compatibility requires ImplicitDiscreteSolve 2.1.2 on its 2.x line. That release in turn requires a compatible OrdinaryDiffEqCore version. This is the dependency correction from ModelingToolkit.jl #4677.

After correcting that graph, ModelingToolkit 11.27 still fails three unchanged isothermal actuator assertions: the first acceleration and maximum acceleration are NaN, and the terminal piston displacement remains zero. ModelingToolkit 11.28 is the first passing release. It contains the perfect-alias elimination rerun from ModelingToolkit.jl #4640, which handles equations exposed by the earlier alias-elimination pass before Pantelides differentiation.

Boundary verification

Julia 1.10.11:

  • ModelingToolkitBase 1.48.0 reproduces the CommonControllerOptions load failure on its exact downgrade graph.
  • ModelingToolkitBase 1.49.0 loads with ImplicitDiscreteSolve 2.1.2 and OrdinaryDiffEqCore 4.5.0.
  • ModelingToolkit 11.27.0 / ModelingToolkitBase 1.49.0: the unchanged isothermal file reports 24 passes and 3 actuator failures.
  • ModelingToolkit 11.28.0 / ModelingToolkitBase 1.49.0: the unchanged isothermal file passes 27/27.
  • On that same pinned 11.28.0/1.49.0 core graph, the full unchanged analog file passes 100/100, including Diode 2/2 and HeatingDiode 5/5.
  • The full 437-line analysis-point test file completes all 60 @test/@test_logs sites on the same pinned core graph.
  • Clean current main passes the isothermal file 27/27, confirming that the actuator failure is specific to the old ModelingToolkit floor.

The pinned graph kept ModelingToolkit 11.28.0, ModelingToolkitBase 1.49.0, ModelingToolkitTearing 1.18.3, OrdinaryDiffEq 7.0.0, OrdinaryDiffEqCore 4.5.0, OrdinaryDiffEqDifferentiation 3.2.0, OrdinaryDiffEqNonlinearSolve 2.0.0, OrdinaryDiffEqRosenbrock 2.0.0, SciMLBase 3.18.0, DiffEqBase 7.2.0, LinearSolve 3.87.0, NonlinearSolve 4.19.1, SciCompDSL 1.0.0, SymbolicUtils 4.38.1, and Symbolics 7.24.0.

Deployed downgrade workflow verification

Using julia-downgrade-compat v2.6.1 at fab1defb76df9fd672f63c94df73ce131d32e134 in dependency mode:

  • The resolver completed successfully and wrote ModelingToolkit 11.28.0 and ModelingToolkitBase 1.49.0 to the package manifest.
  • Pkg.instantiate() and Pkg.build() completed successfully from that generated manifest.
  • The official GROUP=Core target selected ModelingToolkit 11.30.0 while retaining ModelingToolkitBase 1.49.0. It passed 566 assertions with 3 existing broken tests through thermal.jl, then stopped at the same clean-main AccelerationSensor structural-singularity error tracked by Initialize translational acceleration sensor test #489.
  • Runic's repository check passed.
  • TOML floor assertions and git diff --check passed.

No assertion was loosened, skipped, disabled, or changed. The existing actuator, analog, and analysis-point tests directly exercise both corrected boundaries.

Process log

  1. Reproduced the original downgrade load failure and isolated the ModelingToolkitBase 1.49 dependency boundary.
  2. Initially tested that Base-only correction on the full Core group; it exposed the later isothermal actuator failure rather than resolving the lane.
  3. Reproduced the actuator failure at ModelingToolkit 11.27 and the pass at 11.28 on otherwise pinned graphs.
  4. Matched the release boundary to ModelingToolkit.jl#4640 and independently checked the same file on clean current main.
  5. Reran the deployed resolver, package build, unchanged focused regressions, Runic, and metadata checks with both final floors.

The one remaining Core error is the clean-main AccelerationSensor fixture tracked and fixed separately by #489; it is independent of this compatibility-only patch.

Require the first ModelingToolkit and ModelingToolkitBase releases that satisfy the package downgrade graph and actuator tests.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Validation scratchpad for 1bab85cc:

  1. The deployed v2.6.1 dependency-mode resolver exited 0 and wrote ModelingToolkit 11.28.0, ModelingToolkitBase 1.49.0, ImplicitDiscreteSolve 2.1.2, OrdinaryDiffEq 7.0.0, and OrdinaryDiffEqCore 4.5.0.
  2. Pkg.instantiate() plus Pkg.build() exited 0 from that generated manifest.
  3. Boundary pair on otherwise pinned graphs:
    • ModelingToolkit 11.27.0 / ModelingToolkitBase 1.49.0: unchanged isothermal actuator test fails 3/9 (NaN, NaN, and zero terminal displacement).
    • ModelingToolkit 11.28.0 / ModelingToolkitBase 1.49.0: unchanged isothermal file passes 27/27.
  4. The same exact 11.28.0/1.49.0 core graph passes the full unchanged analog file 100/100 and all 60 analysis-point assertions. Clean current main also passes isothermal 27/27.
  5. The official GROUP=Core test target selected ModelingToolkit 11.30.0 with ModelingToolkitBase 1.49.0. It passed 566 assertions with 3 existing broken tests through thermal.jl, then reproduced clean main's known AccelerationSensor structural-singularity error (mass₊v(t)) tracked by Initialize translational acceleration sensor test #489.
  6. Repository-wide Runic, TOML floor assertions, and git diff --check all exited 0.

No test, tolerance, warning policy, or assertion was changed. The commit contains only the two compatibility-floor edits and the required co-author trailer.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Hosted CI classification for 1bab85cc:

All four jobs reach the unchanged AccelerationSensor test at test/translational.jl:235 and fail with the same InvalidSystemException: The system is structurally singular!; each reports 15 passes and one error for the final testset. This is the same failure reproduced locally on clean main and tracked by #489. It is not specific to the downgraded dependency graph.

The PR-specific checks remain green: Runic, QA, documentation, formatting, and spelling. The corrected downgrade graph also completed resolution/build and reached the clean-base-only test error, so no new downgrade-specific failure is present.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Clean-main downstream audit (PR source was not modified):

The hosted UndefVarError: ArnoldiMethodJL not defined in LinearSolve is a cross-environment loaded-module mismatch, not evidence of an MTSL source regression.

Exact boundary reproduction on Julia 1.12.6:

  • load LinearSolve 3.87.0, then re-resolve a dependent consumer against LinearSolve 4.2.1: passes;
  • load LinearSolve 3.87.0, then re-resolve the same consumer against LinearSolve 4.3.0: fails with the hosted LinearSolveArnoldiMethodExt.jl:8 stack.

LinearSolve 4.3.0 introduced the Arnoldi extension (571d0a868c490e420f3c48f469b1589adb72d746); the General registry commit that made 4.3.0 resolvable was b1af3c5fd32c0f394e5db1858b892763acbc1acb (2026-07-11). The MTK test sandbox held loaded LinearSolve 3.87.0 while its downstream environment resolved LinearSolve 4.3.0 + ArnoldiMethod 0.4.0, so new extension source referenced a binding absent from the old module.

Splitting dependency mutation and Pkg.test() into separate workflow steps is not sufficient: a fresh standalone Downstream run was green at 31/31 only because it silently selected registered MTSL v2.29.4 instead of the path-developed clean-main checkout.

The focused fix is in SciML/SciMLTesting.jl#23, with the stacked MTK opt-in in SciML/ModelingToolkit.jl#4749. Isolated children now retain path-developed outer-sandbox packages while respecting group-local [sources] overrides.

Real-graph validation developed this clean-main MTSL checkout, patched SciMLTesting, and MTK #4749 by path, then exercised the production GROUP=All -> isolated Downstream child route. The child resolver explicitly retained all path sources, resolved LinearSolve 4.3.0 + ArnoldiMethod 0.4.0, successfully precompiled the formerly failing Arnoldi extension, and completed:

Downstream | 31 pass / 31 total | 6m51.5s
Testing ModelingToolkit tests passed

The full unmodified split-process GROUP=All replay is still running through the pre-Downstream groups; I will post its terminal result separately rather than infer it from code inspection.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Terminal follow-up for the unmodified clean-main replay promised above.

I kept dependency setup and the actual test run in separate Julia processes, then ran ModelingToolkit clean main at 3704e7ec6e75a67c9e20121483c9122c4b2699a1 with a fresh depot:

JULIA_NUM_THREADS=2 GROUP=All julia +1.12 --project=. \
  -e 'using Pkg; Pkg.test(; coverage=false)'

The run reached the following terminal results before exiting 1:

  • InterfaceI: 1,477 passed, 3 broken
  • Initialization: 798 passed, 12 broken
  • InterfaceII: 946 passed, 7 broken
  • SymbolicIndexingInterface: 1,964/1,964 passed
  • Downstream: 3/3 testsets errored in 2m29.5s

The downstream manifest resolved LinearSolve 4.3.0. As soon as Downstream precompiled its dependencies, it reported LinearSolve -> LinearSolveArnoldiMethodExt as failed and then reproduced the hosted exception exactly:

UndefVarError: `ArnoldiMethodJL` not defined in `LinearSolve`
.../LinearSolve/ext/LinearSolveArnoldiMethodExt.jl:8

ModelingToolkitStandardLibrary and ControlSystemsMTK consequently failed to precompile, and Julia also reported that 11 dependencies had been precompiled at versions different from the versions already loaded by the outer test process. This confirms that launching Pkg.test() fresh is not enough: the collision is created later when the Downstream group changes environments inside that same outer test process.

This is the failing control for the successful isolated-group real-graph run reported above with SciMLTesting #23 plus ModelingToolkit #4749. No source in this PR was modified for either run.

@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review July 21, 2026 14:10
@ChrisRackauckas
ChrisRackauckas merged commit 262b967 into SciML:main Jul 21, 2026
6 of 11 checks passed
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.

2 participants