Skip to content

GPU offload for Nassau's Milnor multiply (p = 2)#271

Open
JoeyBF wants to merge 3 commits into
SpectralSequences:masterfrom
JoeyBF:claude/nassau-gpu-refactor-k1ggps
Open

GPU offload for Nassau's Milnor multiply (p = 2)#271
JoeyBF wants to merge 3 commits into
SpectralSequences:masterfrom
JoeyBF:claude/nassau-gpu-refactor-k1ggps

Conversation

@JoeyBF

@JoeyBF JoeyBF commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Reorganized successor to #264: the GPU Milnor-multiply offload, with the benchmark suite (#269, merged) and the seqno index (#270) split out.

Stacked on #270. This PR is based on the seqno branch, so its diff currently shows the seqno commit too. The net-new commit here is the top one, "Add CubeCL GPU offload…". Once #270 merges I'll rebase and the diff will reduce to the GPU commit alone. Review against #270, or just the head commit.

What

Offloads the admissible-matrix Milnor multiply at the heart of Nassau's get_partial_matrix to the GPU via CubeCL, for the p = 2 / trivial-profile regime. Gated behind the gpu feature; cargo check/build need no CUDA toolkit (cudarc dlopens at runtime).

  • milnor_algebra.rs: an admissible-matrix multiply (multiply_basis_element_by_element_2 + AdmissibleMatrix) as the CPU reference model for the kernel, plus the #[cfg(feature = "gpu")] upload helpers. Covered by admissible_multiply_agrees_with_reference.
  • milnor_gpu.rs: the batched CubeCL kernel (multiply_batch_kernel / multiply_batch_on_gpu), fusing every (R, s) product of one matrix build into a single launch, with dedup-by-R, device-resident admissible buffers, and per-launch memory release pinned to one CUDA stream. Single-kernel building blocks used only to validate it live under #[cfg(test)], so the production surface is just multiply_batch_on_gpu + GpuProduct.
  • ext::nassau_gpu + the build_partial_matrix hook in nassau.rs: route the differential-matrix build through the GPU path when compiled in, opted into (NASSAU_GPU), applicable, and large enough to amortise launch overhead; otherwise the CPU path is unchanged.
  • free_module.rs: skip zero generator blocks in act (a general CPU win).
  • Supporting nassau_e2e example, GPU/CPU consistency tests, the milnor_gpu_ab A/B bench, and a gpu dev shell in flake.nix.

Notes vs #264

Dead code and dev-only profiling scaffolding removed; the validation-only kernels moved behind #[cfg(test)]. The env-var dispatch and the process-global GPU context are unchanged (deferred as larger follow-ups).

Test plan

  • cargo test -p algebra (incl. admissible_multiply_agrees_with_reference)
  • cargo test -p ext --features nassau --test milnor_vs_nassau (CPU Nassau correctness)
  • just lint (nightly fmt + clippy, -D warnings) — incl. --all-features (compiles the gpu path via cubecl)
  • GPU-execution tests (tests/nassau_gpu*.rs) require a live CUDA device — not run in CI

🤖 Generated with Claude Code


Generated by Claude Code

Add a flat, arc-swapped `seqno` index for the Milnor basis: an
O(#p-part-entries) rank computed from a precomputed `g` table, with no
hash lookup. This is a general (GPU-agnostic) data structure — it is the
uploadable/on-device index primitive, and an independently benchmarkable
alternative to the basis hashmap.

- `SeqnoTables` + `compute_seqno_tables` (idempotent, concurrency-safe
  via `ArcSwapOption::rcu`) + `seqno` in `milnor_algebra.rs`, applicable
  at p = 2 with a trivial profile and stable ordering.
- The CPU basis index deliberately still uses the hashmap (the tables lose
  to it on the CPU); `compute_basis` does not build them. Documented at
  `try_basis_element_to_index`.
- `benches/seqno.rs`: A/B of the table index against the hashmap.
- Covered by the `seqno_matches_enumeration_order` test.

Split out of the Nassau GPU work as standalone infrastructure.

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

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@JoeyBF, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 30e50a6e-a2a3-4124-bf40-1b0eccd80e1f

📥 Commits

Reviewing files that changed from the base of the PR and between 4867b30 and 31aced0.

📒 Files selected for processing (16)
  • ext/Cargo.toml
  • ext/benches/milnor_gpu_ab.rs
  • ext/crates/algebra/Cargo.toml
  • ext/crates/algebra/benches/seqno.rs
  • ext/crates/algebra/src/algebra/milnor_algebra.rs
  • ext/crates/algebra/src/algebra/milnor_gpu.rs
  • ext/crates/algebra/src/algebra/mod.rs
  • ext/crates/algebra/src/module/free_module.rs
  • ext/examples/nassau_e2e.rs
  • ext/flake.nix
  • ext/src/lib.rs
  • ext/src/nassau.rs
  • ext/src/nassau_gpu.rs
  • ext/tests/nassau_gpu.rs
  • ext/tests/nassau_gpu_reuse.rs
  • ext/tests/nassau_gpu_timing.rs
✨ 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.

claude added 2 commits July 15, 2026 05:14
- `seqno`: add a `debug_assert` that the element's degree is within the loaded
  table's `max_degree`, so a not-built-far-enough call fails with a clear
  diagnostic instead of a raw slice out-of-bounds panic.
- `seqno_matches_enumeration_order`: build the tables partially, rebuild
  identically (no-op), grow, then request a smaller degree — exercising the
  idempotent, monotonic (non-shrinking) publish documented on
  `compute_seqno_tables`, not just a single build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UPYvsLdEfitgCbAiPxxx3U
Offload the admissible-matrix Milnor multiply at the heart of Nassau's
`get_partial_matrix` to the GPU via CubeCL, for the p = 2 / trivial-profile
regime. Gated behind the `gpu` feature; `cargo check`/`build` need no CUDA
toolkit (cudarc dlopens at runtime).

- `milnor_algebra.rs`: an admissible-matrix multiply
  (`multiply_basis_element_by_element_2` + `AdmissibleMatrix`) as the CPU
  reference model for the kernel, plus the `#[cfg(feature = "gpu")]` upload
  helpers (`admissible_matrices`, `seqno_table_u32`, `gpu_multiply_applicable`).
  Covered by `admissible_multiply_agrees_with_reference`.
- `milnor_gpu.rs`: the batched CubeCL kernel (`multiply_batch_kernel` /
  `multiply_batch_on_gpu`), fusing every `(R, s)` product of one matrix build
  into a single launch, with dedup-by-`R`, device-resident admissible buffers,
  and per-launch memory release pinned to one CUDA stream. The single-kernel
  building blocks used only to validate it live under `#[cfg(test)]`, so the
  production surface is just `multiply_batch_on_gpu` + `GpuProduct`.
- `ext::nassau_gpu` + the `build_partial_matrix` hook in `nassau.rs`: route the
  differential-matrix build through the GPU path when compiled in, opted into
  (`NASSAU_GPU`), applicable, and large enough to amortise launch overhead;
  otherwise the CPU path is used unchanged.
- `free_module.rs`: skip zero generator blocks in `act` (a general CPU win).
- Supporting `nassau_e2e` example, GPU/CPU consistency tests, the
  `milnor_gpu_ab` A/B bench, and a `gpu` dev shell in `flake.nix`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UPYvsLdEfitgCbAiPxxx3U
@JoeyBF
JoeyBF force-pushed the claude/nassau-gpu-refactor-k1ggps branch from 7824e7d to 31aced0 Compare July 15, 2026 05:14
JoeyBF added a commit to JoeyBF/sseq that referenced this pull request Jul 18, 2026
…Sequences#272's restricted graph

PR SpectralSequences#272's restricted_partial_matrix (degree-bounded columns) had displaced
PR SpectralSequences#271's GPU partial-matrix offload and cross-signature row-reuse. Add a
restricted GPU variant (get_partial_matrix_restricted[_verified]) that keeps the
batched Milnor multiply but sizes output to the frozen prefix and masks bits
beyond it, dispatch to it from restricted_partial_matrix_maybe_gpu, and restore
row-reuse (one full restricted matrix per bidegree, select_rows per signature).

Verified GPU==CPU on H200 NVL (CUDA 12.4): nassau_gpu (14230 rows / 527
bidegrees) and milnor_vs_nassau (9 tests) pass with NASSAU_GPU_VERIFY=1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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