Skip to content

Preserve nonlinear verbosity when resizing caches#3971

Draft
ChrisRackauckas-Claude wants to merge 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:agent/preserve-nonlinear-verbosity-resize
Draft

Preserve nonlinear verbosity when resizing caches#3971
ChrisRackauckas-Claude wants to merge 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:agent/preserve-nonlinear-verbosity-resize

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Jul 20, 2026

Copy link
Copy Markdown
Member

Important

Please ignore this draft until it has been reviewed by @ChrisRackauckas.

Summary

  • preserve the configured nonlinear verbosity when resize-driven initialization rebuilds an inner NonlinearSolve cache
  • add a regression test that resizes and steps an ImplicitEuler integrator configured with detailed nonlinear verbosity
  • bump OrdinaryDiffEqNonlinearSolve from 2.3.0 to 2.3.1

Root cause

The first inner NonlinearSolve cache is initialized with integrator.opts.verbose.nonlinear_verbosity. When an integrator resize changes the nonlinear problem size, initialize! rebuilt that cache without passing the verbosity setting, so NonlinearSolve fell back to its default.

Besides silently changing the requested logging behavior, the rebuilt cache can have a different concrete verbosity type from the cache field created during the original initialization. With SciMLLogging.Detailed(), the resize path then fails while assigning the rebuilt cache.

This patch passes the integrator's configured nonlinear verbosity through the rebuild, matching the original initialization path.

The source-introduction boundary is 32dec6cafeb4104bb69438f578a9043c4f7bd11f (#3799), which introduced both Base.resize!(::NonlinearSolveCache, ...) and its keyword-less cache rebuild. Its parent, 4259e46ca875a7c9f297271aebbd5590ec648d46, has no specialized resize method, so this is not a conventional passing-parent/first-failing behavioral bisect: the resize capability and omitted propagation entered together. Commit 030f9eb84 later moved the already-defective rebuild into initialize!; it did not introduce the omission.

Validation

  • Red/green regression on the pre-rebase source base: with the new test present and the source fix reverted, the official GROUP=InterfaceIII Pkg.test() run reported 141 passes and one error in DEVerbosity Tests, at the post-resize step!. Restoring the fix produced 142/142 passing DEVerbosity assertions; the full InterfaceIII group also passed (12/12 derivative utilities, 14/14 stats, 24/24 no-index, 5/5 events/DAE, and 52 passed plus four pre-existing broken unit tests).
  • A sequential isolated-depot boundary probe used identical external versions (LinearSolve 3.87.0, NonlinearSolve 4.21.0, NonlinearSolveBase 2.33.0, SciMLLogging 2.0.3) and confirmed exact in-tree source paths. At 32dec6caf, Detailed verbosity was present before resize and the rebuilt default-verbosity cache caused the expected typed-field conversion error. At its parent, the same probe stopped at the expected missing resize!(::NonlinearSolveCache, ...) method.
  • On the rebased commit, the deterministic resize/verbosity regression passed.
  • Under the exact constrained downgrade graph produced with SciML/.github#118 (NonlinearSolveBase 2.34.1, SciMLLogging 1.10.1), all 11 focused sparse/resize assertions passed (3/3, 4/4, and 4/4).
  • Full-repository Runic 1.7.0, git diff --check, and TOML parsing passed after the rebase.

Scope and coordination

The natural downgrade graph on unmodified master independently selects NonlinearSolveBase 2.33.0 and fails the existing sparse operator-Jacobian test in safe_similar. That compatibility-floor issue is addressed by #3917 and is intentionally not folded into this source fix.

This PR takes the OrdinaryDiffEqNonlinearSolve 2.3.1 patch version. #3917 and #3927 currently touch the same version line and will need to rebase and use the next available patch version.

Process

The failure was reproduced against clean source, reduced to the resize rebuild, traced to its source-introduction boundary, verified red/green with a deterministic regression, checked against the exact reconciled downgrade graph, then rebased onto current master and revalidated before publication.

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

ChrisRackauckas-Claude commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Validation scratchpad:

  1. Reproduced the resize failure with an explicit SciMLLogging.Detailed() nonlinear verbosity setting.
  2. Reduced it to the inner NonlinearSolve cache rebuild in initialize!, which omitted the verbosity keyword used by the initial cache construction.
  3. Traced the source-introduction boundary to 32dec6cafeb4104bb69438f578a9043c4f7bd11f (NonlinearSolveCache: define Base.resize! and guard firstcall write #3799). That commit introduced both Base.resize!(::NonlinearSolveCache, ...) and init(new_prob, nlcache.cache.alg) without verbosity; 030f9eb84 only relocated the existing rebuild.
  4. Ran sequential isolated-depot probes with identical external versions (LinearSolve 3.87.0, NonlinearSolve 4.21.0, NonlinearSolveBase 2.33.0, SciMLLogging 2.0.3) and verified pathof pointed at each detached in-tree source. At 32dec6caf, Detailed verbosity before resize became a default-verbosity rebuild and triggered the expected typed-field conversion error. The parent 4259e46ca875a7c9f297271aebbd5590ec648d46 lacks the specialized resize method, so this is a source-introduction boundary rather than a conventional green/first-bad behavioral bisect.
  5. Added a resize-and-step regression to the existing DEVerbosity test file and verified the red/green transition with the official GROUP=InterfaceIII harness.
  6. Checked the fix under the exact reconciled minimum graph with NonlinearSolveBase 2.34.1 and SciMLLogging 1.10.1; the three focused sparse/resize testsets passed 3/3, 4/4, and 4/4.
  7. Rebased onto current master, then reran the deterministic regression, the exact 11/11 focused tests, full-repository Runic, TOML parsing, and git diff --check.

Boundary evidence:

  • 32dec6caf manifest SHA-256: f86c825989df08d56673212b642845b2070cde77579edf799338aaad8091652d
  • parent manifest SHA-256: 8bc522ca4f588b2d99229ea69dea6fde88f820f4fd2b601f296bf3d7bb5ae8e3

The independent NonlinearSolveBase 2.33.0 operator-Jacobian incompatibility remains scoped to #3917. This PR takes version 2.3.1, so #3917 and #3927 will need the next available patch after rebasing.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Two-hour CI checkpoint:

The source-fix coverage is green across every substantive CPU lane:

  • InterfaceIII passed on Julia LTS, current, and pre.
  • Integrators_II passed on Julia LTS, current, and pre.
  • OrdinaryDiffEqNonlinearSolve Core passed on Julia LTS, current, and pre.
  • OrdinaryDiffEqNonlinearSolve ModelingToolkit integration passed.

The failures are independently classified rather than attributed to this one-line propagation fix:

At the checkpoint GitHub reports 148 successful, 18 failed, and three skipped checks. The only unfinished check is StochasticDiffEq [NoncommutativeConvergence], queued with no runner assigned because it requires the self-hosted high-memory label.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

High-memory queue reread — 2026-07-21 01:07 EDT

The sole unfinished #3971 check, StochasticDiffEq NoncommutativeConvergence, remains queued.

  • Required labels: self-hosted, Linux, X64, high-memory
  • Queued since: 2026-07-20 18:38 EDT
  • Assigned runner: none
  • Conclusion: none

This is runner-capacity waiting, not a test result. The PR remains unchanged at 063d785f7c468460b62dcd00a0c8d1eec0d0d57f, draft, and mergeable. Its rollup remains 170 checks: 148 success, 18 failure, 3 skipped, 1 queued.

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