Repository navigation
Conversation
- Add 6-argument Stream-K operator() overload on GemmPipelineAgBgCrCompTDMV3 forwarding to the 6-argument tuple operator() overload, and allow comp_tdm_v3 in StreamKKernel alongside comp_tdm and comp_tdm_v2. - Fix StreamKReductionOps::MakePartialsDistribution() for multi-block warp tiles (such as 32x32x128 8-bit WMMA on gfx1250 where kAMBlock = 2, kBNBlock = 2) by dividing WarpGemm::kM and WarpGemm::kN by kAMBlock and kBNBlock. - Fuse partial tile load and accumulation in StreamKReductionOps::AddBlockTile and move the Tree reduction epilogue / StorePartial exit out of the partner accumulation loop in StreamKKernel so 16-wave 256x256x256 fp8/bf8 comp_tdm_v3 Stream-K kernels compile within the 256-VGPR budget with zero spills and zero scratch. - Add test_gemm_streamk_tdm_v3_gfx1250_wmma.cpp and zero-spill resource checks to test_ck_tile_streamk_gfx1250_wmma and test_ck_tile_streamk_gfx1250_wmma_smoke. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5feca364-503f-427f-b262-c067a35fa592
- PartialTileLoader carries only the partials window: its conversion to a C-distributed tile was unused, since both callers pass the loader to AddBlockTile. - Keep the tile + tile AddBlockTile as on develop (no caller changed it). - Name the scheduling-barrier group size and document why the partial adds are fused into the loads; document the Tree loop. - Drop a PR number from a test comment; the resource-check script header now names both users; CHANGELOG wording matches the other entries. No device code change intended.
Moving the epilogue and the partial store out of the tree loop makes the gfx950 tree kernels spill heavily (test_ck_tile_streamk_tree_smoke: 252 -> 11138 VGPR spills) and slows Stream-K tree reduction on gfx950 by 30% (geomean of 24 shapes; up to 43%). With the develop loop and the fused partial add kept, tree reduction on gfx950 is 34% faster than develop, and every comp_tdm_v3 Stream-K kernel on gfx1250 still uses no scratch and no spills.
⏳ Waiting on Required Checks⏳ Required checks have not all concluded yet. This bot run is exiting without failing so those checks can report independently.
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
⏳ Waiting for required checks to start or finish:
|
This branch has not been deployed
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.
Stacked on #15083 (Stream-K on comp_tdm and comp_tdm_v2), so the diff below includes it until #15083 merges. Only the top commits belong to this PR. It builds on #15005 (comp_tdm_v3 bf16/fp16), which is in
develop. This is the comp_tdm_v3 item from the follow-up list in #15083.Motivation
After #15083, gfx1250 Stream-K runs comp_tdm and comp_tdm_v2, but not comp_tdm_v3, the 16-wave TDM pipeline.
StreamKKernelrejected it because it setskPlainGemmOnly, and it had no Stream-K call form. Enabling it exposed two problems in the shared Stream-K reduction code (streamk_common.hpp):MakePartialsDistribution()assumed one WMMA instruction per warp tile. The 8-bit comp_tdm_v3 warp tile is 32x32x128 (kAMBlock = kBNBlock = 2, four 16x16 instructions), so the partials distribution did not match the accumulator's thread buffer.LoadPartialloaded a second full tile, and only then didAddBlockTileadd it.Changes
Pipeline (
gemm_pipeline_ag_bg_cr_comp_tdm_v3.hpp)operator()(a_window, b_window, num_loop, has_hot_loop, tail_number, p_smem)for non-tuple windows. It forwards to the tuple form, the same as comp_tdm and comp_tdm_v2 in feat(ck-tile): enable gfx1250 Stream-K on the comp_tdm and comp_tdm_v2 pipelines #15083. V3 restates it because itsoperator()overloads hide V1's.kPlainGemmOnlycomment now names the Stream-K kernel too. Multi-D, grouped and batched-contraction still reject the pipeline.Kernel (
streamk_gemm_kernel.hpp)kIsPlainGemmOnlyPipelinestatic_assert. comp_tdm_v3 is the only pipeline that sets the flag.kIsCompTdmPipelinealready covers comp_tdm_v3 (TDM, not wavelet). So V3 gets the same CShuffle/TDM epilogue and row-major C checks as comp_tdm and comp_tdm_v2. V3 drains its last prefetch before returning, so the TDM wait after a partial tile does nothing for it.Shared Stream-K reduction (
streamk_common.hpp)MakePartialsDistribution()uses the per-instruction warp size,WarpGemm::kM / kAMBlockandWarpGemm::kN / kBNBlock. For warp tiles withkAMBlock = kBNBlock = 1(every MFMA and 16-bit WMMA tile that the Stream-K tests and examples use) this is the old formula.LoadPartialreturns aPartialTileLoader, which holds the partials window.AddBlockTile(tile, loader)adds each element as it is loaded, with asched_barrierevery 32 elements so that the compiler does not issue all loads first. No second full tile is held in VGPRs.This file is also used by the Stream-K GEMM on gfx90a/gfx942/gfx950/gfx11/gfx12 and by grouped conv backward-weight Stream-K. See "Effect on existing kernels".
Tests and CMake
test_gemm_streamk_tdm_v3_gfx1250_wmma.cppgoes intotest_ck_tile_streamk_gfx1250_wmma(REGRESSION_TESTS) and_smoke, but not_legacy, the same as the comp_tdm suite. It has 40 typed configs (8 in smoke) plus edge cases:-mllvm -enable-post-misched=1, the same as the comp_tdm_v3 GEMM tests.check_comp_tdm_v3_resources.cmake(from feat(ck-tile): comp_tdm_v3 bf16/fp16 GEMM on gfx1250 #15005) is now also registered for both Stream-K binaries. It fails if any CompTDMV3 kernel uses scratch or spills VGPRs.Validation
Resource checks (no scratch, no VGPR spills):
test_ck_tile_streamk_gfx1250_wmma_comp_tdm_v3_resources: 50 kernels. The 16-wave 256x256x256 fp8/bf8 linear and tree kernels use 251 VGPRs.test_ck_tile_streamk_gfx1250_wmma_smoke_comp_tdm_v3_resources: 10 kernels.test_ck_tile_gemm_pipeline_comp_tdm_v3_resources: 9 kernels._bf16_resources: 14 kernels.gfx1250 B0 board (asicRevision 1, ROCm 10.2), at the head of this PR, with
BUILD_DEV=Onand-Werror(0 warnings):test_ck_tile_streamk_gfx1250_wmma: 423/423 (379 from feat(ck-tile): enable gfx1250 Stream-K on the comp_tdm and comp_tdm_v2 pipelines #15083 + 44 new)._smoke: 43/43._legacy: 91/91.--gtest_repeat=3: 132/132.Before the tree-loop change (see the end), I also ran these on an A0 board, with the same counts. On both boards I ran
test_ck_tile_gemm_pipeline_comp_tdm_v3_wmma66/66,_bf16_wmma84/84 and_unaligned_mnk_wmma115/115.gfx1250 emulator (Jenkins smoke path):
ctest -L SMOKE_TEST -R streamk: 2/2 (_smoke43/43 plus its resource check).Effect on existing kernels
The shared reduction change reaches other architectures. I checked gfx950 (MI350X, ROCm 7.1), comparing #15083's head against this PR.
Device ISA:
test_ck_tile_streamk_regressionandtest_ck_tile_streamk_tile_partitioner.Tests, all passing:
test_ck_tile_grouped_conv_bwd_weight_streamk: 30.Performance:
40_streamk_gemmexample; fp16 and bf16; persistent and non-persistent; M x N x K = 256x256x65536, 512x512x16384, 1024x1024x8192, 2048x2048x4096, 3840x4096x4096 and 4096x4096x8192. Base and PR are interleaved; each value is the median of 3 rounds of 50 warmup + 100 timed runs.The example only offers atomic and linear, so for tree I built it with
StreamKReductionStrategy::Tree. The tree gain is largest on small M x N with long K, where most of the time goes into the reduction. Large tiles (4096x4096x8192) are unchanged.An earlier revision of this PR also moved the tree epilogue and partial store out of the partner loop. On gfx950 that raised tree-kernel VGPR spills from 252 to 11,138 (
tree_smoke) and made tree reduction 30% slower (geomean, down to -43%). Without it, comp_tdm_v3 is still spill-free, so the tree loop is the same as indevelop.