Skip to content

Preserve Jacobian cache parameter representation - #1227

Merged
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix/autodespecialize-initialization
Sep 5, 2026
Merged

ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix/autodespecialize-initialization

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

What changed

Normalize incoming parameters to the representation already stored by a nonlinear cache, and apply that policy when a nested JacobianCache is reinitialized. This preserves despecialized storage when the cache was built with it and unwraps DespecializedParameters when initialization built the nested cache from a concrete parameter object.

The regression test constructs the latter cache shape directly and verifies that reinitializing it with a despecialized wrapper retains its concrete parameter storage.

This is a focused follow-up to #1199. Please ignore this PR until it has been reviewed by @ChrisRackauckas.

Failing before / passing after

With the new regression test present and the two source changes reverted:

TMPDIR="$PWD/../.tmp" JULIA_PKG_PRECOMPILE_AUTO=0 timeout 3600 \
  "$HOME/.juliaup/bin/julia" +1.12 --startup-file=no \
  --project=lib/NonlinearSolveBase --color=no \
  -e 'using Pkg; Pkg.instantiate(); include("lib/NonlinearSolveBase/test/autodespecialize.jl")'
AutoDespecialize dynamic parameter barrier | 15  15
Jacobian cache preserves raw parameter storage | Error  1
MethodError: Cannot convert SciMLBase.DespecializedParameters to DynamicParameters

The identical command with the fix applied exits 0:

AutoDespecialize dynamic parameter barrier | 15  15
Jacobian cache preserves raw parameter storage | 1  1
AutoDespecialize out-of-place residual | 4  4
AutoDespecialize nonlinear problem variants | 4  4
other specialization policies retain concrete parameters | 2  2

Aggregate: 26 passed, 0 failed, 0 errored.

Introduction boundary

The identical Catalyst/SciMLSensitivity reduced solve exits 0 with NonlinearSolve 4.26.0 / NonlinearSolveBase 2.43.0 and exits 1 with the same DespecializedParameters → MTKParameters conversion on NonlinearSolve 4.27.0 / NonlinearSolveBase 2.44.0. The first-bad release contains the AutoDespecialize implementation from #1164 (e4166415).

The reduced solve still fails on the current NonlinearSolveBase 2.49.2 release and current master. With this patch developed into the same environment, it exits 0 with CATALYST_LOAD_ORDER_NONLINEAR_SUCCESS.

Verification

  • GROUP=Core ... julia +1.12 --project=lib/NonlinearSolveBase -e 'using Pkg; Pkg.test()': 363 passed, 0 failed, 0 errored.
  • GROUP=Core ... julia +1.10.12 --project=<clean temporary environment> -e 'using Pkg; Pkg.develop(path=ARGS[1]); Pkg.test("NonlinearSolveBase")' <path>: 350 passed, 0 failed, 0 errored.
  • GROUP=QA ... julia +1.12 --project=lib/NonlinearSolveBase -e 'using Pkg; Pkg.test()': 20 passed, 0 failed, 0 errored.
  • NONLINEARSOLVE_TEST_GROUP=Core ... julia +1.12 --project=. -e 'using Pkg; Pkg.test()': 1,497 passed, 0 failed, 0 errored, 88 pre-existing broken (1,585 total).
  • JULIA_CONDAPKG_BACKEND=Null JULIA_PYTHONCALL_EXE=/usr/bin/python3 ... julia +1.12 --project=docs -e 'using Pkg; Pkg.instantiate(); include("docs/make.jl")': exit 0; doctests, linkcheck, document checks, and HTML rendering completed.
  • julia +1.12 --project=@runic -m Runic --check <changed files>: exit 0.
  • typos <changed files>: exit 0.
  • git diff --check: exit 0.

The full Catalyst docs build with current downstream sources is still running at the time of this draft; its terminal result will be added in a PR comment. The reduced downstream reproducer above has completed both failing-before and passing-after.

The registered Catalyst docs graph currently cannot resolve NonlinearSolveBase 2.49.x because TimerOutputs 1 support is pending in pogudingleb/RationalFunctionFields.jl#61 and sumiya11/Groebner.jl#226. I validated the 2.49.2 downstream result using those same one-line compat changes rebased onto the current RationalFunctionFields 0.3.4 and Groebner 0.10.6 releases; no dependency was pinned as a workaround.

🤖 Generated with Codex CLI 0.151.0 (model: gpt-5.6-sol; session: local transcript /home/crackauc/.codex/sessions/2026/09/04/rollout-2026-09-04T00-54-40-01a06ac4-d6d4-7812-b432-39b974dddab6.jsonl)

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Codex <noreply@openai.com>
Agent-Harness: Codex CLI 0.151.0
Agent-Model: gpt-5.6-sol
Agent-Session: /home/crackauc/.codex/sessions/2026/09/04/rollout-2026-09-04T00-54-40-01a06ac4-d6d4-7812-b432-39b974dddab6.jsonl
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

The full Catalyst documentation run with this Jacobian-cache fix reached a second parameter-representation error in TrustRegion:

failed to run @example block in docs/src/steady_state_functionality/nonlinear_solve.md:89-92
sol_ntr = solve(nlprob, TrustRegion())
MethodError: Cannot convert SciMLBase.DespecializedParameters to MTKParameters{...}
reinit!(cache::NonlinearSolveFirstOrder.GenericTrustRegionSchemeCache, ...)
makedocs encountered an error [:example_block]

This is reproducible without Catalyst using AutoDespecialize, Enzyme, and public reinit!; the corresponding error converts DespecializedParameters to Float64. Enzyme initializes the inner trust-region cache with raw parameters, whereas reinitialization forwards the outer solver's despecialized parameters.

A two-line follow-up preserving that inner cache's parameter representation is under local validation. The regression fails before the change and passes four assertions afterward; FirstOrder QA passes 20/20. Core and the Catalyst package-load-order check are still running. This PR's successful CI does not establish that the full Catalyst documentation build passes.

AI validation update: Codex CLI 0.153.4, model gpt-6-astra, local session ID 01a0598f-11b9-72d1-91d9-b2fbb186557d.

@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review September 5, 2026 09:40
@ChrisRackauckas
ChrisRackauckas merged commit 0f1fabc into SciML:master Sep 5, 2026
96 checks passed
ChrisRackauckas added a commit that referenced this pull request Sep 7, 2026
- NonlinearSolveBase: rebuild a pre-wrapped function when its signatures do not match u0/p (#1226)
- Fix reverse AD through despecialized parameters (#1228)
- Preserve Jacobian cache parameter representation (#1227)
- Preserve TrustRegion cache parameter representation on reinit (#1229)



Agent-Harness: Claude Code
Agent-Model: claude-opus-5[1m]
Claude-Session: https://claude.ai/code/session_014FEzNTLFutCmTEAZ3zBg5R

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ChrisRackauckas added a commit that referenced this pull request Sep 7, 2026
- NonlinearSolveBase: rebuild a pre-wrapped function when its signatures do not match u0/p (#1226)
- Fix reverse AD through despecialized parameters (#1228)
- Preserve Jacobian cache parameter representation (#1227)
- Preserve TrustRegion cache parameter representation on reinit (#1229)
- Run runic on docstrings and markdown files (#1231)
- Release NonlinearSolveFirstOrder 2.5.1 (#1232)
- NonlinearSolveBase: report the wrapped arity for despecialization wrappers (#1230)



Agent-Harness: Claude Code
Agent-Model: claude-opus-5[1m]
Claude-Session: https://claude.ai/code/session_014FEzNTLFutCmTEAZ3zBg5R

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ChrisRackauckas referenced this pull request Sep 7, 2026
- Drop stale [compat] majors older than one year (#1198)
- Drop @fastmath from L2_NORM/Linf_NORM so isfinite guards survive (#1182)
- Release 4.28.1 (#1202)
- Release 2.48.1 (#1206)
- Align QA NLsolve compat with root project (#1205)
- Widen NonlinearSolveBase LogExpFunctions compat to 0.3.28–1 (#1203)
- Continue polyalgorithm after stalled least-squares solves (#1204)
- Align Wrappers NLsolve compat with root project (#1208)
- Release 2.48.2 (#1210)
- Preserve despecialized parameters during reinit (#1199)



Agent-Harness: Claude Code
Agent-Model: claude-opus-5[1m]
Claude-Session: https://claude.ai/code/session_014FEzNTLFutCmTEAZ3zBg5R

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ChrisRackauckas added a commit that referenced this pull request Sep 10, 2026
- Require all components to stall before resetting Broyden (#1184)
- Add adaptive Jacobian reuse to first-order solvers (#1072)
- Release 4.29.1 (#1220)
- Release 2.49.1 (#1221)
- Release 1.15.3 (#1222)
- Fix @static_timeit for TimerOutputs ≥ 0.5.27 (#1224) (#1225)
- NonlinearSolveBase: rebuild a pre-wrapped function when its signatures do not match u0/p (#1226)
- Fix reverse AD through despecialized parameters (#1228)
- Preserve Jacobian cache parameter representation (#1227)
- Preserve TrustRegion cache parameter representation on reinit (#1229)



Agent-Harness: Claude Code
Agent-Model: claude-opus-5[1m]
Claude-Session: https://claude.ai/code/session_014FEzNTLFutCmTEAZ3zBg5R

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ChrisRackauckas referenced this pull request Sep 10, 2026
- Remove name duplicates in keyword arguments/named tuples (#1238)
- Add 32-bit Core CI lane via test_groups.toml (#1239)
- Add a native bounded trust-region solver (#1219)



Agent-Harness: Claude Code
Agent-Model: claude-opus-5[1m]
Claude-Session: https://claude.ai/code/session_014FEzNTLFutCmTEAZ3zBg5R

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.

2 participants