Repository navigation
perf: interferometer sparse data vector without the dense mapping matrix - #630
Merged
Merged
Conversation
InversionInterferometerSparse.data_vector computed mapping_matrix.T @ d~, materialising the dense (masked pixels x source pixels) mapping matrix via hstack: 4.2 GB at 91,507 x 5,746 on the Aris 512x512 mask, the entire RSS growth of one likelihood call on both the numba and FFT routes. Each Mapper block is now a segment-sum of vals * d~[rows] over its sparse COO triplets (slim rows; np.bincount on NumPy, .at[].add on JAX), built by a new _sparse_triplets_slim_from helper that reproduces mapping_matrix_from exactly (sub_fraction normalisation, padding slots beyond pix_sizes and -1 indices zeroed). Linear function lists keep their small dense block; blocks are concatenated in linear_obj_list order. Aris 512x512 (91,507 masked pixels), bench.py: - numba route, 5,746 vertices, 1 thread: peak RSS 7.17 -> 3.14 GB; logL rel. change <= 2.5e-11 (data vector rel. diff 6e-16 vs dense) - JAX jit, 1,459 vertices: peak RSS 3.65 -> 2.60 GB, logL identical - JAX, 5,746 vertices: XLA compile temp 8.95 -> 1.86 GB; the jit run that was previously infeasible now runs at peak RSS 3.24 GB Closes #626. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
InversionInterferometerSparse.data_vectorcomputedmapping_matrix.T @ d~, which builds the dense (masked pixels x source pixels) mapping matrix withhstack. On the Aris 512x512 mask (91,507 masked pixels, 5,746 Delaunay vertices) that matrix is 4.2 GB, and it accounted for all of the RSS growth in one likelihood call on both the numba and FFT routes.Each
Mapperblock is now a segment-sum ofvals * d~[rows]over its sparse COO triplets. It usesnp.bincounton NumPy and.at[].addon JAX. A new private helper,_sparse_triplets_slim_from, rebuilds the triplets so they matchmapper_util.mapping_matrix_fromexactly: it keeps thesub_fractionnormalisation and gives zero weight to padding slots (slot >=pix_sizes, or index -1). Linear function lists keep their small dense block. Blocks are joined inlinear_obj_listorder. The numba subclass inherits the new path.Closes #626
Witness: Aris 512x512,
use_jax=False, before vs afterDirect check at 1,459 vertices: the sparse data vector matches the dense
mapping_matrix.T @ d~to a maximum relative difference of 5.8e-16. Timings are not claimed: the machine's load average was 2 to 14 while measuring. The data-vector change is not on a hot path.Campaign: this task belongs to the PyAutoPulse interferometer campaign as task
interferometer_large_mask_aris(PyAutoLabs/PyAutoPulse#62). At close-out, copy the before/after witness table above into that task file.Decision taken
git revert 8676b6a0API Changes
None. Internal changes only.
Behaviour note: in JAX mixed-precision mode the data vector now uses a float64 data-vector block instead of a float32 mapping matrix. This is slightly more accurate, but not bit-identical in that mode.
Test Plan
pytest test_autoarray -x -qin the worktree: 2033 passed, 4 xfailed, 0 failed. The interferometer and interferometer_numba suites (125 tests) are included.mapping_matrix.T @ d~to 1e-12. They cover an over-sampled (sub 2) Delaunay mapper, a mapper plus a linear function list in both orders, and aDatasetInterfacewith its ownsparse_dirty_image(with a control check). The JAX backend case usesimportorskip, matching the existing JAX tests in this file.Validation checklist (--auto run — plan was not pre-approved)
pyauto-heart smoke autolens autogalaxy autolens_test --root <worktree>ran 92/92 scripts and 4/4 notebooks with 0 failures. That covers autolens_workspace 41+2, autogalaxy_workspace 14+2 and autolens_workspace_test 37, including 15 interferometer scripts (interferometer/features/pixelization/delaunay.py,jax_assertions/fit_interferometer_sparse_operator.py,interferometer/jax_likelihood/*,datacube/shared_preloads.py,subhalo_recovery_interferometer.py, …). There were no pre-existing failures to separate out. · review CLEAN (independent Opus reader; the author was Fable). Claim checked: "JAX jit, 1,459 vertices: peak RSS 3.65 -> 2.60 GB, logL identical". Evidence:before_jit_s8.json/after_jit_s8.jsongive peak_rss_gb 3.653/2.604 and out_sample 14088615.924248978 in both. · Heart RED, under a recorded development override (not green):Heart: RED — Release RED; monitoring RED · 10/100 · 415 unresolved;[red] release validation FAILED (stage integrate);[red] PyAutoHands/workflows/Python Version Matrix: failure;[red] PyAutoHeart/workflows/Release Integrate: failure;[red] PyAutoMind/workflows/Lifecycle Drift: failure;[red] PyAutoArray/Tests: red;[red] autofit_workspace_test/Smoke Tests: red;[red] autogalaxy_workspace_test/Smoke Tests: red;[red] autolens_workspace_test/Smoke Tests: red;[red] Release validation: NOT release_ready — v2026.10.15.1.dev81701;[red] Worktree drift: 5 orphan / 0 missing / 4 dirty;[red] autolens_inference: red;[red] autolens_profiling: red;[red] euclid_strong_lens_modeling_pipeline: red.pyauto-heart readiness --jsonafter a vitals refresh, 2026-10-15 ~18:51): verdictred, reasonsrelease validation FAILED (stage integrate);PyAutoFit: open PR 8d old./prm, and Heart stays RED for release.decision-takenand shipped under a Heart RED override.Full API Changes (for automation & release notes)
Added (private)
InversionInterferometerSparse._sparse_triplets_slim_from(mapper): slim-row COO triplets that reproducemapping_matrix_fromInversionInterferometerSparse._data_vector_mapper_from(mapper, dirty_image): segment-sumAᵀ d~blockChanged Behaviour
InversionInterferometerSparse.data_vector: same values to float64 precision. The dense mapping matrix is no longer built. JAX mixed precision now uses a float64 block instead of a float32 mapping matrix.Migration
Generated by the PyAutoLabs agent workflow.
🤖 Generated with Claude Code