Fix strict Kantorovich step acceptance#3908
Conversation
|
Commit Executed plan and local evidence:
No test was skipped, disabled, loosened, or converted to warn-only behavior. |
|
CI note: the red |
f32e100 to
b1f6c20
Compare
|
Rebased this PR directly onto current master and removed the unrelated #3907 commit. The branch now contains only |
|
CI note: the red downgrade jobs for |
|
Feature-specific CI update: ImplicitDiscreteSolve Core now passes on Julia LTS, current stable, and prerelease; its downgrade job passes, as does SimpleImplicitDiscreteSolve downgrade. The sole red ImplicitDiscreteSolve check is QA, which is the independently reproduced current-master removal of the previously released OrdinaryDiffEqCore.isdiscretecache public declaration; the focused restoration is #3907. The controller branch remains limited to the strict-predicate fix. |
|
Baseline dependency-floor update: the minimal registered-root prerequisite is now draft NonlinearSolve #1079. It patches NonlinearSolve to 4.21.1, permits LinearSolve 4.3/5, and raises the NonlinearSolveBase floor to the operator-capable 2.35. Exact local evidence includes FirstOrder with LinearSolve 4.3 (including operator tests 14/14), LinearSolve 5 operator tests 14/14, QA 15/15, Runic 373/373, and the formerly failing OrdinaryDiffEq nonlinear sets 44/44, 113/113, and 10/10. The focused OrdinaryDiffEq source-floor follow-up remains separate from this controller PR. |
|
Investigated the failed CI evidence:
Clean local reproduction from upstream
The local peak leaves only about 0.55 GiB on a nominal 8 GiB runner before the OS and runner service. The evidence is therefore consistent with runner memory pressure terminating the VM/runner connection, not a reproducible Julia source/test regression. I found no source failure to bisect and made no code change. This lane should be rerun on a larger-memory runner or split into lower-peak jobs. |
b1f6c20 to
8b2950d
Compare
|
Rebased the focused predicate fix onto current clean I also tested the proposed replacement with
The Kantorovich adapter reached the same endpoint to about For a scalar fixed path where a whole-span homotopy is valid, direct continuation beat the full IDS integrator overhead, but Accordingly, this PR remains the small correctness fix for the general recurrence controller; no homotopy adapter code was added. Post-rebase local validation:
|
|
One-hour rebased-head CI audit:
No completed check implicates the controller predicate or its regression tests. The PR description now contains the benchmark and this full baseline map. |
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
8b2950d to
6a73faf
Compare
|
Rebased after #3970 merged. Current base/head: Fresh local validation on this exact head:
The branch was force-updated only after fetching and confirming the remote feature branch still contained solely the prior authored commit; the update used an explicit force-with-lease. |
|
Fresh post-#3970 CI is complete: 119 success, 3 skipped, 7 failed. All #3908-relevant checks passed: ImplicitDiscreteSolve Core on LTS/current/pre, IDS downgrade, documentation, Runic, and both benchmark lanes. The seven failures are independently tracked/classified:
No tests were skipped, silenced, loosened, or changed. |
Summary
KantorovichTypeControlleracceptance to accept a converged step only when every recorded contraction satisfiesΘk <= Θreject.ImplicitDiscreteSolvefrom 2.1.3 to 2.1.4.Root cause
The controller documentation says strict mode rejects a step whenever any
Θk > Θreject. The implementation usedall(Θreject .< Θks), which reversed the inequality: normal well-contracted steps were rejected, while a history in which every contraction exceeded the rejection threshold was accepted.Why this remains separate from homotopy solving
NonlinearSolve #1071 now provides the controller as
KantorovichHomotopyfor a genuineHomotopyProblem, and OrdinaryDiffEq's existingHomotopyNonlinearSolveAlgadapter can use it for ODE stage equations. That does not make it a drop-in replacement for this controller:HomotopyNonlinearSolveAlgis anOrdinaryDiffEqCore.AbstractNLSolverAlgorithmconsumed by the ODE stage-solver machinery, not a NonlinearSolve algorithm accepted byinit(::NonlinearProblem, ...). An exact attempted substitution inIDSolve.nlsolveexits withSciMLBase.NonSolverError.ImplicitDiscreteProblemsolvesf(u_next, uprev, p, t) = 0and replacesuprevafter every accepted state. It is therefore a sequence of changing nonlinear problems, not one fixed homotopy int.Performance check
The closest generic square-problem prototype used
at every discrete step. The recurrence endpoint matched the current solver to about
1e-12. Medians below are from 20 warmed Julia 1.12.6 samples:IDSolveKantorovichHomotopyper stepHomotopySweepper stepThe Kantorovich replacement was 17.4x slower and allocated 35x as many objects.
For a scalar path whose residual ignores
uprev, a whole-span homotopy is valid and avoids the IDS integrator overhead. In that restricted case,HomotopySweeptook 0.205 ms andKantorovichHomotopytook 0.347 ms (current IDS: 0.507 ms), with all endpoints agreeing at floating-point precision. This is consistent with NonlinearSolve #1071's broader comparison: Kantorovich continuation can win on some paths, but it is not a general replacement for Sweep or for the recurrence controller here.Validation
Run on the rebased branch head
6a73faf817:ODEDIFFEQ_TEST_GROUP=Coreon Julia 1.10.11: exit 0, all 34 assertions passed;Kantorovich strict acceptancepassed 4/4.Repository-wide Runic check: exit 0.
git diff --check: exit 0.ODEDIFFEQ_TEST_GROUP=QAon rebased head: JET passed 1/1; Aqua passed 16/17 and failed only the rendered-public-API check on 185 SciMLBase re-exports plusIDSolve(186 names total). This clean-master failure was bisected to Update SciMLTesting QA docs coverage #3867 and remains isolated in #3969; that focused fix passes Julia 1.10 JET 1/1 and Aqua 17/17 plus Runic and diff checks. The umbrella docs fix #3970 is merged in this branch base. No test was skipped, silenced, loosened, or changed.Rebased-head GitHub CI completed with 119 successful, 3 skipped, and 7 failed checks. All ImplicitDiscreteSolve Core lanes, its downgrade lane, documentation, Runic, and both benchmark lanes passed. The non-passing checks are independent clean-master baselines or infrastructure:
MatrixOperatordowngrade failures in BDF, SDIRK, and OrdinaryDiffEqNonlinearSolve: #3917, with shared-workflow prerequisite SciML/.github #118. The exact locked Raise NonlinearSolveBase floor for operator Jacobians #3917 Core suite was independently rerun on Julia 1.11 and exited 0, including the formerly failing 44/44 and 113/113 groups.Process notes
The work mapped the exact residual-contraction sampling and Deuflhard step-size formula, extracted the reusable controller into NonlinearSolve, benchmarked it against
HomotopySweepandArcLengthContinuation, tested the proposed direct and affine adapters after NonlinearSolve #1071 merged, and kept this independent predicate bug as a small OrdinaryDiffEq patch.