Skip to content

Avoid eager AutoSpecialize wrapping in SCC solves - #1211

Merged
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix/scc-autospecialize-mooncake
Aug 29, 2026
Merged

ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix/scc-autospecialize-mooncake

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

Ignore this PR until reviewed by @ChrisRackauckas.

What changed

SCCNonlinearSolve now eagerly concretizes only AutoDespecialize subproblems. Ordinary AutoSpecialize subproblems remain unchanged at the outer SCC boundary and are concretized by their individual nonlinear solves, keeping FunctionWrapper construction behind the existing nonlinear solve_up AD boundary.

This restores Mooncake differentiation through ModelingToolkit SCC initialization without weakening the AutoDespecialize behavior added in SCCNonlinearSolve 1.15.0. A regression test verifies that the outer SCC solution retains the original AutoSpecialize residual.

Regression boundary

The last successful SciMLSensitivity Core8 Julia 1.11 job resolved SCCNonlinearSolve 1.14.1 and NonlinearSolveBase 2.43.0. The first failing job resolved SCCNonlinearSolve 1.15.0 and NonlinearSolveBase 2.45.0 while Mooncake 0.5.45, FunctionWrappersWrappers 1.12.1, and the SciMLSensitivity test remained unchanged.

Both SCCNonlinearSolve 1.15.0 and NonlinearSolveBase 2.44.0 were released from commit e416641, which added eager SCC subproblem concretization for AutoDespecialize support. A local package boundary test held Mooncake 0.5.48 and NonlinearSolveBase 2.48.0 constant: SCCNonlinearSolve 1.14.1 passed the exact SciMLSensitivity reproducer, while 1.15.1 failed.

Failing before

On a detached worktree at current NonlinearSolve master with only the new regression test applied:

GROUP=Core julia +1.11 --project=lib/SCCNonlinearSolve -e \
  'using Pkg; Pkg.test(; julia_args=["--check-bounds=yes", "--depwarn=yes"])'
AutoSpecialize remains unconcretized at the SCC boundary: Test Failed
Expression: (solution.prob.probs[1]).f.f === scc_dynamic_residual!
Evaluated: NonlinearSolveBase.AutoSpecializeCallable{...} === scc_dynamic_residual!
Test Summary:                    | Pass  Fail  Total
AutoDespecialize SCC subproblems |   20     1     21
ERROR: Package SCCNonlinearSolve errored during testing

The exact clean SciMLSensitivity master Core8 command on Julia 1.11.9 also reproduced the reported error:

GROUP=Core8 julia +1.11 --project -e \
  'using Pkg; Pkg.test(; coverage=true, julia_args=["--check-bounds=yes", "--compiled-modules=yes", "--depwarn=yes"], force_latest_compatible_version=false, allow_reresolve=true)'
Mooncake through init: Error During Test at test/Core8/desauty_dae_mwe.jl:163
TypeError: in typeassert, expected Mooncake.CoDual{FunctionWrappers.FunctionWrapper{...},
MooncakeFunctionWrappersExt.FunctionWrapperTangent{..., Tuple{...}, ...}},
got ... FunctionWrapperTangent{..., Union{}, ..., Union{}}
Stacktrace:
  [1] maybe_wrap_f
      @ NonlinearSolveBase/src/solve.jl:1038

Passing after

The same SCC Core command on this branch passed all six testsets (62 tests total), including the discriminator:

Test Summary:                                              | Pass  Total
HomotopyProblem SCC block is continued (autodiff threaded) |    5      5
Test Summary:                    | Pass  Total
AutoDespecialize SCC subproblems |   21     21
Testing SCCNonlinearSolve tests passed

The exact SciMLSensitivity test file with Mooncake 0.5.48, NonlinearSolveBase 2.48.0, and this patched SCCNonlinearSolve source passed:

julia +1.11 --project=.repro-env --check-bounds=yes --depwarn=yes -e \
  'include("test/Core8/desauty_dae_mwe.jl")'
Test Summary:               | Pass  Broken  Total
DAE with SCC Initialization |   21       5     26

The dependency-boundary control, changing only SCCNonlinearSolve 1.15.1 to 1.14.1, produced the same 21 pass / 5 broken result.

Additional local validation:

  • GROUP=QA julia +1.11 --project=lib/SCCNonlinearSolve -e 'using Pkg; Pkg.test(; julia_args=["--check-bounds=yes", "--depwarn=yes"])' — QA 20/20; package tests passed.
  • Julia Runic --check --diff on both changed Julia files — exit 0.
  • typos on both changed files — exit 0.
  • git diff --check — exit 0.
  • actionlint — exit 0.

Not verified locally

I did not run GROUP=Everything, GPU groups, Julia 1.10, or the complete downstream matrix. I did not build docs because this changes no documentation or public API. The exact affected SciMLSensitivity test was run directly with the patched sublibrary source; the complete patched SciMLSensitivity Core8 group was not rerun after the focused test passed.

Reviewer judgment

The restriction intentionally applies only to AutoDespecialize, the policy whose stable outer SCC problem type requires eager concretization. AutoSpecialize and the other pre-existing policies keep their pre-1.15 outer-boundary behavior and are still concretized by each individual subproblem solve.

Links

🤖 Generated with Claude Code
https://chatgpt.com/codex/tasks/01a03a17-ad6f-7131-82fc-d0fd57ea6512

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://chatgpt.com/codex/tasks/01a03a17-ad6f-7131-82fc-d0fd57ea6512
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