You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Optimize the non-negative least squares (NNLS) solve used by the pixelization inversion pipelines. The JAX path solves via jaxnnls.solve_nnls_primal (PDIP); the 2026-07-09 Delaunay review measured that the solver is a modest but real lever (tolerance loosening ≈15–20%, hard-coded MAX_ITER=50 under vmap pays worst-case-lane, fresh ~n² Cholesky every PDIP iteration) while refuting warm-starts (cond(Q)~1e16). Priority is the rectangular pipeline — upcoming work concentrates there and it has no host callback, so the linear-algebra solve dominates its 52.7ms/32.9ms (A100 single/vmap) per-eval cost. All profiling uses the production pixelization + MGE lens light configuration.
Two deliverables beyond the speedup itself:
A go/no-go checkpoint with measured NNLS shares per pipeline before any source edit.
Re-baseline Delaunay + rectangular per-eval costs post PyAutoArray#368 (qhull-only callback), pixelization+MGE configs; local CPU now, A100 when RAL returns.
Measure the NNLS PDIP share and iteration counts per pipeline; instrument per-iteration Cholesky cost and vmap worst-lane amplification.
Checkpoint: report go/no-go + chosen lever set on this issue, including the Delaunay next-target verdict.
If go: expose solver controls (solver_tol, max_iter) — vendor the PDIP loop into autoarray or land params upstream in jaxnnls (decided at checkpoint with numbers).
New config keys default to current behavior; mirror into workspace configs.
Stability gates: Δlog_evidence parity on production rect + Delaunay fits, JIT-vs-eager drift, vmap batch checks, noise-scale invariance; before/after benchmarks.
Design note written for later PyAutoBrain ingestion; ship via ship_library.
Detailed implementation plan
Affected Repositories
PyAutoArray (primary — all source edits)
PyAutoLens (context/validation only; no edits expected)
autolens_profiling (untracked scratch/ only — repo is claimed by profiling-preopt-campaign, so no branch there)
Branch Survey
Repository
Current Branch
Dirty?
./PyAutoArray
main
clean
./PyAutoLens
main
clean
./autolens_profiling
main
untracked results only (claimed by profiling-preopt-campaign)
Suggested branch:feature/nnls-solver-optimization Work Classification: Library Worktree root:~/Code/PyAutoLabs-wt/nnls-solver-optimization/ (created by /start_library)
Implementation Steps
Phase A — assessment (standalone, no source edits)
Checkpoint on this issue: measured shares, go/no-go, vendor-vs-upstream decision.
Phase B — implementation (PyAutoArray, only if go)
6. Expose solver_tol / max_iter controls. Preferred route decided at checkpoint:
vendor: autoarray/util/jax_nnls.py PDIP loop with configurable tol/max_iter (and any measured Cholesky-reuse win), dispatch in autoarray/inversion/inversion/inversion_util.py (~lines 275–321);
upstream: params added to jaxnnls.solve_nnls_primal, autoarray passes them through.
Config keys in autoarray/config/general.yaml → inversion (alongside nnls_jacobi_preconditioning, nnls_target_kappa), defaults = current behavior; mirror into workspace configs.
NumPy-only unit tests for config plumbing/dispatch (no JAX in library unit tests).
Phase C — validation + ship
9. JAX validation via autolens_workspace_test parity scripts + fitness._vmap; Δlog_evidence parity on production fits (caustic-geometry lesson from #367: production grids, not toy grids).
10. Before/after benchmark table; design note for PyAutoBrain ingestion; ship_library + smoke tests.
Optimize the fast non-negative least squares solver for the Delaunay and rectangular mesh pipelines
Type: feature
Target: autolens_profiling
Repos:
PyAutoArray
PyAutoLens
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: formalised
You are working in the PyAutoLens codebase. First, review the recent Delaunay mesh speed-up work and understand what was changed and why. Then assess whether optimizing the fast non-negative least squares solver is the right next target, considering both Delaunay and rectangular mesh pipelines. If it is, propose and implement a careful optimization with benchmarks and numerical stability checks. Keep the design clean and document it so that it can be ingested into PyAutoBrain later. Before coding, summarize your understanding, confirm the optimization target, and outline a step-by-step plan.
(formalised by the Intake (Conception) Agent on 2026-07-09; user refinements at issue time: rectangular pipeline is the priority; profile pixelization+MGE configs only; re-baseline Delaunay post-#368; work standalone; report the correct next Delaunay target before implementation.)
Overview
Optimize the non-negative least squares (NNLS) solve used by the pixelization inversion pipelines. The JAX path solves via
jaxnnls.solve_nnls_primal(PDIP); the 2026-07-09 Delaunay review measured that the solver is a modest but real lever (tolerance loosening ≈15–20%, hard-codedMAX_ITER=50undervmappays worst-case-lane, fresh ~n² Cholesky every PDIP iteration) while refuting warm-starts (cond(Q)~1e16). Priority is the rectangular pipeline — upcoming work concentrates there and it has no host callback, so the linear-algebra solve dominates its 52.7ms/32.9ms (A100 single/vmap) per-eval cost. All profiling uses the production pixelization + MGE lens light configuration.Two deliverables beyond the speedup itself:
vmap_method="sequential"), the NNLS solve, or something else in the per-eval budget.Plan
solver_tol,max_iter) — vendor the PDIP loop into autoarray or land params upstream in jaxnnls (decided at checkpoint with numbers).ship_library.Detailed implementation plan
Affected Repositories
scratch/only — repo is claimed byprofiling-preopt-campaign, so no branch there)Branch Survey
Suggested branch:
feature/nnls-solver-optimizationWork Classification: Library
Worktree root:
~/Code/PyAutoLabs-wt/nnls-solver-optimization/(created by/start_library)Implementation Steps
Phase A — assessment (standalone, no source edits)
autolens_profiling/scratch/nnls_speedup/PoC scripts (extend the priorscratch/delaunay_speedup/demo_2_nnls_speedup.py), HST pixelization+MGE configs, rectangular first, Delaunay second.jaxnnls.pdip: iteration counts, per-iterationcho_factorcost (n≈1560), share of total per-eval; measurelax.while_loop-under-vmapworst-lane amplification on realistic batches.vmap_method="sequential") vs NNLS vs mapping/curvature ops → the "right next Delaunay target" verdict.Phase B — implementation (PyAutoArray, only if go)
6. Expose
solver_tol/max_itercontrols. Preferred route decided at checkpoint:autoarray/util/jax_nnls.pyPDIP loop with configurable tol/max_iter (and any measured Cholesky-reuse win), dispatch inautoarray/inversion/inversion/inversion_util.py(~lines 275–321);jaxnnls.solve_nnls_primal, autoarray passes them through.autoarray/config/general.yaml→inversion(alongsidennls_jacobi_preconditioning,nnls_target_kappa), defaults = current behavior; mirror into workspace configs.Phase C — validation + ship
9. JAX validation via
autolens_workspace_testparity scripts +fitness._vmap; Δlog_evidence parity on production fits (caustic-geometry lesson from #367: production grids, not toy grids).10. Before/after benchmark table; design note for PyAutoBrain ingestion;
ship_library+ smoke tests.Key Files
autoarray/inversion/inversion/inversion_util.py— NNLS dispatch (JAX → jaxnnls PDIP, NumPy → fnnls_cholesky)autoarray/util/fnnls.py— NumPy Bro & Jong solver (not the lever; unchanged unless profiling says otherwise)autoarray/config/general.yaml— inversion solver config keysjaxnnls/pdip.py— hard-codedMAX_ITER=50,solver_tol = n*EPSILON, per-itercho_factor(third-party, already PyAuto-modified)autolens_profiling/scratch/delaunay_speedup/— prior PoC + design notes this work builds onPrior evidence (2026-07-09 Delaunay review)
Original Prompt
Click to expand starting prompt
Optimize the fast non-negative least squares solver for the Delaunay and rectangular mesh pipelines
Type: feature
Target: autolens_profiling
Repos:
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: formalised
You are working in the PyAutoLens codebase. First, review the recent Delaunay mesh speed-up work and understand what was changed and why. Then assess whether optimizing the fast non-negative least squares solver is the right next target, considering both Delaunay and rectangular mesh pipelines. If it is, propose and implement a careful optimization with benchmarks and numerical stability checks. Keep the design clean and document it so that it can be ingested into PyAutoBrain later. Before coding, summarize your understanding, confirm the optimization target, and outline a step-by-step plan.
(formalised by the Intake (Conception) Agent on 2026-07-09; user refinements at issue time: rectangular pipeline is the priority; profile pixelization+MGE configs only; re-baseline Delaunay post-#368; work standalone; report the correct next Delaunay target before implementation.)