Skip to content

Lay out off-resonance and transmit phase per voxel together on a card - #28

Merged
mcencini merged 1 commit into
mainfrom
cuda-off-axis-buffers
Oct 6, 2026
Merged

mcencini merged 1 commit into
mainfrom
cuda-off-axis-buffers

Conversation

@mcencini

@mcencini mcencini commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

What changed

_prepare_tissue treats B0 and B1_PHASE as one group: when a run declares either, both get a value per voxel.

Why

The CUDA kernels carry both through one launch flag, off_axis (feature_flags), and read both per voxel when either is declared. The tissue buffers, though, narrowed each property to a single value by its own feature. A tissue that gives off-resonance beside a transmit map (or any other per-voxel property), without a transmit phase, then read b1_phase past the end of a one-element buffer, at the voxel stride. The echo phase came back wrong, and it changed with whatever the allocator had left in that block.

It only shows where off-resonance stays in the states, i.e. where the windings are uneven and the analytic dephasing path is off. A spin echo with a spoiler after the echo is enough. The CPU kernel lays everything out and was right throughout.

Found while driving torchsim from the pulserver virtual scanner's Fourier engine, where atoms carry both a field bin and a transmit bin.

Validation

  • New test_one_half_of_the_off_axis_turn_matches_the_cpu_kernel (4 cases). It dirties the allocator's small blocks first, so an over-read reads non-zero values. It fails on main for the two off-resonance-only cases and passes with the change.
  • tests/sequence/test_cuda_parity.py, test_transmit_array.py, test_real_subspace.py, test_flow_kernels.py, test_diffusion_kernels.py, tests/model/test_signal_model.py and tests/optim/test_binding.py pass on an RTX 4060 (231 passed).
  • ruff check and ruff format --check are clean on the touched files.

🤖 Generated with Claude Code

The CUDA kernels carry the two through one launch flag and read both per
voxel when either is declared, while the tissue buffers narrowed each to a
single value by its own feature. A tissue giving off-resonance beside a
transmit map, without a transmit phase, then read the phase past the end of
its buffer: a wrong echo phase that changed with the batch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mcencini
mcencini merged commit 0f9cf2d into main Oct 6, 2026
32 of 36 checks passed
@mcencini
mcencini deleted the cuda-off-axis-buffers branch October 6, 2026 13:25
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