Skip to content

perf(lsmr): one true-residual check at a tolerance stop, restart from a refuted one - #388

Merged
schroedk merged 2 commits into
mainfrom
perf/lsmr-exit-cost
Sep 23, 2026
Merged

schroedk merged 2 commits into
mainfrom
perf/lsmr-exit-cost

Conversation

@schroedk

@schroedk schroedk commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Stack 7/9 (feature), based on main (#399 merged). Closes the v0.3.0→main additive solve regression from the #291 exit audit (A + Aᵀ + M⁻¹ apply and serial passes at every tolerance stop, ~1.5 iterations per solve).

  • A tolerance stop is held to one fused A apply: ‖b − A x‖ against the recurrence's own ‖r_k‖ (fix(lsmr): underflowed norms, Givens update scale, LSMR's own residual estimate #391), slack 100·tol·‖b‖. A refuted stop restarts from its iterate, at most twice, then FalseConvergence.
  • Warm exits still report the normal-equation residual relative to ‖Âᵀb‖ (one Aᵀ + one M⁻¹ apply), as the Python stubs promise for the Adaptive hand-off.
  • The α₁ = 0 corroboration stays; the singular-preconditioner blind-spot tests at k > 0 go with the Aᵀ leg, so M⁻¹ must be nonsingular.
  • A refused stop reports the returned iterate's normal-equation residual, reseeding once from the staged residual (off the converged path).
  • The check sees estimate drift, not drift within range(A); the docs and CHANGELOG say so. test: pin the #286 akm_slopes cell against fake convergence #397's cell stays green.

Hot loop, measured before the split, 8 threads, min of interleaved rounds vs v0.3.0: 2M×3FE/10 iters +0.9% (main +18.1%), 8M×3FE/14 iters +1.5% (main +13.5%). Smoke suite 94/94 converged, correctness 8/8.

@schroedk
schroedk changed the base branch from main to fix/lsmr-numerics September 23, 2026 07:19
@schroedk
schroedk added this pull request to stack #393 September 23, 2026 07:24
@schroedk
schroedk force-pushed the perf/lsmr-exit-cost branch 2 times, most recently from 3651105 to ff8530e Compare September 23, 2026 07:36
@schroedk
schroedk removed this pull request from stack #393 September 23, 2026 13:17
@schroedk
schroedk added this pull request to stack #396 September 23, 2026 13:17
Base automatically changed from fix/lsmr-numerics to main September 23, 2026 13:28
@schroedk
schroedk removed this pull request from stack #396 September 23, 2026 15:05
@schroedk
schroedk changed the base branch from main to test/fake-convergence-cell September 23, 2026 15:05
@schroedk
schroedk added this pull request to stack #398 September 23, 2026 15:06
Base automatically changed from test/fake-convergence-cell to main September 23, 2026 15:19
@schroedk
schroedk removed this pull request from stack #398 September 23, 2026 15:35
@schroedk
schroedk changed the base branch from main to refactor/lsmr-stream-seed September 23, 2026 15:35
@schroedk
schroedk added this pull request to stack #400 September 23, 2026 15:36
@schroedk
schroedk removed this pull request from stack #400 September 23, 2026 15:51
@schroedk
schroedk added this pull request to stack #402 September 23, 2026 15:52
Base automatically changed from refactor/lsmr-stream-seed to main September 23, 2026 16:10
…om a refuted one

The exit audit recomputed `b − Ax`, `Aᵀr` and `M⁻¹Aᵀr` at every tolerance
stop, about 1.5 iterations per solve. A stop is now held to one
true-residual evaluation, `‖b − A x‖` against the recurrence's own
`‖r_k‖`, and a refuted stop restarts the stream from its iterate, at most
twice, before `FalseConvergence`. The `Aᵀr` and `M⁻¹` legs, the
certificate and its warm re-base are gone; a warm exit's normal-equation
report still divides by `‖Âᵀb‖`, one `Aᵀ` and one `M⁻¹` apply, fixed for
the solve so a restarted pass reports against the same quantity.

`M⁻¹` must now be nonsingular: a direction it annihilates lies outside
the Krylov space, and the singular-preconditioner test flips from
refused to certified.

Hot loop, measured at d49ffd6 before the stack was split, 8 threads,
min of interleaved rounds against v0.3.0: 2M×3FE 10 iterations +0.9%
(main +18.1%), 8M×3FE 14 iterations +1.5% (main +13.5%). Smoke suite
94/94 converged.
…terate

A `FalseConvergence` result carried the recurrence's refuted estimate as
`normal_eq_residual`, often a collapsed ~0 next to `converged = false`.
The refused path now seeds once from the staged `b − A x` (one Aᵀ and
one M⁻¹ apply, off the converged path) and reports its `‖Âᵀr‖`.

The `converged` doc and CHANGELOG say what the one-apply check covers:
estimate drift, not drift within `range(A)`. Multi-line doc comments
added by the exit rework are collapsed to one line.
@schroedk
schroedk merged commit 498f0c7 into main Sep 23, 2026
5 checks passed
@schroedk
schroedk deleted the perf/lsmr-exit-cost branch September 26, 2026 06:58
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.

1 participant