Skip to content

fix: coerce fnnls_cholesky inputs to numpy — JAX ZTx broke the numba buffer kernels - #463

Merged
Jammy2211 merged 1 commit into
mainfrom
claude/wake-up-22piwp
Aug 21, 2026
Merged

fix: coerce fnnls_cholesky inputs to numpy — JAX ZTx broke the numba buffer kernels#463
Jammy2211 merged 1 commit into
mainfrom
claude/wake-up-22piwp

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

What

fnnls_cholesky now coerces ZTZ / ZTx / P_initial to numpy once at the function boundary, with a regression test that feeds it jax.numpy arrays.

Why

The sparse-operator inversion path hands fnnls_cholesky JAX arrays even when the fit itself runs the numba CPU path (PYAUTO_DISABLE_JAX=1). Indexing a JAX array yields another JAX array, which numba maps to a readonly buffer — and the in-place buffer kernels introduced by #453 (_cho_solve_buffer_solve_upper_transposed_buffer) overwrite their vector argument, so kernel compilation fails with Cannot modify readonly array of type: readonly buffer(float64, 1d, C) the first time the solver runs on such input. The scipy solvers #453 replaced tolerated JAX input by copying internally, which is why this never bit before.

Visible failure: HowToLens smoke on main, red since 2026-08-20 22:30 UTC — tutorial_8_adaptive_pixelization and tutorial_11_brightness_adaption (the two tutorials whose fits route through the sparse operator) failed with During: Pass nopython_type_inference on both CI Pythons, 21 minutes after #453 merged (failing run). This is the HowToLens: Smoke Tests failure on main RED that blocked the 2026-08-21 nightly release. Timeline pinned it to #453: no other library merge landed in the pass→fail window and both runs resolved identical dependency versions (numba 0.67.0 / numpy 2.5.2).

With numpy parents, fancy indexing hands every downstream kernel a fresh writeable array, so the in-place contract holds for all callers.

Validation

  • New test__fnnls_cholesky__accepts_jax_arrays (importorskip'd on jax) reproduces the failure without the coercion and passes with it; result cross-checked against the numpy-input solve.
  • test_autoarray/: 1063 passed. (3 test_transformer.py pynufft failures reproduce identically on unmodified main in the validation env — missing [optional] extras — and are unrelated.)
  • End-to-end: HowToLens tutorial_8_adaptive_pixelization + tutorial_11_brightness_adaption pass locally against current library mains with this fix (plus the HowToLens-side mesh-rename API update, PR'd separately).

🤖 Generated with Claude Code

https://claude.ai/code/session_015GsUfbCwPd4XC8kpsiUJp7


Generated by Claude Code

…buffer kernels

The sparse-operator inversion path hands fnnls_cholesky JAX arrays even when
the fit itself runs the numba CPU path. Indexing a JAX array yields another
JAX array, which numba maps to a *readonly* buffer — and the in-place buffer
kernels introduced by #453 (_cho_solve_buffer via
_solve_upper_transposed_buffer) overwrite their vector argument, so kernel
compilation fails with "Cannot modify readonly array" the first time the
solver runs on such input. The scipy solvers #453 replaced tolerated JAX
input by copying internally, which is why this never bit before.

Visible failure: HowToLens smoke on main, red since 2026-08-20 22:30 UTC —
tutorial_8_adaptive_pixelization and tutorial_11_brightness_adaption (the two
tutorials whose fits route through the sparse operator) died with
"During: Pass nopython_type_inference" on both CI Pythons, 21 minutes after
the #453 merge. This RED is what blocked the 2026-08-21 nightly release.

Coerce ZTZ / ZTx / P_initial once at the function boundary: fancy indexing a
numpy parent hands every downstream kernel a fresh writeable array. The new
regression test calls fnnls_cholesky with jnp arrays (importorskip'd) and is
verified to fail without the coercion.

test_autoarray: 1063 passed; the 3 test_transformer pynufft failures
reproduce identically on unmodified main in this environment (missing
[optional] extras) and are unrelated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015GsUfbCwPd4XC8kpsiUJp7
@Jammy2211
Jammy2211 merged commit b808a9b into main Aug 21, 2026
3 checks passed
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.

2 participants