Skip to content

[HIP] [CI] [JIT] Add aiter.mqa_logits with a tuned Triton/FlyDSL table - #6185

Merged
vgokhale merged 9 commits into
ROCm:mainfrom
amd-sriram:rocm/mqa-logits-dispatch
Nov 5, 2026
Merged

vgokhale merged 9 commits into
ROCm:mainfrom
amd-sriram:rocm/mqa-logits-dispatch

Conversation

@amd-sriram

@amd-sriram amd-sriram commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

vLLM's sparse indexer prefill calls the Triton/Gluon fp8_mqa_logits directly on gfx950. Moving it to the FlyDSL kernel from #4538 took a vLLM PR (vllm-project/vllm#59280), and so would every later switch. Like aiter.paged_mqa_logits for decode (#6140), this adds aiter.mqa_logits: the framework asks for MQA logits, and AITER picks the backend and FlyDSL variant from a tuned table, the way fused_moe does. The vLLM side is vllm-project/vllm#60294.

What it adds

  • mqa_logits(Q, KV, kv_scales, weights, cu_starts, cu_ends, clean_logits=True): takes the same tensors as fp8_mqa_logits and returns the same [seq_len, seq_len_kv] logits.
  • A tuned table keyed on (gfx, cu_num, heads, head_dim, seq_len, seq_len_kv). Both lengths are tensor sizes, so the lookup never reads device memory. A call uses the row with the largest tuned seq_len_kv not above its own, then the largest tuned seq_len not above its own; a length below every tuned one uses the smallest. Rows are looked up with the live GPU arch (get_gfx_runtime()).
  • Each row picks triton (the existing fp8_mqa_logits, Gluon on gfx950) or flydsl with a variant from KERNEL_VARIANTS.
  • A tuner. It checks every candidate against a torch reference before timing it, then re-times the three fastest interleaved and keeps the best median.
  • gfx950 rows for the GLM-5 indexer (H=32, D=128): 24 shapes, seq_len 256 to 8192 and seq_len_kv 4096 to 60000, limited to what vLLM produces (seq_len <= seq_len_kv, logits within the default 512 MB VLLM_SPARSE_INDEXER_MAX_LOGITS_MB).

Without a matching row it runs fp8_mqa_logits, so an empty table changes nothing. A FlyDSL row is only used where the kernel can run (gfx942/gfx950, the variant exists, native e4m3fn on gfx950); otherwise the call runs fp8_mqa_logits.

The CSVs are named like fused MoE's (tuned_mqa_logits.csv, model_configs/glm5_tuned_mqa_logits.csv). A mqa_logits_tuned name would also match paged_mqa_logits_tuned_*.csv in the model_configs glob.

Test Result

MI355X (gfx950), AITER 1a37aa008 with this change applied, Triton 3.8.0, FlyDSL 0.3.4.1.

  • FlyDSL wins all 24 shapes, mostly with mfma32x32x64_bkv128_r2_w4_lds3 (13 of 24).
  • Against Triton/Gluon, what vLLM runs on gfx950 today: -36.6% geomean, from -16.6% to -74.5%.
  • Against FlyDSL's built-in variant choice (what [ROCm][Perf] gfx950: use FlyDSL fp8 MQA logits kernel for the sparse indexer prefill vllm-project/vllm#59280 uses): -5.8% geomean, from -15.4% to +3.3%. Below about 40 us the run-to-run spread is about 10%, so those rows are close to noise.
  • Every candidate matches torch (exact -inf mask, calc_diff < 1e-3); none was rejected.
  • op_tests/test_mqa_logits.py passes, including the live-GPU lookup check (child process started with the other arch in GPU_ARCHS), the dispatched-config check and the FlyDSL fallback.
  • --run_config: 24/24 within 10% on one pass, 22/24 on a second (the two smallest kernels, about 20 and 40 us, at +12%). Collision guard: OK.
  • With GPU_ARCHS naming another arch, the FlyDSL module builds its variant list for that arch at import, so a gfx950 FlyDSL row falls back to fp8_mqa_logits instead of failing.
  • Not measured end to end.
python3 csrc/mqa_logits/mqa_logits_tune.py \
    -i aiter/configs/model_configs/glm5_untuned_mqa_logits.csv \
    -o aiter/configs/model_configs/glm5_tuned_mqa_logits.csv
python3 csrc/mqa_logits/mqa_logits_tune.py --run_config aiter/configs/model_configs/glm5_tuned_mqa_logits.csv
python3 op_tests/test_mqa_logits.py
python3 -m unittest op_tests.tuning_tests.test_config_shape_collision.TestConfigShapeCollision.test_mqa_logits
All 24 shapes (us, single sweep timings; FlyDSL auto = the variant flydsl_fp8_mqa_logits picks by itself)
seq_len seq_len_kv Triton/Gluon FlyDSL auto picked variant picked vs Triton/Gluon vs FlyDSL auto
256 4096 45.9 21.2 mfma32x32x64_bkv64_r1_w2_lds2 18.4 -59.9% -13.2%
1024 4096 60.2 38.8 mfma32x32x64_bkv64_r2_w2_lds3 38.8 -35.5% +0.0%
2048 4096 80.2 54.2 mfma32x32x64_bkv128_r2_w4_lds3 56.0 -30.2% +3.3%
4096 4096 95.1 70.2 mfma32x32x64_bkv128_r2_w4_lds3 67.2 -29.3% -4.2%
256 8192 76.5 30.0 mfma32x32x64_bkv64_r2_w2_lds2 29.0 -62.1% -3.4%
1024 8192 108.5 67.5 mfma32x32x64_bkv128_r2_w4_lds3 62.7 -42.2% -7.2%
2048 8192 145.8 103.9 mfma32x32x64_bkv64_r2_w4_lds3 98.9 -32.1% -4.8%
4096 8192 212.7 161.2 mfma32x32x64_bkv128_r2_w4_lds3 161.1 -24.3% -0.1%
8192 8192 271.9 204.3 mfma32x32x64_bkv64_r2_w4_lds3 204.3 -24.9% +0.0%
256 16384 147.8 44.5 mfma32x32x64_bkv128_r2_w4_lds3 37.7 -74.5% -15.4%
1024 16384 200.4 111.8 mfma32x32x64_bkv64_r2_w4_lds3 111.7 -44.2% -0.1%
2048 16384 271.2 209.9 mfma32x32x64_bkv128_r2_w4_lds3 199.7 -26.4% -4.8%
4096 16384 440.0 376.1 mfma32x32x64_bkv128_r2_w4_lds3 345.0 -21.6% -8.3%
8192 16384 668.9 592.8 mfma32x32x64_bkv128_r2_w4_lds3 557.1 -16.7% -6.0%
256 32768 140.9 69.0 mfma32x32x64_bkv128_r2_w4_lds3 62.2 -55.9% -9.9%
1024 32768 288.1 218.3 mfma32x32x64_bkv128_r2_w4_lds3 207.9 -27.8% -4.8%
2048 32768 514.1 417.4 mfma32x32x64_bkv128_r2_w4_lds3 380.6 -26.0% -8.8%
4096 32768 826.0 778.4 mfma32x32x64_bkv128_r2_w4_lds2 689.1 -16.6% -11.5%
256 49152 150.1 88.7 mfma32x32x64_bkv64_r2_w4_lds3 89.1 -40.6% +0.4%
1024 49152 400.4 318.1 mfma32x32x64_bkv128_r2_w4_lds3 297.6 -25.7% -6.4%
2048 49152 698.0 611.3 mfma32x32x64_bkv128_r2_w4_lds2 557.8 -20.1% -8.8%
256 60000 193.2 112.3 mfma32x32x64_bkv64_r2_w4_lds3 109.0 -43.6% -2.9%
1024 60000 476.2 398.8 mfma32x32x64_bkv128_r2_w4_lds3 359.7 -24.5% -9.8%
2048 60000 820.6 740.6 mfma32x32x64_bkv128_r2_w4_lds2 661.0 -19.4% -10.8%

PR Self-Review

Reviewed revision

3d33634

Behavior and intent

Adds a new entry point, aiter.mqa_logits, for the sparse-indexer prefill. Today vLLM calls the Triton/Gluon fp8_mqa_logits directly, so every move to a faster kernel (such as the FlyDSL one) needs a vLLM PR. With this, AITER picks Triton or a FlyDSL variant per shape from a tuned table, the way fused_moe does. No existing op changes behavior: without a matching row, or when FlyDSL cannot run the row, the call runs fp8_mqa_logits as before. Strided kv_scales, cu_starts or cu_ends raise ValueError (neither backend reads their strides); a strided weights runs on Triton. The tuning CI workflow also learns the new tuner and uploads aiter/configs/model_configs/*.csv.

Validation and unverified scope

MI355X (gfx950, 256 CUs):

  • Tuner on 1a37aa0 + this change (FlyDSL 0.3.4.1, Triton 3.8.0): every candidate matched the torch reference (same -inf mask, calc_diff < 1e-3); FlyDSL won all 24 shapes, -36.6% geomean vs Triton/Gluon (table above).
  • python3 csrc/mqa_logits/mqa_logits_tune.py --run_config ...: 24/24 within 10% on one pass, 22/24 on a second (two kernels under 40 us at +12%).
  • python3 op_tests/test_mqa_logits.py passed at b8a6af0, including the strided-operand checks.
  • python3 -m unittest op_tests.tuning_tests.test_config_shape_collision.TestConfigShapeCollision.test_mqa_logits: passed.

Unverified: 3d33634 only changes the expectation in check_dispatches_shipped_row and has not been run on a GPU yet (CI will run it). Not measured end to end in vLLM (that is vllm-project/vllm#60294). Not run on gfx942 or with the pinned FlyDSL 0.4.x. The tuning workflow change was not dispatched.

PR-specific question

operators-tuning.yaml is workflow_dispatch only, so it never runs on a pull request; only a maintainer with write access can start it, on a branch of ROCm/aiter, and fork PR code or text cannot trigger it. This PR adds no permissions, secrets or new inputs. It adds one fixed line to the tune_jobs list in op_tune.sh (a static command for the new tuner, no interpolated input) and one more path, aiter/configs/model_configs/*.csv, to the existing upload-artifact step, which keeps its 7-day retention.

Changed op tests

  • op_tests/test_mqa_logits.py (new): checks mqa_logits, Triton and FlyDSL (its built-in variant choice) against a torch reference on the default shapes; that the table lookup uses the live GPU (child process with another arch in GPU_ARCHS); that the shipped FlyDSL row is the config dispatched, or Triton when FlyDSL cannot run it; the FlyDSL-to-Triton fallback; and strided operands (strided weights match the reference, strided kv_scales raises). No other test covers aiter.mqa_logits.
  • op_tests/tuning_tests/test_config_shape_collision.py (+4): adds the tuned_mqa_logits family to the duplicate-key check across configs/ and model_configs/, which every other tuned family already has.
  • op_tests/tuning_tests/test_run_config.py (+9): adds the mqa_logits tuner to the shipped-row re-timing test, the same check every other tuner family has.

Picks the FP8 MQA logits backend and FlyDSL variant per shape from
tuned_mqa_logits.csv. Adds the tuner, op test and gfx950 GLM-5 rows.
@amd-sriram
amd-sriram requested review from a team and a balanced review from Copilot October 6, 2026 19:56
@github-actions github-actions Bot changed the title [Triton][FlyDSL] Add aiter.mqa_logits with a tuned Triton/FlyDSL table [HIP] [CI] [JIT] Add aiter.mqa_logits with a tuned Triton/FlyDSL table Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026

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
multigpu 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: 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 6185 --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.

Copilot review overview

🔵 Needs a closer look

Architecture-specific GPU dispatch and performance claims require final human review with head-matched gfx950 validation.

Review effort: Balanced
Findings: None

What changed in this PR

Adds tuned MQA-logits dispatch for vLLM’s gfx950 sparse-indexer prefill path.

Changes:

  • Adds Triton/FlyDSL backend selection with safe fallback.
  • Adds a correctness-aware tuner and 24 GLM-5 configurations.
  • Integrates GPU tests, tuning CI, and collision checks.
File Description
aiter/​mqa_logits.py Implements tuned runtime dispatch.
aiter/​jit/​core.py Registers MQA-logits configuration resolution.
csrc/​mqa_logits/​mqa_logits_tune.py Adds correctness and performance tuning.
op_tests/​test_mqa_logits.py Tests correctness, dispatch, and fallback.
op_tests/​tuning_tests/​test_run_config.py Validates shipped configurations.
op_tests/​tuning_tests/​test_config_shape_collision.py Checks configuration-key collisions.
.github/​scripts/​op_tune.sh Adds tuning CI integration.
aiter/​configs/​untuned_mqa_logits.csv Defines the generic input schema.
aiter/​configs/​tuned_mqa_logits.csv Defines the generic result schema.
aiter/​configs/​model_configs/​glm5_untuned_mqa_logits.csv Lists GLM-5 tuning shapes.
aiter/​configs/​model_configs/​glm5_tuned_mqa_logits.csv Supplies tuned gfx950 variants.

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

Copilot AI balanced review requested due to automatic review settings October 6, 2026 20:51

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.

Copilot review overview

🔵 Needs a closer look

FlyDSL compatibility checking can select a head-count-incompatible variant and raise instead of falling back to Triton.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Validate variant head-count compatibility before custom kernel dispatch

aiter/​mqa_logits.py:121

KERNEL_VARIANTS membership does not prove that a variant supports this head count. On gfx950 the registered MFMA_M=32 variants reject heads=16 in fp8_mqa_logits_kernels.py:409-420, so a custom tuned row for H=16 passes this predicate and then raises instead of taking the documented Triton fallback. Include the selected variant's head-count compatibility in this support check.

Comment thread aiter/mqa_logits.py Resolved
State the contract here instead of pointing at the Triton/Gluon kernel;
each backend accepts these inputs.
Copilot AI balanced review requested due to automatic review settings October 14, 2026 17:26

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.

🔵 Needs a closer look

Strided-weight correctness, fallback expectations, tuner failure reporting, and CI artifact retention need corrections.

0 open findings

Previously missed (4)

In code that hasn't changed since last review

Medium severity Upload generated model configuration CSVs in CI

.github/​scripts/​op_tune.sh:22

This job writes results under aiter/configs/model_configs/, but .github/workflows/operators-tuning.yaml:116 uploads only aiter/configs/*.csv. The generated MQA table is therefore missing from the downloadable tuned-csvs artifact. Add aiter/configs/model_configs/*.csv to the workflow's upload paths so CI retains these results.

Medium severity Make strided weights contiguous before FlyDSL dispatch

aiter/​mqa_logits.py:161

Strided weights are passed unchanged to FlyDSL. For the shipped gfx950 row with 256 queries and 32 heads, weights = base[:, ::2] from a [256, 64] tensor is valid for Triton's stride-aware loads. However, FlyDSL's _load_row_weights uses row * H + head, and its wrapper only reshapes weights; this reads the wrong values. Make weights contiguous before the FlyDSL call to preserve the existing input contract.

Medium severity Exit nonzero when tuning errors or interruptions occur

csrc/​mqa_logits/​mqa_logits_tune.py:282

Tuning errors can exit successfully here. If input/reference creation or finalist re-timing raises, TunerCommon.run catches the exception and calls tune_summary("Error") without adding a row to self.failed. This condition then returns normally, allowing CI to report incomplete tuning as successful. Exit nonzero for an error or interruption as well as recorded candidate failures.

Medium severity Update operator expectation for FlyDSL fallback configurations

op_tests/​test_mqa_logits.py:194

On a gfx950 GPU with 256 CUs, the shipped table selects FlyDSL even when that optional dependency is unavailable or its variant registry was built for another GPU_ARCHS value. The dispatcher correctly falls back to DEFAULT_CONFIG, but this assertion still expects the FlyDSL row, so the operator test rejects a supported fallback configuration. Adjust the expected dispatched config using flydsl_supports; keep the separate table-lookup check unchanged.

🧠 Review effort: Balanced

@zufayu
zufayu requested review from coderfeli and removed request for amd-ruitang3 October 15, 2026 08:48
@zufayu zufayu assigned coderfeli and unassigned amd-ruitang3 Oct 15, 2026

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

Strided-weight handling can change logits, aborted tuning can report success, and model-specific tuning output is excluded from CI artifacts.

3 open issues

Review effort: Balanced

Comment thread aiter/mqa_logits.py Resolved
Comment thread .github/scripts/op_tune.sh Resolved
Comment thread csrc/mqa_logits/mqa_logits_tune.py Resolved
TunerCommon.run() catches the exception and calls tune_summary with status Error or Interrupted. With no failed row recorded, the script exited 0 and op_tune.sh reported a pass.
The mqa_logits job writes aiter/configs/model_configs/glm5_tuned_mqa_logits.csv, which aiter/configs/*.csv does not match.
Copilot AI balanced review requested due to automatic review settings October 24, 2026 09:36

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.

🔵 Needs a closer look

The shipped-row test rejects valid Triton fallback behavior when FlyDSL is unavailable or its variant registry is incompatible.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Allow fallback backend in shipped-row check

op_tests/​test_mqa_logits.py:194

[P2] Allow the shipped-row check to expect a valid backend fallback. On gfx950 with 256 CUs, this assertion fails when FlyDSL is unavailable or GPU_ARCHS produces an incompatible variant registry, even though mqa_logits() correctly dispatches DEFAULT_CONFIG. Use flydsl_supports() with the same shapes and dtype as the dispatch probe to expect the tuned row only when supported, and DEFAULT_CONFIG otherwise.

2 resolved since last review

Review effort: Balanced

The FlyDSL wrapper copies Q and KV to contiguous but only reshapes kv_scales, weights, cu_starts and cu_ends, and the kernel reads them as packed rows. A weights view with row stride 2H gave calc_diff 0.95 on the shipped (256, 4096) FlyDSL row. mqa_logits() now sends any strided one of these to Triton, which takes strides, instead of copying it; run_mqa_logits() raises ValueError for them on FlyDSL. The test checks a strided weights view against the fp32 reference.
Copilot AI balanced review requested due to automatic review settings October 24, 2026 10:00

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

Strided scales and window tensors remain incorrectly addressed by the fallback, and the dispatch test rejects legitimate backend fallback.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Mock FlyDSL support for the table-to-launcher assertion

op_tests/​test_mqa_logits.py:193

On gfx950 with GPU_ARCHS=gfx942, or when FlyDSL is unavailable, mqa_logits() correctly dispatches DEFAULT_CONFIG instead of the shipped FlyDSL row. This unconditional assertion then fails before the fallback and numerical checks run. Mock flydsl_supports to return true for this table-to-launcher check, restoring it afterward, and leave unsupported-backend behavior to the separate fallback test.

1 resolved since last review

Review effort: Balanced

Comment thread aiter/mqa_logits.py Resolved
Triton takes the strides of weights only; it reads kv_scales, cu_starts and cu_ends as packed, like FlyDSL. The previous commit sent all four to Triton when strided, so a strided scale or window array was still misread. run_mqa_logits now raises ValueError for those three on both backends; a strided weights still runs on Triton. The test checks a kv_scales[::2] view is rejected.
Copilot AI balanced review requested due to automatic review settings October 24, 2026 13:36

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.

🔵 Needs a closer look

The GPU dispatch and tuned selections still need independent hardware validation, and the shipped-row test must account for supported fallback conditions.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Avoid requiring unavailable FlyDSL in gfx950 operator test

op_tests/​test_mqa_logits.py:194

On gfx950 with 256 CUs, this assertion requires FlyDSL even when it is unavailable or its registry was built for another GPU_ARCHS. The shipped row still says flydsl, but mqa_logits() correctly downgrades it to DEFAULT_CONFIG, so the operator test fails before reaching the fallback and numerical checks. Derive the expected dispatched config using the same support conditions, or skip this FlyDSL-specific assertion when the shipped variant cannot run.

1 resolved since last review

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 3, 2026 08:32
@amd-sriram

Copy link
Copy Markdown
Contributor Author

Avoid requiring unavailable FlyDSL in gfx950 operator test (op_tests/test_mqa_logits.py:194)

Done - 3d33634. When FlyDSL can't run the shipped variant, the test now expects the Triton fallback.

@aiter-bot

aiter-bot commented Nov 3, 2026 •

Copy link
Copy Markdown

READY FOR HUMAN REVIEW

PR Self-Review

Revision 3d33634e3ba6 · mode shadow

Author self-review accepted. Readiness report:

Author answers

  • PASS — current-SHA answers are present and structurally specific
Show the author's self-review answers

Behavior and intent

Adds a new entry point, `aiter.mqa_logits`, for the sparse-indexer prefill. Today vLLM calls the Triton/Gluon `fp8_mqa_logits` directly, so every move to a faster kernel (such as the FlyDSL one) needs a vLLM PR. With this, AITER picks Triton or a FlyDSL variant per shape from a tuned table, the way `fused_moe` does. No existing op changes behavior: without a matching row, or when FlyDSL cannot run the row, the call runs `fp8_mqa_logits` as before. Strided `kv_scales`, `cu_starts` or `cu_ends` raise `ValueError` (neither backend reads their strides); a strided `weights` runs on Triton. The tuning CI workflow also learns the new tuner and uploads `aiter/configs/model_configs/*.csv`.

Validation and unverified scope

MI355X (gfx950, 256 CUs):
- Tuner on 1a37aa008 + this change (FlyDSL 0.3.4.1, Triton 3.8.0): every candidate matched the torch reference (same `-inf` mask, `calc_diff < 1e-3`); FlyDSL won all 24 shapes, -36.6% geomean vs Triton/Gluon (table above).
- `python3 csrc/mqa_logits/mqa_logits_tune.py --run_config ...`: 24/24 within 10% on one pass, 22/24 on a second (two kernels under 40 us at +12%).
- `python3 op_tests/test_mqa_logits.py` passed at b8a6af0, including the strided-operand checks.
- `python3 -m unittest op_tests.tuning_tests.test_config_shape_collision.TestConfigShapeCollision.test_mqa_logits`: passed.

Unverified: 3d33634 only changes the expectation in `check_dispatches_shipped_row` and has not been run on a GPU yet (CI will run it). Not measured end to end in vLLM (that is vllm-project/vllm#60294). Not run on gfx942 or with the pinned FlyDSL 0.4.x. The tuning workflow change was not dispatched.

PR-specific question

`operators-tuning.yaml` is `workflow_dispatch` only, so it never runs on a pull request; only a maintainer with write access can start it, on a branch of ROCm/aiter, and fork PR code or text cannot trigger it. This PR adds no permissions, secrets or new inputs. It adds one fixed line to the `tune_jobs` list in `op_tune.sh` (a static command for the new tuner, no interpolated input) and one more path, `aiter/configs/model_configs/*.csv`, to the existing `upload-artifact` step, which keeps its 7-day retention.

Changed op tests

- `op_tests/test_mqa_logits.py` (new): checks `mqa_logits`, Triton and FlyDSL (its built-in variant choice) against a torch reference on the default shapes; that the table lookup uses the live GPU (child process with another arch in `GPU_ARCHS`); that the shipped FlyDSL row is the config dispatched, or Triton when FlyDSL cannot run it; the FlyDSL-to-Triton fallback; and strided operands (strided `weights` match the reference, strided `kv_scales` raises). No other test covers `aiter.mqa_logits`.
- `op_tests/tuning_tests/test_config_shape_collision.py` (+4): adds the `tuned_mqa_logits` family to the duplicate-key check across `configs/` and `model_configs/`, which every other tuned family already has.
- `op_tests/tuning_tests/test_run_config.py` (+9): adds the `mqa_logits` tuner to the shipped-row re-timing test, the same check every other tuner family has.

PR state

  • PASS — pull request is marked ready for review

Copilot findings

  • PASS — no active Copilot finding lacks a substantive author reply

Code and op-test hygiene

  • PASS — no committed artifact or conflict marker detected

Required CI

  • PASS — Black: passed
  • PASS — Ruff: passed
  • PASS — Repository dependency: passed
  • PASS — Aiter Test Gate: passed

Shadow mode reports what would block but keeps the status successful. Set AITER_PR_SELF_REVIEW_MODE=enforce only after reviewing real false positives.

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.

🔵 Needs a closer look

Human assessment is needed because the FlyDSL dispatch can accept large FP8 inputs whose byte offsets wrap, silently reading the wrong key.

No open issues 🎉

Review effort: Balanced

@vgokhale
vgokhale merged commit 20455aa into ROCm:main Nov 5, 2026
59 checks passed
amd-sriram added a commit to amd-sriram/vllm that referenced this pull request Nov 5, 2026
…fx950

Ask AITER for prefill MQA logits (ROCm/aiter#6185) and let its tuned table
pick the Triton/Gluon or FlyDSL kernel, instead of calling the Triton/Gluon
fp8_mqa_logits directly. Pass clean_logits=False like the Triton call
(vllm-project#51314). With an AITER that has no aiter.mqa_logits, the existing path
runs unchanged.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
amd-sriram added a commit to amd-sriram/vllm that referenced this pull request Nov 5, 2026
…fx950

Ask AITER for prefill MQA logits (ROCm/aiter#6185) and let its tuned table
pick the Triton/Gluon or FlyDSL kernel, instead of calling the Triton/Gluon
fp8_mqa_logits directly. Pass clean_logits=False like the Triton call
(vllm-project#51314). With an AITER that has no aiter.mqa_logits, the existing path
runs unchanged.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants