Skip to content

fp-cuda: transpose B on the device - #286

Open
JoeyBF wants to merge 1 commit into
SpectralSequences:masterfrom
JoeyBF:fp_cuda_device_transpose
Open

fp-cuda: transpose B on the device#286
JoeyBF wants to merge 1 commit into
SpectralSequences:masterfrom
JoeyBF:fp_cuda_device_transpose

Conversation

@JoeyBF

@JoeyBF JoeyBF commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Closes #285.

transpose_b rearranged B into the kernel's K-major layout one bit at a time on the host, and at
large sizes that cost more than the multiply it fed. transpose_tile_b1_kernel does it on the
device instead: B is uploaded exactly as it stands, and the host does no bit-level work on either
operand. The kernel also supplies the K padding, so that padding costs no host copy either.

matmul_b1_kernel is untouched, and the public signatures are unchanged — fp's dispatch already
passes B row-major, so this PR touches one crate and needs no companion change.

Why on the device

The obvious alternative is to keep the rearrangement on the host but make it fast, which is cheap to
do: with Bᵀ in hand each output tile row is a contiguous limb run, so the tiling becomes a gather,
and #175 gives fp a blocked p = 2 transpose to produce Bᵀ with. That version was built and
benchmarked first. It still loses.

End to end on an H200 NVL, arms interleaved, 5 iterations, medians, each arm paying its own operand
serialization:

n host transpose device transpose speedup
4096 2.59 ms 2.09 ms 1.24×
8192 16.32 ms 11.18 ms 1.46×
16384 127.24 ms 76.93 ms 1.65×
32768 459.54 ms 271.18 ms 1.70×

Reproduced on a second run (1.24 / 1.33 / 1.68 / 1.73×). The margin exceeds the host transpose alone
because the host arm also runs pad_2d and a tiling pass, so the kernel displaces two pieces of host
work rather than one. The host transpose is not slow in isolation — it reaches 7.4–9.4 GB/s while its
working set fits in cache — but at 32768² that set is 128 MiB and it falls to roughly 1.4 GB/s.

Since the device wins at every size the GPU path is used at, there is one entry point rather than
two. Both this and the kernel-optimization decision below are recorded in EXPERIMENTS.md.

Validation, on an H200 NVL

  • matmul_b1_demo passes every shape, including 65×65 * 65×65.
  • The device path was checked against both the CPU product and a host-transposing implementation
    across eight shapes — ragged on each axis independently, spanning multiple K chunks (k = 1025, 2049) and column groups (n = 129, 333).
  • cargo test -p fp --features gpu passes, so gpu_dispatch_matches_cpu and
    gpu_matmul_concurrent cover the dispatched path, including 16 threads multiplying at once.
  • No regression: kernel-only throughput 4064.9 / 6829.3 / 8365.0 / 9571.4 binary TOPS at
    4096 / 8192 / 16384 / 32768, within ~2% of before, and the PTX still emits exactly 12
    wgmma.mma_async.

Deliberately not done

  • The kernel is uncoalesced. Thread bit reads a column of B, so consecutive threads are
    n_lim limbs apart; ncu at 16384² shows 9.94% DRAM throughput against 92.4% on the memory pipes.
    Staging a row-major tile in shared memory would fix it and __ballot_sync would replace the
    64-iteration gather. Neither is worth doing: the kernel runs 113 µs against matmul_b1_kernel's
    1.36 ms inside a 77 ms end-to-end call, so making it free would buy about 0.15%.
  • Parallelising the remaining host passes (fp-cuda: transpose_b dominates end-to-end time at large sizes #285's second suggestion). pad_2d and interleave_a
    are still serial; they are now a smaller share of the total than the transfers.
  • Transfers and allocation, which now dominate. Of that 77 ms call, roughly 20 ms is operand
    serialization, ~1.5 ms is the two kernels, and the remaining ~55 ms is H2D/D2H plus per-call device
    allocation — though pad_2d and interleave_a also rewrite ~33 MB on the host inside
    matmul_b1_inner, so not all of it is PCIe. It wants an nsys timeline before anyone optimizes
    it, and it is the largest single item left.

Relationship to #175

Independent — they share no file, and either can merge first. #175 adds Matrix::transpose, which
was written for the host-transposing version of this change and remains useful on its own merits;
this PR does not use it.

Summary by CodeRabbit

  • Performance

    • Improved CUDA matrix multiplication by moving B-matrix transposition to the device.
    • Reduced host-side preprocessing and data movement overhead.
  • Correctness

    • Ensured unused bits are cleared for matrices whose dimensions are not multiples of 64.
    • Added handling for padded matrix data during GPU processing.
  • Documentation

    • Documented performance findings and the decision to retain the current transposition approach.

`transpose_b` rearranged B into the kernel's K-major layout one bit at a time
on the host, and at large sizes that cost more than the multiply it fed. It is
replaced by `transpose_tile_b1_kernel`: B is uploaded exactly as it stands and
rearranged on the device, so the host does no bit-level work on either operand.
The kernel supplies the K padding too, so that padding costs no host copy.

End to end on an H200 NVL this is 1.24x at 4096 rising to 1.70x at 32768
against transposing on the host, even when the host uses a blocked transpose.
See EXPERIMENTS.md, which also records why the kernel is left uncoalesced: it
runs 113 us against a 1.36 ms matmul, so making it free would buy ~0.15%.

`matmul_b1_kernel` is untouched and the public signatures are unchanged, so
`fp`'s dispatch needs no edit.

The demo built matrices from random limbs, leaving the bits past the last
column set; `Matrix` requires them zero and compares limb-wise. It happened not
to matter before and there is no reason to keep relying on that.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFfXYt9zvAvHWhNHnULe6r
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7e3f4186-9741-4a03-9a71-9477090c2c28

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8c98d830-fab6-48b7-8fe3-d2869dcbf602

📥 Commits

Reviewing files that changed from the base of the PR and between e30727e and 51322e0.

📒 Files selected for processing (4)
  • ext/crates/fp-cuda/EXPERIMENTS.md
  • ext/crates/fp-cuda/cuda_kernels/matmul_b1.cu
  • ext/crates/fp-cuda/examples/matmul_b1_demo.rs
  • ext/crates/fp-cuda/src/lib.rs

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The fp-cuda matmul path now uploads B unchanged and transposes it on the GPU. A new CUDA kernel produces the layout consumed by matmul. Host-side B transposition and padding were removed. Demo data generation now clears unused bits.

Changes

CUDA B transpose

Layer / File(s) Summary
Transpose kernel implementation
ext/crates/fp-cuda/cuda_kernels/matmul_b1.cu
Adds transpose_tile_b1_kernel with guarded shared-memory loads, bit-plane transposition, zero filling, and grouped tile output.
Multiplication pipeline integration
ext/crates/fp-cuda/src/lib.rs
Loads the transpose kernel, uploads B unchanged, allocates a transposed device buffer, launches the transpose, and removes host-side B padding and transpose_b.
Canonical test data and experiment record
ext/crates/fp-cuda/examples/matmul_b1_demo.rs, ext/crates/fp-cuda/EXPERIMENTS.md
Masks unused bits in generated rows and records device-side transpose measurements and implementation decisions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 51322

The device-side transpose is validated across ragged shapes and concurrent GPU dispatches, with reported kernel throughput preserved; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant GpuContext
  participant CUDA_Module
  participant transpose_tile_b1_kernel
  participant matmul_kernel
  GpuContext->>CUDA_Module: load transpose_tile_b1_kernel
  GpuContext->>CUDA_Module: upload B and allocate transposed buffer
  GpuContext->>transpose_tile_b1_kernel: launch B transpose
  transpose_tile_b1_kernel->>matmul_kernel: provide transposed B tile layout
  GpuContext->>matmul_kernel: launch matrix multiplication
Loading

Possibly related PRs

Poem

A rabbit watched B take flight,
From host-side loops to CUDA light.
Bits lined up in tiles so neat,
The matmul kernel found its sheet.
“Hop!” said the hare, “That path is sweet!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses issue #285 by removing host-side B transposition, preserving correctness, and improving end-to-end GPU performance.
Out of Scope Changes check ✅ Passed The changes support the device-side B transposition objective and include related validation and documentation without unrelated scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: moving B transposition from the host to the CUDA device.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JoeyBF

JoeyBF commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

fp-cuda: transpose_b dominates end-to-end time at large sizes

1 participant