Skip to content

[FlyDSL] gfx942 a16wi4: pack f32->bf16 with lshr-16 instead of scalar - #5017

Merged
samremes merged 2 commits into
mainfrom
users/msaffari-amd/aiter/gfx942-a16wi4-lshr-pack
Aug 27, 2026
Merged

[FlyDSL] gfx942 a16wi4: pack f32->bf16 with lshr-16 instead of scalar#5017
samremes merged 2 commits into
mainfrom
users/msaffari-amd/aiter/gfx942-a16wi4-lshr-pack

Conversation

@msaffari-amd

Copy link
Copy Markdown
Contributor

Summary

On gfx942, FlyDSL a16wi4 (bf16 × int4) became slower after #4646.
gfx942 has no v_cvt_pk_bf16_f32. The new pipeline fell back to scalar f32.to(bf16) / truncf for the int4 → bf16 upconvert. That path is much more VALU than packing two f32 values into a bf16 pair with lshr 16.
This PR restores that pack for a16wi4 on gfx942 only. Nibble order is unchanged. gfx950 still uses the packed convert. MXFP4 is not touched.

Why it is faster

truncf is ~5 VALU ops per element. The pack is:

  • take the high 16 bits of the first f32 (lshr 16)
  • keep the high 16 bits of the second f32
  • OR them into one i32 = two bf16s
    For scaled int4 this is exact (no extra rounding vs the old truncf fallback).

What changed

  • _int4_nibble_to_bf16x8(..., use_k16=True) — gfx942 pack, not truncf

Perf (convert only, same tile)

MI300X gfx942. a16wi4, SiLU, h=3584, inter=512, E=896, topk=16, ksplit=1. Same gemm1 tile for both: 16×64×128, k_wave=2. CUDA events, 10 warmup + 51 iters. origin/main (truncf) vs this branch (lshr).

tokens truncf gemm1 lshr gemm1 speedup
1 60.5 µs 39.0 µs 1.55×
16 283.5 µs 169.1 µs 1.68×
64 667.6 µs 445.2 µs 1.50×

… truncf

v_cvt_pk_bf16_f32 is gfx950-only. After #4646 the gfx942 int4 fallback used
f32.to(bf16)/truncf, which is much more VALU than the old moe_gemm_2stage
shift-pack. Same nibble order; gfx950 packed convert and MXFP4 are unchanged.
@msaffari-amd
msaffari-amd requested review from a team and a lite review from Copilot August 26, 2026 11:10
@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; main branch always runs both MI35X and MI300X
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: GPT-OSS-120B, DeepSeek-R1-0528, Kimi-K2.5
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 5017 --add-label <label>

PR title tags:
Component tags ([Triton/Gluon], [HIP], [CK], [ASM], ...) are added to the PR title automatically from the changed files and re-synced on every push — change-type tags like [fix]/[Perf] and op tags like [MLA] are left untouched. Add the no-auto-title label to opt this PR out of title tagging.

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.

Pull request overview

Restores a faster gfx942-specific int4→bf16 upconvert path in the FlyDSL a16wi4 (bf16×int4) MOE 2-stage kernels by replacing the scalar f32→bf16 truncation fallback with a high-16-bit pack (lshr 16 + mask/OR). This targets the regression introduced after #4646 by avoiding a VALU-heavy conversion sequence on gfx942 (which lacks v_cvt_pk_bf16_f32).

Changes:

  • Reworked _int4_nibble_to_bf16x8(..., use_k16=True) to generate bf16 pairs by packing the high 16 bits of two f32 bitpatterns, instead of per-element scalar bf16 truncation.
  • Added clarifying comments about the gfx942 packing path and FlyDSL cache-key behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
aiter/ops/flydsl/kernels/moe_2stage_a16wmix/utils.py Implements gfx942-only lshr-16 bf16 packing for int4 upconvert in _int4_nibble_to_bf16x8 and documents the cache-key implication.
aiter/ops/flydsl/kernels/moe_2stage_a16wmix/gemm1.py Adds a note indicating gfx942 weight upconvert uses the lshr-16 pack path in utils.
aiter/ops/flydsl/kernels/moe_2stage_a16wmix/gemm2.py Adds a note indicating gfx942 weight upconvert uses the lshr-16 pack path in utils.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@msaffari-amd
msaffari-amd requested a review from yadaish August 26, 2026 11:13
Comment thread aiter/ops/flydsl/kernels/moe_2stage_a16wmix/gemm1.py Outdated
Comment thread aiter/ops/flydsl/kernels/moe_2stage_a16wmix/gemm2.py Outdated
Comment thread aiter/ops/flydsl/kernels/moe_2stage_a16wmix/utils.py Outdated
Copilot AI review requested due to automatic review settings August 26, 2026 11:35

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@msaffari-amd msaffari-amd changed the title [FlyDSL] gfx942 a16wi4: pack f32->bf16 with lshr-16 instead of scalar… [FlyDSL] gfx942 a16wi4: pack f32->bf16 with lshr-16 instead of scalar Aug 26, 2026
@samremes
samremes merged commit 5715ecb into main Aug 27, 2026
55 checks passed
@samremes
samremes deleted the users/msaffari-amd/aiter/gfx942-a16wi4-lshr-pack branch August 27, 2026 06:38
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.

4 participants