Skip to content

potential: pin SCF/Multipole construction-time setup to numpy#986

Merged
jobovy merged 1 commit into
feat/backendsfrom
backend/scf-multipole-construction
Jun 20, 2026
Merged

potential: pin SCF/Multipole construction-time setup to numpy#986
jobovy merged 1 commit into
feat/backendsfrom
backend/scf-multipole-construction

Conversation

@jobovy

@jobovy jobovy commented Jun 20, 2026

Copy link
Copy Markdown
Owner

What

Burndown PR-4 (SCFPotential.py + MultipoleExpansionPotential.py). Constructing SCF/Multipole/DiskSCF/DiskMultipole/KuijkenDubinski potentials ran their pure-numpy coefficient/density-grid quadrature + density-lambda arity autodetect while the forced backend default was torch/jax, so get_namespace(<plain scalar>) returned the backend and torch rejected the mixed ops (numpy.ndarray * Tensor; a swallowed TypeError mis-detecting a Multipole density lambda's arity). Wrap the construction-time numerical setup in with use("numpy", force=True):. This is non-differentiable host setup that builds the stored numpy coefficient tables; evaluation stays backend-aware (the jax/torch eval tables are built lazily, outside the wrap).

Byte-identity + review

numpy byte-identical (forced-numpy is a no-op on the numpy default): 118 stored coefficient/table attributes bit-identical parent vs branch; test_scf/test_MultipoleExpansionPotential/test_amp_mult_divide counts unchanged. Under torch these families now construct and 12 test_amp_mult_divide entries flip to pass; the 3 remaining (expwhole*/nonaxiDiskSCF) fail for the separate Potential.normalize-stores-Tensor central-coercion reason (PR-3b). Adversarially reviewed (byte-identity, eval-path-not-pinned, context-manager exception/nesting safety, no missed/double-wrapped paths — all refuted).

🤖 Generated with Claude Code

Constructing SCF / Multipole / DiskSCF / DiskMultipole / KuijkenDubinski
potentials ran their pure-numpy coefficient/density-grid quadrature and the
density-lambda arity autodetect while the forced backend default was torch/jax,
so get_namespace(<plain numpy/Python scalar>) returned the backend and torch
rejected the mixed ops (`numpy.ndarray * Tensor` in the SCF integrands; a
swallowed TypeError mis-detecting numOfParam -> wrong-arity Multipole density
lambda). Wrap the construction-time numerical setup in
`with use("numpy", force=True):` (scf_compute_coeffs[_axi/_spherical] +
SCFPotential.from_density arity probe; MultipoleExpansionPotential.from_density
rho_lm quadrature/spline build). This is non-differentiable host setup that
builds the stored numpy coefficient tables; evaluation stays backend-aware.

numpy byte-identical (the forced-numpy default is a no-op on the numpy path):
16 stored coefficient arrays (._Acos/._Asin, ._me._Acos/_Asin, multipole spline
tables) bit-identical parent vs branch; test_scf/test_MultipoleExpansionPotential
/test_amp_mult_divide counts unchanged. Under torch these families now construct
successfully and 12 test_amp_mult_divide entries flip to pass; the 3 remaining
(expwhole*/nonaxiDiskSCF) fail for the separate Potential.normalize-stores-Tensor
central-coercion reason, handled by another PR.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.93%. Comparing base (fcad3f7) to head (d02be4c).

Additional details and impacted files
@@              Coverage Diff               @@
##           feat/backends     #986   +/-   ##
==============================================
  Coverage          99.93%   99.93%           
==============================================
  Files                253      253           
  Lines              39803    39810    +7     
  Branches             839      845    +6     
==============================================
+ Hits               39778    39785    +7     
  Misses                25       25           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown
Contributor

All-backend test status (jax / torch)

Commit 5125d1aa871db4f2c37bfa3d5334c50c7d697a75

Green is achieved via the checked-in xfail-ledger (tests/backend_xfail.txt, applied xfail(strict=False)), so the metric to watch is the shrinking xfail count (burndown), not a raw pass count. A FAIL/ERR is an un-ledgered regression (reds the run). Because the ledger is non-strict, a now-passing ledgered test is a plain pass here (no per-push XPASS); burndown candidates -- in both directions -- are surfaced by the scheduled regen run, which rewrites the ledger from real outcomes. deferred is a separate burndown: tests skipped because they are unrunnable under the backend until the port is vectorized (see tests/backend_slow_skip.txt), e.g. the jax spherical-DF sampling/quadrature tests pending the Track F DF migration.

Overall: jax: 1050 passed · 272 xfail · 725 deferred | torch: 782 passed · 1261 xfail · 1 deferred

Ledger size: 2357 entries (jax=284, torch=2073).

Test shard jax torch
actionAngle ✅ 112 pass · 89 xfail ✅ 26 pass · 175 xfail
sphericaldf ✅ 164 pass · 26 xfail · 28 deferred ✅ 8 pass · 210 xfail
conversion + util + misc ✅ 85 pass · 6 xfail · 1 deferred ✅ 41 pass · 51 xfail
potential + scf + multipole — (no result) — (no result)
quantity + coords ✅ 281 pass · 55 xfail ✅ 189 pass · 147 xfail
orbit (energy/Jacobi + from_name) ✅ 0 pass · 0 xfail · 115 deferred ✅ 62 pass · 53 xfail
orbit + orbits (main) ✅ 0 pass · 0 xfail · 578 deferred ✅ 198 pass · 377 xfail
evolveddiskdf ✅ 35 pass · 0 xfail ✅ 32 pass · 3 xfail
jeans + dynamfric ✅ 17 pass · 2 xfail · 2 deferred ✅ 7 pass · 13 xfail · 1 deferred
qdf + pv2qdf + streamgapdf_impulse + noninertial ✅ 57 pass · 75 xfail · 1 deferred ✅ 14 pass · 119 xfail
streamgapdf ✅ 28 pass · 2 xfail ✅ 27 pass · 3 xfail
diskdf ✅ 129 pass · 0 xfail ✅ 112 pass · 17 xfail
streamdf + streamspraydf + streamTrack ✅ 142 pass · 17 xfail ✅ 66 pass · 93 xfail
Per-shard counts
Test shard backend pass xfail deferred XPASS fail error
actionAngle jax 112 89 0 0 0 0
actionAngle torch 26 175 0 0 0 0
sphericaldf jax 164 26 28 0 0 0
sphericaldf torch 8 210 0 0 0 0
conversion + util + misc jax 85 6 1 0 0 0
conversion + util + misc torch 41 51 0 0 0 0
potential + scf + multipole jax
potential + scf + multipole torch
quantity + coords jax 281 55 0 0 0 0
quantity + coords torch 189 147 0 0 0 0
orbit (energy/Jacobi + from_name) jax 0 0 115 0 0 0
orbit (energy/Jacobi + from_name) torch 62 53 0 0 0 0
orbit + orbits (main) jax 0 0 578 0 0 0
orbit + orbits (main) torch 198 377 0 0 0 0
evolveddiskdf jax 35 0 0 0 0 0
evolveddiskdf torch 32 3 0 0 0 0
jeans + dynamfric jax 17 2 2 0 0 0
jeans + dynamfric torch 7 13 1 0 0 0
qdf + pv2qdf + streamgapdf_impulse + noninertial jax 57 75 1 0 0 0
qdf + pv2qdf + streamgapdf_impulse + noninertial torch 14 119 0 0 0 0
streamgapdf jax 28 2 0 0 0 0
streamgapdf torch 27 3 0 0 0 0
diskdf jax 129 0 0 0 0 0
diskdf torch 112 17 0 0 0 0
streamdf + streamspraydf + streamTrack jax 142 17 0 0 0 0
streamdf + streamspraydf + streamTrack torch 66 93 0 0 0 0

@jobovy jobovy merged commit 69659c6 into feat/backends Jun 20, 2026
146 checks passed
@jobovy jobovy deleted the backend/scf-multipole-construction branch June 20, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant