Repository navigation
Conversation
yuweih205
marked this pull request as ready for review
September 30, 2026 07:56
yuweih205
force-pushed
the
perf/sm90-gathered-bf16
branch
from
October 17, 2026 08:10
2c15049 to
ca1291f
Compare
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.
Routed BF16 forward paths currently materialize
a.index_select(0, rows)before grouped GEMM. This addsm_grouped_bf16_gemm_nt_contiguous_gathered(a, b, d, grouped_layout, a_row_indices)on SM90, loading A through row indices directly into the existing WGMMA pipeline.The first version supports K-major BF16, K divisible by 64, contiguous weights, 128-row expert alignment and an int64 CUDA row map. A may have a padded row stride. The A loader uses 16-byte
cp.asynccopies with the existing shared-memory swizzle; B/output retain TMA. It does not add a fused SwiGLU epilogue or change default dispatch.Current revision
Commit
ca1291f7cd2dbe483af7d89f033b2a5a1e96ca1f, based on main1fc9c66975ee322d628b3288534ca0e9ce12a64d, keeps the change in six existing files:csrc/apis/gemm.hpp; configuration, TMA descriptors and launch in the existing SM90 implementation header.tests/test_bf16.py, rather than a separate gathered test file. It covers three generated configurations, six boundary cases and three rejected invalid inputs.The native extension was forcibly rebuilt from this exact source and the focused gathered test passed on the original H200/SM90 stack: PyTorch
2.13.0+cu132, CUDA runtime 13.2, seed 42, strict deterministic algorithms and uninitialized-memory filling disabled. All generated results are checked bitwise against the materialized path. Both paths use CUDA events in the integrated test, but those printed timings are not a new controlled performance result.This is build/numerical/boundary validation, not a rerun of the historical full integration, sanitizer or performance studies below.
Earlier 2.8.1 measurements
The following results were collected against the 2.8.1 release, #462 (
057ca5964aae0879ff2e0eb71ee05a3cb0ba3df7), at PR commit0ff99780929827f24f19d5e67a10c390c5f77592.On eight H200s, against activation gather + the existing GEMM with prepacked gate/up weights + the same fused output-compaction/SwiGLU kernel:
Eager numbers are median per-GPU ABBA/BAAB reductions; Graph is one GPU. The general eager sweep uses random routes with replacement, while Graph uses source-ordered unique routes; only the explicitly source-ordered rows compare matching routes across modes. Workers and process repeats reuse seed 42. An additional same-GPU, matching-row-map test at R=8192/M=16384 measures 6.25% eager / 6.01% Graph. The small R=1024, M=512, D=F=256 case measures 26.07% eager but regresses 2.31% under Graph, on matching routes. This is a fixed-route forward benchmark, not a full-model speedup.
All tested h/gate/up outputs match both existing-library baselines bitwise. API tests cover partial/empty M, empty experts, source/output stride, aligned offsets and misaligned pointer rejection. An additional 79-case regression covers existing BF16 GEMM/einsum layouts, output dtypes and accumulation modes using exact references and bytewise repeats. Independent FP32 reference checks pass; compute-sanitizer memcheck reports 0 errors. The full 13-phase 2.8.1 run passed, including live EP8 integration and receive-view lifetime checks; combined forward reductions are 16.99%–17.59% across two runs when both this change and DeepEP #769 are enabled.
2.8.1 reproducer, raw cycles, source hashes and limitations. These measurements retain their original test revision and predate the current reorganization; this update makes no additional performance claim. The earlier 2.8.0 measurements remain separately preserved in the same Gist.
Before this reorganization, the PR test scripts also passed a separate eight-H200 correctness rerun against the frozen production-equivalent runtimes. That DeepEP test revision checked an independent input/route oracle, raw deterministic order and two delayed consumer streams under both record-stream policies. Exact test revisions and retained test-development failures.