Skip to content

Drop the redundant axes(::SparsityPatternCSC, ::Integer) method (invalidates 2k+ ModelingToolkit instances on load) - #338

Merged
gdalle merged 1 commit into
JuliaDiff:mainfrom
ChrisRackauckas-Claude:remove-redundant-axes
Sep 4, 2026
Merged

Drop the redundant axes(::SparsityPatternCSC, ::Integer) method (invalidates 2k+ ModelingToolkit instances on load)#338
gdalle merged 1 commit into
JuliaDiff:mainfrom
ChrisRackauckas-Claude:remove-redundant-axes

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

What

Removes Base.axes(S::SparsityPatternCSC, d::Integer) = Base.OneTo(size(S, d)) from src/graph.jl. SparsityPatternCSC <: AbstractMatrix{Bool} and defines size, so Base's fallback axes(A::AbstractArray, d) already returns exactly OneTo(size(S, d)) (and OneTo(1) for d > 2, same as before). Adds axes(A) == axes(S) and the d = 3 case to the existing size testset so the behaviour stays pinned.

Why

Adding that method at load time invalidates every axes(A, d) call site that was compiled earlier with an abstract A (axes(::AbstractArray, ::Int64), axes(::AbstractMatrix, ::Int64), axes(::AbstractArray, ::Any) all take a backedge to the method table). SparseMatrixColorings is loaded by OrdinaryDiffEqDifferentiation, i.e. after ModelingToolkit, and on that stack the insertion kills 3,055 cached instances, 2,049 of them in ModelingToolkit / ModelingToolkitBase / ModelingToolkitTearing / Symbolics: __mtkcompile, _mtkcompile, maybe_build_initialization_problem, process_SciMLProblem, alias_elimination!, find_eq_solvables!, ODEProblem, NonlinearProblem. In practice using ModelingToolkit, OrdinaryDiffEq discards the model-building code that ModelingToolkit's precompile workload just cached.

Measured with SnoopCompileCore.@snoop_invalidations using OrdinaryDiffEq after using ModelingToolkit (Julia 1.12.7, ModelingToolkit 11.40, OrdinaryDiffEq 7.8.1, SparseMatrixColorings 0.4.27 vs this branch Pkg.developed):

instances invalidated by the axes insertion of which ModelingToolkit-family build the workload models after using OrdinaryDiffEq
0.4.27 3,055 2,049 12.3 s / 3.4 s
this branch – (method gone) 0 0.37 s / 0.10 s

(The last column is mtkcompile + ODEProblem for a small ODE and a small DAE that ModelingToolkit's own workload compiles; with the invalidation those take 12.3 s and 3.4 s on first use even though they are in the pkgimage.)

Tests

Pkg.test() on Julia 1.12.7: SparseMatrixColorings | 50464 pass, 31 broken (pre-existing) | 11m44s, tests passed. JuliaFormatter (BlueStyle) reports both touched files formatted.

Context (analysis and scripts): https://github.com/ChrisRackauckas/InternalJunk/issues/88#issuecomment-5537967759. SciML also carries a defensive canary for this pattern in SciML/CommonWorldInvalidations.jl#45; this PR is the fix at the source.

🤖 Generated with Claude Code (model: claude-fable-5-1) on behalf of Chris Rackauckas
https://claude.ai/code/session_01FeJYXni9MkJhPFA9yxYvfn

`SparsityPatternCSC <: AbstractMatrix{Bool}` and defines `size`, so Base's
`axes(A::AbstractArray, d)` already returns `OneTo(size(S, d))`. The extra
method changes nothing for callers, but inserting it when the package loads
invalidates every `axes(A, d)` call site compiled earlier with an abstract
`A`; on the ModelingToolkit stack that is 2,049 instances, which throws away
those packages' precompile caches as soon as OrdinaryDiffEq is loaded.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Agent-Harness: Claude Code 2.1.259
Agent-Model: claude-fable-5-1
Agent-Session: https://claude.ai/code/session_01FeJYXni9MkJhPFA9yxYvfn
@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review September 4, 2026 18:05
@ChrisRackauckas

Copy link
Copy Markdown
Member

Seems like an easy win.

@gdalle

gdalle commented Sep 4, 2026

Copy link
Copy Markdown
Member

Agreed, docs failure is unrelated

@gdalle
gdalle merged commit 2102e7e into JuliaDiff:main Sep 4, 2026
5 of 7 checks passed
ChrisRackauckas added a commit to SciML/CommonWorldInvalidations.jl that referenced this pull request Sep 4, 2026
This reverts commit e84633a and bumps to
1.2.2. The invalidation the canaries guarded against came from a single
redundant method, `Base.axes(::SparsityPatternCSC, ::Integer)` in
SparseMatrixColorings, which has now been removed at the source
(JuliaDiff/SparseMatrixColorings.jl#338). With that
gone, the canaries only cost every abstractly typed `axes(A, d)` call site
its world-split, so they are no longer worth carrying.



Agent-Harness: Claude Code 2.1.259
Agent-Model: claude-fable-5-1
Agent-Session: https://claude.ai/code/session_01FeJYXni9MkJhPFA9yxYvfn

Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.20%. Comparing base (e8d80d6) to head (37cb48d).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #338      +/-   ##
==========================================
- Coverage   99.20%   99.20%   -0.01%     
==========================================
  Files          21       21              
  Lines        2151     2150       -1     
==========================================
- Hits         2134     2133       -1     
  Misses         17       17              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

3 participants