Skip to content

feat: NNLS solver knobs via Settings (nnls_solver_tol / nnls_max_iter), default off#371

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/nnls-solver-optimization
Jul 9, 2026
Merged

feat: NNLS solver knobs via Settings (nnls_solver_tol / nnls_max_iter), default off#371
Jammy2211 merged 2 commits into
mainfrom
feature/nnls-solver-optimization

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

Per-fit knobs for the JAX positive-only (NNLS) interior-point solve, exposed on the Settings class and default off (unset = bit-identical to upstream jaxnnls, validated in solutions and gradients on real production systems):

  • Settings(nnls_solver_tol=1e-6) — ~15-20% of solve time on production HST pixelization+MGE fits, rel Δobjective 3.8e-13 (Δlog-evidence ~1e-8).
  • Settings(nnls_max_iter=...) — caps the solve; under vmap this bounds the worst-case (slowest-lane) batched cost.

Implementation: autoarray/util/jax_nnls.py vendors only jaxnnls's while_loop driver (tolerance/cap are hard-coded upstream); every building block (initialize, pdip_pc_step, solve_relaxed_nnls, diff_nnls) and the relaxed-KKT custom-vjp backward pass are reused from jaxnnls. Knobs are static closure params behind an lru_cache so JIT tracing caches hit. NumPy (fnnls_cholesky) path untouched.

Evidence

Full measurement record: #369 and autolens_profiling/results/notes/nnls_solver_ledger.md (the closed optimization ledger — every deeper lever measured negative; this knob is the one real win).

Test plan

  • New test_autoarray/util/test_jax_nnls.py: module-level JAX-import guard, Settings defaults-off, NumPy-path invariance to the knobs.
  • Full suite: 876 passed.
  • End-to-end JAX validation on the real extracted rect/Delaunay systems: defaults bit-identical to upstream (solutions + gradients); knob reproduces the probe numbers (285→249ms on RTX 2060).
  • Downstream: no API breakage (new optional Settings args); workspace smoke via the normal release gate.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QgtjXWS2iJegXMTDU4GHth

Jammy2211 and others added 2 commits July 9, 2026 22:18
…) — PARKED, not for merge (#369)

Vendored jaxnnls while_loop driver with configurable tolerance and
iteration cap; defaults bit-identical to upstream (solutions and
gradients, validated on real production systems). Parked at user request
2026-07-09 — the measured win (~15-20% of solve) was judged not worth the
new solver code path; this branch preserves the validated implementation
should that change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QgtjXWS2iJegXMTDU4GHth
…), default off (#369)

Rework of the parked d8a1c84: the knobs move from general.yaml config keys
to per-fit Settings attributes (defaults None = jaxnnls's own tolerance
formula and 50-iteration cap — behaviour identical when unset). The vendored
autoarray/util/jax_nnls.py driver is unchanged: reuses all jaxnnls building
blocks + the relaxed-KKT custom-vjp backward; defaults validated bit-identical
to upstream in solutions and gradients on real production systems.

Measured on the real HST pixelization+MGE systems (PyAutoArray#369):
Settings(nnls_solver_tol=1e-6) saves ~15-20% of solve time with rel
delta-objective 3.8e-13 (delta log-evidence ~1e-8); nnls_max_iter also caps
the vmap worst-case lane. Full ledger: autolens_profiling
results/notes/nnls_solver_ledger.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QgtjXWS2iJegXMTDU4GHth
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 9, 2026
@Jammy2211 Jammy2211 merged commit e0cb2fa into main Jul 9, 2026
4 checks passed
@Jammy2211 Jammy2211 deleted the feature/nnls-solver-optimization branch July 9, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant