Skip to content

[FlyDSL] gfx950 MXFP8 bmm: grouped XCD tile order, split-K LDS flag only when split - #6440

Closed
andrei-kochin wants to merge 1 commit into
ROCm:mainfrom
andrei-kochin:split/mxfp8-xcd-swizzle
Closed

andrei-kochin wants to merge 1 commit into
ROCm:mainfrom
andrei-kochin:split/mxfp8-xcd-swizzle

Conversation

@andrei-kochin

@andrei-kochin andrei-kochin commented Oct 12, 2026 •

Copy link
Copy Markdown

Motivation

Part 2 of 3 split out of #6060 (author: @sshlyapn), so each PR covers one concern.

The gfx950 FlyDSL MXFP8 bmm's XCD tile order (_xcd, #5896) gives each XCD a contiguous run of tiles, but within that run tiles are N-major, so many B column blocks are live per XCD at once. This PR re-orders the run in M-major groups to improve L2 reuse, and trims an LDS reservation that kept a few large tiles from fitting. It is independent of the 1x32 weight-scale change.

Changes

  • xcd_swizzle (_xcd<g> in kernel names): inside each XCD's contiguous run of tiles
    (xcd_order), tiles are re-ordered M-major in groups of g M tiles, as
    xcd_remap_bx_by does. Fewer B column blocks are live per XCD, so L2 reuse improves.
    • The heuristic for b_direct configs now picks _xcd4 instead of _xcd.
    • Existing _xcd CSV rows parse and run unchanged.
    • xcd_swizzle without xcd_order is rejected by both check_bmm_config and bmm_kernel_name (the digits would otherwise parse back as part of _sk<splits>).
  • LDS: the 16-byte split-K flag is reserved only when K is actually split. This lets a
    few large tiles fit.
  • Tests (test_gemm_group32_interface.py):
    • _xcd4 accuracy with 32x32 scales against a dequantized FP32 reference, including a partial swizzle group (5 M tiles) and a padded grid (12 N tiles).
    • Kernel-name round trip for _xcd / _xcd4, and rejection of a swizzle without _xcd.

Related PRs

Performance (MI355, gfx950, 256 CU), from #6060

Effect of the tile order alone: 15 tuned _xcd4 rows were re-timed with the same config,
changing only the tile order to _xcd (#5896's order) or to no XCD order.

  • _xcd4 vs _xcd: never slower, 0.3-27% faster.
  • _xcd4 vs no XCD order: about equal at M <= 16k (-1% to +5%, one +20% case),
    5-26% faster at M >= 32k.

Protocol: weights rotate between 2 copies; each point is the median of 3 interleaved rounds; every timed config was checked against a dequantized fp32 reference (rel err < 3e-3).

Tests

The kernel code is the XCD/LDS subset of #6060, unchanged. The _xcd4 configs exercised here were validated in #6060 with 1x32 scales; the 32x32 variants of those cases are new in this PR and run in CI on gfx950. black: clean.

…nly when split

- xcd_swizzle (_xcd<g> in kernel names): inside each XCD's contiguous run
  of tiles (xcd_order), re-order tiles M-major in groups of g M tiles, as
  xcd_remap_bx_by does. Fewer B column blocks are live per XCD, so L2
  reuse improves. The b_direct heuristic now picks _xcd4 instead of _xcd.
  Existing _xcd CSV rows parse and run unchanged; xcd_swizzle without
  xcd_order is rejected, since the digits would parse back as _sk.
- LDS: reserve the 16-byte split-K flag only when K is actually split,
  which lets a few large tiles fit.
- Tests: _xcd4 accuracy with 32x32 scales (including a partial swizzle
  group and a padded grid), kernel-name round trip, and the invalid
  xcd_swizzle-without-xcd_order name.

Split out of ROCm#6060.

Signed-off-by: Sergei Shliapnikov <sergei.shliapnikov@amd.com>
Signed-off-by: Andrei Kochin <andrei.kochin@amd.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@andrei-kochin
andrei-kochin requested review from a team and a balanced review from Copilot October 12, 2026 16:07
@github-actions

Copy link
Copy Markdown
Contributor

🏷️ CI Guide

Runs automatically on every PR:

  • ✅ Pre-checks (submodule verification, code formatting)
  • ✅ Aiter op tests (gfx942 + gfx950)
  • ✅ Triton tests on MI35X (only when aiter/ops/triton/** or related paths are changed)

Extended tests (opt-in via labels):

Label Tests
ci:gfx1250-ffm-triton Run the five-shard gfx1250 FFM Triton test suite
ci:triton-300x Run an additional Triton test job on MI300X in PRs (added automatically when gfx942 configs change); main branch always runs both MI35X and MI300X
ci:triton-355 Run the full Triton test suite on MI35X, not only the tests the change affects
ci:windows Windows JIT op smoke test on the gfx1201 ROCm runner
ci:multi-gpu Aiter multi-GPU tests on the 8-GPU runner
ci:sglang SGLang integration tests: DeepSeek-R1-MXFP4 accuracy, Qwen 3.5 accuracy
ci:atom ATOM benchmark: DeepSeek-R1-0528, GPT-OSS-120B
ci:atom_full ATOM accuracy suite for PR and main models from ATOM models_accuracy.json
ci:vllm vLLM benchmark: DeepSeek-V4-Pro, MiniMax-M3-MXFP4
ci:all All standard extended tests (excludes ci:atom_full)

Only add ci:atom_full for FlyDSL or Triton upgrades.
Add labels via the sidebar or gh pr edit 6440 --add-label <label>

One backend per PR:
A PR changes one kernel backend: [Triton/Gluon] (Triton and Gluon count as one), [HIP], [ASM], [CK], [OPUS] or [FlyDSL]. If the title ends up with two backend tags, split the PR -- as stacked pull requests when one part cannot merge without the other.

PR title tags & labels:
Component tags ([Triton/Gluon], [HIP], [CK], [ASM], ...) are added to the PR title and as PR labels automatically from the changed files and re-synced on every push — change-type tags like [fix]/[Perf], op tags like [MLA], and human labels (ci:*) are left untouched. Add the no-auto-title label to stop the title rewrites; labels stay in sync either way.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Split-K configurations accept _xcd<g> but silently bypass the grouped remapping, and the LDS boundary change lacks regression coverage.

2 open findings
What changed in this PR

Adds grouped XCD tile ordering to improve gfx950 MXFP8 BMM cache reuse while reducing non-split LDS usage.

Changes:

  • Adds _xcd<g> parsing, validation, and grouped tile remapping.
  • Reserves the LDS split-K flag only for split launches.
  • Adds swizzle accuracy and kernel-name tests.
File Description
aiter/​ops/​flydsl/​kernels/​bmm_a8w8_mxscale_gfx950.py Implements grouped XCD remapping and conditional LDS allocation.
aiter/​ops/​flydsl/​batched_gemm_a8w8_gfx950.py Extends kernel naming and heuristic selection with _xcd4.
op_tests/​test_gemm_group32_interface.py Tests swizzle correctness, parsing, and validation.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

tile = bid_x % 8 * per_xcd + bid_x // 8
rest = tile // (N // tile_n)
bid_x, bid_y, bid_z = rest % m_tiles, tile % (N // tile_n), rest // m_tiles
if const_expr(xcd_swizzle > 1):
c_rows,
flag_off,
flag_off + 16,
flag_off + (16 if split else 0),
@andrei-kochin

Copy link
Copy Markdown
Author

Opened by mistake against the wrong PR; closing.

@andrei-kochin
andrei-kochin deleted the split/mxfp8-xcd-swizzle branch October 12, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants