Skip to content

fix: JAX-trace Sérsic stellar-mass CSE deflection path (#499)#500

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/mass-cse-jax-decompose
Jul 14, 2026
Merged

fix: JAX-trace Sérsic stellar-mass CSE deflection path (#499)#500
Jammy2211 merged 1 commit into
mainfrom
feature/mass-cse-jax-decompose

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

JAX-trace the Sérsic stellar-mass CSE deflection path so a jitted likelihood over a Sérsic mass profile no longer crashes with TracerArrayConversionError. Surfaced by group/features/advanced/mass_stellar_dark/chaining.py failing fast (26.6s) on the release stack. Classification: real library bug (incomplete CSE→JAX port), not a jax-0.10.2 regression — isothermal and NFW deflect analytically (HK24) and never exercised the CSE path under jit, so this was the first release script to jit a CSE mass profile.

P1 (unblock) only; P2 (parity hardening) tracked as a follow-up (see below).

API Changes

None to the public profile API — no symbol removed or renamed. Internal CSE helpers (decompose_convergence_via_cse, cse_settings_from, _decompose_convergence_via_cse_from) gain an optional xp=np kwarg. Behaviour change: NumPy Sérsic-mass deflections shift at the ~1e-3 level because the CSE count rose (30/40 → static 50/80, i.e. finer → closer to the integral truth). See full details below.

Test Plan

  • test_autogalaxy/profiles/mass/ → 432 passed (NumPy path intact).
  • mass_stellar_dark/chaining.py (release profile, PYAUTO_TEST_MODE=1, jax 0.10.2) → completes, 0 tracebacks.
  • JAX jit round-trip: deflections(xp=jnp) nojit == jit to ~1e-11.
  • NumPy-vs-JAX parity (x64): ≤2e-5 for ag.mp.Sersic n∈[1,4].
  • Downstream: regression goldens pinning Sérsic-mass deflections may need a ~1e-3 refresh (/start_workspace if so).
Full API Changes (for automation & release notes)

Changed Signature

  • MassProfileCSE.decompose_convergence_via_cse(grid_radii, xp=np) — added xp (abstract + Sersic, SersicGradient, NFW overrides).
  • MassProfileCSE._decompose_convergence_via_cse_from(..., xp=np) — added xp; uses jnp.linalg.lstsq when xp is jax.numpy, scipy.linalg.lstsq for NumPy.
  • sersic.cse_settings_from(..., xp=np) — added xp; standard (mass_to_light_gradient<=0.5) branch rewritten branch-free.

Changed Behaviour

  • Sérsic-family stellar-mass deflections (ag.mp.Sersic/Exponential/DevVaucouleurs) now trace under jax.jit.
  • NumPy deflection values shift ~1e-3 for typical/high n (CSE total_cses/sample_points frozen to static 50/80). test_sersic integral-tolerance asserts (1e-4/1e-3) still pass.

Migration

  • None required — new kwarg is optional and defaults to prior NumPy behaviour.

Validation checklist (--auto run — plan was not pre-approved)

  • Effective level: supervised (header: supervised, cap: bug → supervised)
  • Plan: on the issue (fix: JAX-trace CSE mass-profile decomposition (Sersic/NFW deflections) #499), written at start, unmodified since; ship sign-off given by human in-session
  • Gate: tests 432 pass · smoke n/a (internal API, no workspace symbol refs; chaining.py end-to-end used as smoke — green) · review self-CLEAN · Heart not-GREEN (release-validation integrate:fail = ongoing tail burndown, organism-scope, not this branch)
  • Human: plan sound in hindsight?
  • Human: diff matches plan (no scope creep)?
  • Human: merge, amend, or reject — then log the outcome

Known P2 follow-up (not in this PR)

  • n<1 NumPy-vs-JAX parity gap of 3e-3 (ill-conditioned CSE scipy vs jnp lstsq).
  • Add ag.mp.Sersic deflections to autolens_workspace_test/scripts/profiles_jit.py (harness covers only Isothermal/PowerLaw/NFW — the gap that hid this bug).

Generated by the PyAutoLabs agent workflow.

The cored-steep-ellipsoid (CSE) decomposition used by Sérsic stellar-mass
deflections was only partially ported to JAX, so a jitted likelihood over a
Sérsic mass profile crashed with TracerArrayConversionError (surfaced by
group/features/advanced/mass_stellar_dark/chaining.py on the release stack).
This is an incomplete-JAX-port bug, not a jax-0.10.2 regression — isothermal/
NFW deflect analytically and never exercised the CSE path under jit.

P1 (unblock): thread `xp` through the full CSE deflection path — radial_grid_from,
decompose_convergence_via_cse, axis_ratio, and _decompose_convergence_via_cse_from
(vectorised coefficient matrix + jnp.linalg.lstsq on the JAX path; scipy retained
for NumPy). cse_settings_from is rewritten branch-free (xp.where) so a tracer
sersic_index traces, with total_cses/sample_points frozen to a static 50/80
(conservative max) for static jit shapes and the per-index dex ranges preserved
exactly. NFW/SersicGradient decompose signatures accept `xp` for compatibility.

Validated: mass_stellar_dark/chaining.py completes (0 tracebacks); 432
test_autogalaxy mass-profile tests pass; jit round-trip nojit==jit to ~1e-11;
numpy-vs-jax parity <=2e-5 for n in [1,4]. NumPy Sérsic-mass deflections shift
~1e-3 (finer CSE count). See PyAutoGalaxy#499.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 14, 2026
@Jammy2211 Jammy2211 merged commit b8bc0a3 into main Jul 14, 2026
5 checks passed
@Jammy2211 Jammy2211 deleted the feature/mass-cse-jax-decompose branch July 14, 2026 13:00
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