prompt: confirm root cause of the numba psf_weighted_data garbage, file the kernel-shift split-out - #257
Merged
Conversation
Records the confirmed diagnosis on the bug prompt: an unguarded out-of-bounds gather in `psf_weighted_data_from`, not the numba codegen/caching issue the prompt led with. Proven by compiling the shipped source under numba `boundscheck=True`. Notes why the inf suspect is unreachable, and what was not verified here (the profiling-harness corruption counters). Files the kernel-shift axis swap found alongside it as its own prompt, per the one-prompt-one-task rule. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013unzp382r79c4BN8g4ckb2
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013unzp382r79c4BN8g4ckb2
`dashboard_refresh.yml` gates pull requests on `draft/**`, so the stale page would have failed CI on the branch rather than self-healing on main. Diff is confined to the new prompt: backlog 145 -> 146, bug 36 -> 37, and its backlog entry. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013unzp382r79c4BN8g4ckb2
Symptom 1 reproduced exactly on the real profiling dataset: pre-fix max abs(psf_weighted_data) = 4.901e300, post-fix 298.312. The bug report's own "2.98e02 on fit #2" matches the post-fix value exactly. Corrects an earlier reading of the mask padding: `apply_mask` does not pad, and the padded blurring mask belongs to the dense convolver, not the sparse numba path — which reads the unpadded (71, 71) array, so 1244 of 3841 pixels gather off the array edge. Also records that the named acceptance probe is a weak detector: the corruption counters read zero both pre-fix and post-fix, because the values an out-of-bounds read returns depend on heap state. The direct max abs(psf_weighted_data) check is the reliable probe. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013unzp382r79c4BN8g4ckb2
github-actions
Bot
deleted the
claude/autoarray-numba-psf-garbage-hfxnjv
branch
August 25, 2026 14:01
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.
Mind-side record for the numba sparse-operator likelihood bug fixed in PyAutoArray#456 (merged).
What changed
draft/bug/autoarray/numba_first_call_garbage_psf_weighted_data.md— records the confirmed root cause, which is not the numba codegen/caching issue the prompt led with.psf_weighted_data_fromgathered the weight map with no bounds check, and numba@jit()does not bounds-check array reads. Any unmasked pixel withinkernel_shape // 2of the array edge read uninitialized heap memory instead of raisingIndexError. Proven by compiling the shipped source unchanged underboundscheck=True.That resolves the puzzle the prompt flagged — the inputs really were identical between call 1 and call 2; the function reads memory outside its inputs.
Symptom 1 reproduced on the euclid dataset
Calling
psf_weighted_data_fromon the real profiling dataset (autolens_profiling,dataset/imaging/euclid, mask radius 3.5", PSF 21x21):max abs(psf_weighted_data)1c33850)The bug report's own numbers were "max abs = 4.8e299 on fit #1, 2.98e02 on fit #2". The post-fix value 298.31 = 2.98e02 matches the report's correct value exactly, and the pre-fix value reproduces the uninitialized-memory scale. 1244 of the 3841 unmasked pixels (32%) gather off the array.
The record also notes that the mask padding does not protect this path:
apply_maskleavesdata.nativeanddata.maskat (71, 71), and onlyderive_mask.blurring_from(allow_padding=True)pads (to (89, 89)) for the dense convolver. The sparse numba path reads the unpadded array, so the mask sits flush against the array edge.The named acceptance probe turns out to be a weak detector
parallel_scaling/pixelization_numba.pywas run at P=2, 24 evals, 2 map repeats, coldNUMBA_CACHE_DIR, both pre-fix and post-fix. Both runs reportedcorrupt_evals_first_map = 0andcorrupt_evals_steady_maps = [0, 0]. That is not evidence of no bug — the values an out-of-bounds read returns are whatever the allocator left next to the weight map, and in that process they were benign. The pre-fix warm-up likelihood still drifted from the post-fix one in the 6th decimal (5860.175003698866 vs 5860.175922117387).The record therefore recommends the deterministic
max abs(psf_weighted_data)comparison as the regression probe instead of those counters, which can read zero on a run where the bug is fully present. Correction also posted on PyAutoArray#456.Other findings recorded
The prompt's second suspect (an
inffrom finite image / zero noise passing theisnanguard) is recorded as unreachable —.nativezeroes both data and noise outside the mask, giving0/0 = NaNevery time. Theisnanguard was left alone rather than widened toisfinite, which would have silently swallowed a genuine bad-noise-map error.draft/bug/autoarray/numba_kernel_shift_axes_swapped.md(new) — a separate defect found while fixing the first. Both numba PSF gathers derive their kernel half-widths from the transposed kernel axes (kernel_shift_yfromshape[1]). Harmless for square kernels; kernels are validated as odd, not square, so a 3x5 PSF mis-centres the gather.Filed rather than fixed inline, per the one-prompt-one-task rule:
psf_precision_value_fromcarries the identical swap, and correcting one without the other would make thepsf_weighted_dataandpsf_precision_operatorpaths disagree about kernel orientation. They need fixing together.dashboard.md/dashboard.html— regenerated.dashboard_refresh.ymlgates pull requests ondraft/**, so a stale page fails the branch rather than self-healing on main. The diff is confined to the new prompt: backlog 145 → 146, bug 36 → 37, and its backlog entry.Checks run locally
scripts/lifecycle.py check→ OKscripts/lifecycle.py index --check→ OKscripts/registry_toc.py --check→ freshintake dashboard --check→ current (after regeneration)pytest tests/→ 159 passedNo registry files (
active.md,active/,complete/) were touched — those stay with$start-devand the ship skills.🤖 Generated with Claude Code
https://claude.ai/code/session_013unzp382r79c4BN8g4ckb2