Skip to content

research: numba positive-only solve vs JAX sparse-operator mode — same linear algebra? #513

Description

@Jammy2211

Overview

Research task (batch 2026-08-31-pm, member numba-vs-jax-sparse, --auto, effective level supervised = min(header safe, research cap)). The subhalo_validation end-to-end runs put the numba CPU path ~8x faster than the old code. The human asked whether the linear-algebra approach behind that speed is the same as the sparse-operator mode already implemented for JAX — and if not, whether the numba approach is amenable to GPU-JAX speed-up or rests on sparsity exploitation that suits it to CPU. Deliverable is a written verdict posted on this issue; no library changes.

Plan

Detailed implementation plan

Affected Repositories

  • PyAutoArray (primary — read-only; no changes)

Branch Survey

Repository Current Branch Dirty?
./PyAutoArray main clean (read-only)

Suggested branch: n/a — research verdict only, no code changes, no worktree.

Investigation Steps

  1. Read the solver dispatch: autoarray/inversion/inversion/inversion_util.py::reconstruction_positive_only_from (xp dispatch: JAX → util/jax_nnls.py::solve_nnls_primal PDIP; NumPy → util/fnnls.py::fnnls_cholesky active-set + inversion/inversion/nnls_memo.py warm-start memo).
  2. Read the two operator realisations: inversion/inversion/imaging/inversion_imaging_util.py::ImagingSparseOperator (JAX, FFT matrix-free W = Hᵀ N⁻¹ H) vs inversion/inversion/imaging_numba/inversion_imaging_numba_util.py::psf_precision_operator_sparse_from + SparseLinAlgImagingNumba (numba, explicit per-pixel-pair preload); the dataset factories apply_sparse_operator / apply_sparse_operator_cpu and the inversion factory dispatch.
  3. Read the two F assemblies: ImagingSparseOperator.curvature_matrix_diag_from (COO scatter → batched FFT → segment_sum) vs curvature_matrix_via_sparse_operator_two_stage_from (perf(numba): HST curvature matrix phase 2 — mapper×mapper block + MGE operated matrix #507 sparse contraction over unique data→pix mappings).
  4. Ground the numbers against autolens_profiling/results/notes/nnls_warm_start_memo.md, nnls_warm_start_memo_matrix.md, nnls_solver_ledger.md and the breakdown JSONs — no re-profiling.
  5. Pull Memory context: wiki/methods/concepts/autodiff-implicit-diff.md (gradients through the positive-only solve), wiki/methods/sources/linear-algebra.md (FNNLS lineage).
  6. Write the verdict per the prompt's four questions as an issue comment; park for human review (judge-tier task — no decide-and-flag).

Key Files

  • autoarray/inversion/inversion/inversion_util.py — solver dispatch, both paths
  • autoarray/util/fnnls.py, autoarray/util/cholesky_funcs.py, autoarray/inversion/inversion/nnls_memo.py — numba/NumPy active-set solve
  • autoarray/util/jax_nnls.py — JAX PDIP driver with custom VJP
  • autoarray/inversion/inversion/imaging/{sparse.py,inversion_imaging_util.py} — JAX sparse-operator mode
  • autoarray/inversion/inversion/imaging_numba/{sparse.py,inversion_imaging_numba_util.py} — numba sparse-operator mode
  • autoarray/inversion/inversion/factory.py, autoarray/dataset/imaging/dataset.py — mode selection

Original Prompt

Click to expand starting prompt

Is the numba positive-only solve the same linear algebra as the JAX sparse-operator mode?

Type: research
Target: autoarray
Repos:

  • PyAutoArray
    Themes:
  • numba-cpu
  • jax
    Difficulty: medium
    Autonomy: safe
    Priority: normal
    Status: formalised
    Consequence: judge
    Review-minutes: 20
    Unattended: ready
    Filed: 2026-08-31

Intake from the 2026-08-31-am batch review, prompted by the subhalo_validation
end-to-end runs (numba CPU path ~x8 faster than the old code end to end). Human,
verbatim:

"""

  1. End to end runs are good in general, with numba speed up run times roughly x8
    faster than old code, incredible. Do an intake to investigate if the linear algebra
    approach taken for this is the same as the sparse operator mode alreasdy implemented
    for JAX, and if it is not ask whether it is amenable to GPU JAX speed up or if there
    is some sparsity exploitation that means this is suited to CPU.
    """

Deliverable is a written verdict (no library changes):

  1. Characterise the linear algebra of the numba CPU positive-only solve as shipped
    (the NNLS warm-start/memo lineage — PyAutoArray perf: warm-start the positive-only NNLS solve from the previous evaluation's passive set (#498) #501, epic numba-cpu-likelihood;
    curvature-matrix F work perf: numba CPU curvature matrix F at HST resolution (phase 1: split + FFT mapper×func block) #505/perf(numba): HST curvature matrix phase 2 — mapper×mapper block + MGE operated matrix #507; the 177 MB sparse operator per process).
  2. Compare against the sparse-operator mode already implemented for JAX: same
    formulation (operator storage, curvature assembly, solve strategy) or different?
  3. If different: is the numba approach amenable to a GPU-JAX port (batched/dense
    enough, no data-dependent control flow), or does its speed rest on sparsity
    exploitation / branchy active-set iteration that is intrinsically CPU-suited?
  4. Verdict + recommendation: unify, port, or keep two deliberately different paths —
    with the evidence for whichever it is.

Ground against the installed stack and the numba-cpu epic's memory/notes; do not
re-profile from scratch — the breakdown JSONs and nnls_warm_start_memo.md in
autolens_profiling already carry the numbers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions