Skip to content

feat: skip N_vis allocations for sparse fits without non-linear light (Discussion #13) - #637

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/interferometer-streaming-visibilities
Sep 30, 2026
Merged

Jammy2211 merged 1 commit into
mainfrom
feature/interferometer-streaming-visibilities

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

PyAutoGalaxy half of Phase 1 of GitHub Discussion https://github.com/orgs/PyAutoLabs/discussions/13 (see PyAutoLabs/PyAutoArray#588 and its PR). On the sparse path a fit with no non-linear light profile still allocated two N_vis arrays per likelihood evaluation: profile_visibilities (Visibilities.zeros) and profile_subtracted_visibilities (data - zeros). This PR:

  • adds uses_precomputed_data_term_from(dataset, galaxies, data, noise_map) (exposed as FitInterferometer._uses_precomputed_data_term): true when the sparse operator carries data_term, the data and noise map fitted are the dataset's own, and no galaxy has a non-linear light profile. All checks are identity/type checks, so the branch is fixed at trace time and jit-safe;
  • galaxies_to_inversion then passes data=None to aa.DatasetInterface, so fast_chi_squared reads the cached scalar and neither visibility property is ever evaluated on the likelihood path. Dense-path and light-profile fits are byte-identical to before;
  • adds FitInterferometer.inversion_with_data: the inversion, or a shallow copy carrying fit.data when the inversion ran with data=None, for output paths (data_subtracted_dict → subplot_of_mapper). The visualizer uses it.

Witness (1e5 vis NUFFT, 616-pixel mask, 15x15 rectangular mesh, InversionInterferometerSparseNumba): log_evidence one-shot vs chunked operator 1.8e-16 rel; predicate on vs off bit-equal; tracemalloc peak per figure_of_merit 3.19 MB on vs 7.59 MB off at 1e5 and 3.21 MB vs 21.99 MB at 4e5 (flat in N_vis with the predicate on); 9.8 ms vs 11.2 ms per evaluation.

PyAutoLens has its own FitInterferometer/tracer_to_inversion and still passes the subtracted data, so it is unchanged here (follow-up filed in Mind).

API Changes

Additive. New public names autogalaxy.interferometer.fit_interferometer.uses_precomputed_data_term_from and FitInterferometer.inversion_with_data. Behaviour change: on the sparse path with no non-linear light profile, fit.inversion.dataset.data is now None (use fit.inversion_with_data or fit.data for outputs). Requires the PyAutoArray PR (DatasetInterface(data=None), sparse_operator.data_term).
See full details below.

Test Plan

  • pytest test_autogalaxy — 1262 passed
  • pytest test_autogalaxy/interferometer — 43 passed (new: interface gets data=None, no visibilities_from/Visibilities.zeros call during figure_of_merit, both visibility properties unevaluated; sparse pixelization-only and light+pixelization fits match dense at rel 1e-8; scalar noise_normalization == array; inversion_with_data shares the reconstruction; jax.jit sparse fit matches numpy)
  • pytest PyAutoLens/test_autolens/interferometer against these branches — 25 passed
  • Witness script (numbers above)
  • CI green (needs PyAutoArray branch/merge — same-named branch resolution)
Full API Changes (for automation & release notes)

Added

  • autogalaxy.interferometer.fit_interferometer.uses_precomputed_data_term_from(dataset, galaxies, data, noise_map) -> bool
  • FitInterferometer._uses_precomputed_data_term (private property)
  • FitInterferometer.inversion_with_data -> Optional[aa.AbstractInversion] — inversion carrying the fitted data for output/plot paths

Changed Behaviour

  • FitInterferometer.galaxies_to_inversion passes data=None to aa.DatasetInterface when uses_precomputed_data_term_from(...) holds (sparse operator with data_term, dataset's own data/noise map, no non-linear light profile); profile_visibilities / profile_subtracted_visibilities are then never evaluated on the likelihood path
  • interferometer/model/visualizer.py passes fit.inversion_with_data to the inversion plotter

Migration

  • Code reading fit.inversion.data / fit.inversion.data_subtracted_dict on a sparse pixelization-only fit should use fit.inversion_with_data (or fit.data).

Generated by the PyAutoLabs agent workflow.

🤖 Generated with Claude Code

…#588)

Phase 1 of Discussion PyAutoLabs/13. uses_precomputed_data_term_from
decides when the inversion interface may carry data=None (sparse operator
with data_term, dataset's own data/noise map, no non-linear light
profile); galaxies_to_inversion then never evaluates profile_visibilities
or profile_subtracted_visibilities on the likelihood path. Add
FitInterferometer.inversion_with_data for output paths and use it in the
visualizer. Likelihood bit-equal to before; per-evaluation memory flat in
N_vis.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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