Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
4ce24d1
[Config] Retune the GLM-5.2 a8w8 and BF16 GEMMs for gfx950 (#5069)
XiaobingSuper Aug 28, 2026
5c1e821
Upgrade gfx1250 MLA 64nx1 code objects and their host launch contract…
feifei14119 Aug 28, 2026
91c008d
Tune MoE GEMM A8W8 (#5033)
nidal567 Aug 28, 2026
bfac111
[ASM] [HIP] [CK] feat(mha): gfx950 hd256 FP8 LINEAR paged-varlen asm …
MiloLurati Aug 28, 2026
678aa4e
Tune M=48 for the GLM-5.2 a8w8 bpreshuffle GEMM shapes (#5078)
XiaobingSuper Aug 28, 2026
6d55b57
[Triton/Gluon] [ASM] [HIP] Block-sparse MHAv4 with load-balancing (#5…
nsakkine Aug 28, 2026
018e1d9
[HIP] [DCP] Enable fused indexer QK preparation (#5066)
ZhiweiYan-96 Aug 28, 2026
0c2b0f7
[ASM] [HIP] [CI] Mxfp6 gemms (#4859)
ksikiric Aug 28, 2026
0200ada
[Triton/Gluon] Consolidate and reorganize ops/triton utils (#5061)
Boss2002n Aug 28, 2026
a3f5b62
[Triton/Gluon] Add two fused ops for diffusion transformer blocks (#4…
carlushuang Aug 28, 2026
3633f63
fix(dist): make raw IPC input pools usable — remove init_dist_env's v…
ThomasNing Aug 29, 2026
8898fa9
[FlyDSL] [opt][rope] optimize qk norm rope Ep decoding case specially…
jli-melchior Aug 29, 2026
4ad9983
[Tune] Add GLM-5.3 BF16 GEMM configs for gfx950 (#5060)
andyluo7 Aug 29, 2026
f4e7c75
[Triton/Gluon] [HIP] Dev lumen (#4978)
WuLei-AMD Aug 30, 2026
b6804e5
[CI] Avoid direct github.event interpolation in run: blocks (SEC-0083…
zufayu Aug 31, 2026
7475671
[CI] Drop registry credentials after jobs on persistent runners (SEC-…
zufayu Aug 31, 2026
d408c67
[HIP] [ROCm][Perf] Add head_dim 512 + weightless V-norm to fused_qk_n…
mpashkovskii Aug 31, 2026
b8f5232
[HIP] fix(topk): add acquire fence for mb radix barrier last block (#…
Phi-C Aug 31, 2026
78b9440
[aiter_opus_plus] detorch (#4958)
amd-ruitang3 Aug 31, 2026
fd919ed
[FlyDSL] 1250 clean moe aux kernel codes and ir, add ut (#5112)
coderfeli Aug 31, 2026
a05718c
[CI] Mirror PR title component tags as auto-managed labels (#5057)
Boss2002n Aug 31, 2026
8afaa9e
Tune the new Kimi-K3 a8w8 bpreshuffle and bf16 GEMM shapes (#5124)
XiaobingSuper Aug 31, 2026
8917886
Fix PR title tag workflow syntax (#5134)
gyohuangxin Aug 31, 2026
f2f8ed9
[CI] Document and automate the AITER release plan (#4424)
gyohuangxin Aug 31, 2026
ea6868a
[Triton/Gluon] combine routing early exit (#5053)
k50112113 Aug 31, 2026
5853cf3
[Triton/Gluon] [gfx950] gated_delta_rule: drop removed tl.make_block_…
yuyzhang512 Aug 31, 2026
f64c1c4
[Triton/Gluon] Gluon MXFP4 Fuse Reduce Quant (#3937)
amd-jrosas Aug 31, 2026
8230f15
[Triton/Gluon] Revert Triton parts of #4978 (Dev lumen) (#5149)
vgokhale Aug 31, 2026
c3dd936
[Config] [Tuning] Fill remaining Kimi-K3 bf16 GEMM shapes (#5139)
XiaobingSuper Sep 1, 2026
fba53dc
[HIP] [JIT] [gfx950] Optimize Minimax M3 scoring & top-k kernels (#4787)
ukannika Sep 1, 2026
dbd8bf5
[Triton/Gluon] fp8_mqa_logits: gate buffer ops on the int32 offset, n…
xiaobochen-amd Sep 1, 2026
d8a10bf
[FlyDSL] clean attn-aux kernels: fx.* modernization cleanup (#5113)
coderfeli Sep 1, 2026
8f06fb1
feat(fused_moe): accept a caller-provided output buffer (#4617)
RolaoDenthu Sep 1, 2026
ad27e15
Compare opus, asm and triton in the sparse-prefill test (#5084)
kaiyang-1 Sep 1, 2026
8f30b37
[FlyDSL] [JIT] [gfx1250] Add batched a8w8 mxscale_128 gemm (#5041)
aoli26 Sep 1, 2026
e583a77
[Triton/Gluon] gemm A16w16 tune for disable amdgpu-trackers (#5137)
yanxuer-999 Sep 1, 2026
5ec8c92
[FlyDSL] [CI] feat(mega_moe/gfx1250): quantize before dispatch, on an…
jhchouuu Sep 1, 2026
63114e4
[Triton] Use absolute imports in the wrapper layer (#5092)
Boss2002n Sep 1, 2026
cea4a32
[Triton] Import tests and benchmarks through the categorized paths (#…
Boss2002n Sep 1, 2026
77c96e8
perf: avoid zeroing opus MoE stage1 scales (#5178)
yifehuan Sep 1, 2026
2de2fe7
[Triton] Add config-aware repr to the GEMM and conv1d kernels (#5095)
Boss2002n Sep 1, 2026
7bc2437
topk_per_row fix on gfx1250 (#5169)
junhaha666 Sep 1, 2026
1431744
[CK] [FlyDSL] layout moe2 rm nkpad (#5130)
charlieguo1106 Sep 1, 2026
27a85a1
[Triton] Take the MOE scale layout from shuffle_scale_moe (#5094)
Boss2002n Sep 1, 2026
ab15324
[Triton/Gluon] Add config-aware repr to the attention kernels (#5097)
Boss2002n Sep 1, 2026
7a5d2ad
[Triton] Add config-aware repr to the MOE and fusion kernels (#5098)
Boss2002n Sep 1, 2026
d58537b
[Triton] Clamp the split-K heuristic so it cannot divide by zero (#5136)
Boss2002n Sep 1, 2026
ce788f5
[HIP] [FlyDSL] dcp topk merge (#5123)
ganyi1996ppo Sep 2, 2026
8de2f01
[Triton/Gluon] [CI]bump triton to 3.8.0 and deselect attention cases …
yuyzhang512 Sep 2, 2026
0da135e
[Triton/Gluon] Refactor Unified Attention (#5088)
farlukas Sep 2, 2026
7ff5155
[dist] reuse comm groups when possible for memory saving (#5111)
gbyu-amd Sep 2, 2026
fffe60a
[Triton/Gluon] Add config-aware repr to the rope and normalization ke…
Boss2002n Sep 2, 2026
1c1d846
[Triton/Gluon] Add config-aware repr to the quant kernels (#5100)
Boss2002n Sep 2, 2026
7901f93
CI: use app token for release refs (#5198)
gyohuangxin Sep 2, 2026
cab9e49
CI: respect docker login input in release builds (#5201)
gyohuangxin Sep 2, 2026
3b2a9ce
[FlyDSL] remove utils helper; clean availbility check; move tests and…
coderfeli Sep 2, 2026
fba761a
[FlyDSL] Add FlyDSL Radix-Select TopK Path to the Existing Per-Row De…
lirui927 Sep 2, 2026
62f9a50
CI: set release publish repository context (#5204)
gyohuangxin Sep 2, 2026
0c19477
Add fused SiTUv2 activation + per-token FP8 quant kernel (#5081)
XiaobingSuper Sep 2, 2026
5bd34f3
[Docs] docs: update README (#5073)
shengnxu Sep 2, 2026
0f060d2
[CK] [FlyDSL] Retune Kimi-K3 a16w4 MoE tile geometry (#5118)
amd-wsung102 Sep 2, 2026
5e4a811
tune a8w8 gemm with 64-step m for k3 (#5197)
gbyu-amd Sep 2, 2026
ded4e3e
[CI] CI: add extended test workflow (#4458)
gyohuangxin Sep 2, 2026
3e2770a
Run extended test dispatch on internal runner (#5205)
gyohuangxin Sep 2, 2026
f53e872
[FlyDSL] Remove stale TopK availability checks (#5210)
vorapolsiloai Sep 2, 2026
b5c7f71
CI: limit extended test client payload (#5209)
leo-automation Sep 2, 2026
7b64611
[Triton/Gluon] Move the sage-attention launch params into the config …
Boss2002n Sep 2, 2026
a343a10
moe_gemm_a4w4 num_warps 8 -> 4 for block_m != 16 tile (#5189)
nidal567 Sep 2, 2026
90e91d5
[Triton] Update config docs for the single nested layout (#5085)
Boss2002n Sep 2, 2026
e09939c
[skills] Add kernel PR validation and structural D9 scanning (superse…
zhiding512 Sep 2, 2026
83571d9
[AMD][DSV4] Fix(fmoe): fuse stage-1 fp8 quant on the heuristic FlyDSL…
karverma-amd Sep 2, 2026
5d23231
[Bugfix] Make `_fold_seqlen_indptr` cudagraph-safe (avoid scalar H2D …
micah-wil Sep 3, 2026
0598b04
Update test_flydsl_linear_attention.py (#5215)
xytpai Sep 3, 2026
d06a5f3
[HIP] Extend fused QK norm for MiniMax-M3 (#5143)
weitliao Sep 3, 2026
283e1d4
Revert "[AMD][DSV4] Fix(fmoe): fuse stage-1 fp8 quant on the heuristi…
valarLip Sep 3, 2026
bff4001
perf(gfx1250): add the combined gfx1250 microbench (#5076)
JiaoliangYu Aug 28, 2026
7ce3fa4
perf(gfx1250): let AITER_BENCH_TOKENS reach every op (#5082)
JiaoliangYu Aug 28, 2026
c9bcb90
perf(gfx1250): sweep the fp4 dispatch wire beside bf16 (#5147)
JiaoliangYu Aug 31, 2026
815dcd6
perf(gfx1250): follow the sparse-prefill UT through #5084 (#5170)
JiaoliangYu Sep 1, 2026
b2c29f7
perf(gfx1250): stop every child from shelling out to rocminfo (#5180)
JiaoliangYu Sep 1, 2026
13189ea
test_common:data generate
Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
778 changes: 759 additions & 19 deletions .claude/skills/review-pr/SKILL.md

Large diffs are not rendered by default.

623 changes: 623 additions & 0 deletions .claude/skills/validate-kernel-pr/SKILL.md

Large diffs are not rendered by default.

253 changes: 253 additions & 0 deletions .claude/skills/validate-kernel-pr/pick-idle-gpu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
#!/usr/bin/env python3
"""Select an AMD GPU that stays idle across a sampling window."""

from __future__ import annotations

import argparse
import os
import sys
import time
from pathlib import Path

ACTIVITY_BASIS = "activity+vram"
VRAM_ONLY_BASIS = "vram-only"


def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--samples", type=int, default=10)
parser.add_argument("--interval", type=float, default=1.0)
parser.add_argument("--max-busy", type=int, default=2)
parser.add_argument("--max-used-gib", type=float, default=2.0)
parser.add_argument("--min-free-gib", type=float, default=16.0)
parser.add_argument("--quiet", action="store_true")
parser.add_argument(
"--all",
action="store_true",
help="print every eligible HIP index in preference order, one per line, so a caller "
"whose lock on the first choice is contended can fall through to the next instead of "
"reporting no idle GPU while idle GPUs remain",
)
args = parser.parse_args()
if args.samples < 1 or args.interval < 0:
parser.error("samples must be positive and interval must be non-negative")
if args.max_busy < 0 or args.max_used_gib < 0 or args.min_free_gib < 0:
parser.error("thresholds must be non-negative")
return args


def amdsmi_search_paths() -> list[Path]:
"""Directories that have shipped the amdsmi bindings across ROCm releases."""
roots = [Path(os.environ["ROCM_PATH"])] if os.environ.get("ROCM_PATH") else []
roots.append(Path("/opt/rocm"))
roots.extend(sorted(Path("/opt").glob("rocm-*"), reverse=True))

candidates = [
Path("/usr/lib/python3/dist-packages"),
Path(
f"/usr/lib/python{sys.version_info.major}.{sys.version_info.minor}/dist-packages"
),
]
for root in roots:
# ROCm >= 7.1 ships the bindings under share/amd_smi; older builds put
# them next to the CLI. Probe both, newest ROCm first.
candidates.append(root / "share" / "amd_smi")
candidates.append(root / "libexec" / "amdsmi_cli")
return candidates


def import_amdsmi():
try:
import amdsmi

return amdsmi
except ImportError:
for candidate in amdsmi_search_paths():
if candidate.is_dir() and str(candidate) not in sys.path:
sys.path.append(str(candidate))
import amdsmi

return amdsmi


def read_activity(amdsmi, handle) -> tuple[int | None, int | None]:
"""Return (gfx, umc) busy percentages, or None for whichever is unknown.

Some driver and amd-smi combinations fail this query outright (MI308X on
ROCm 7.0 raises AMDSMI_STATUS_UNEXPECTED_DATA) or report "N/A". Both mean
unknown, which must stay distinct from a measured 0 -- reporting unknown as
idle would claim an idleness that was never observed.
"""
try:
activity = amdsmi.amdsmi_get_gpu_activity(handle)
except (OSError, amdsmi.AmdSmiException):
return None, None
gfx = activity.get("gfx_activity")
umc = activity.get("umc_activity")
return (
gfx if isinstance(gfx, int) else None,
umc if isinstance(umc, int) else None,
)


def sample(amdsmi, count: int, interval: float) -> tuple[list[dict], int]:
gpus = []
for smi_index, handle in enumerate(amdsmi.amdsmi_get_processor_handles()):
enumeration = amdsmi.amdsmi_get_gpu_enumeration_info(handle)
gpus.append(
{
"smi_index": smi_index,
"hip_index": enumeration.get("hip_id"),
"bdf": amdsmi.amdsmi_get_gpu_device_bdf(handle),
"handle": handle,
"gfx": [],
"umc": [],
}
)
peak_concurrent = 0
for sample_index in range(count):
if sample_index:
time.sleep(interval)
busy = 0
for gpu in gpus:
gfx, umc = read_activity(amdsmi, gpu["handle"])
if gfx is not None:
gpu["gfx"].append(gfx)
busy += int(gfx > 5)
if umc is not None:
gpu["umc"].append(umc)
peak_concurrent = max(peak_concurrent, busy)
for gpu in gpus:
memory = amdsmi.amdsmi_get_gpu_vram_usage(gpu["handle"])
used = memory["vram_used"] / 1024
total = memory["vram_total"] / 1024
gpu.update(
{
"used_gib": used,
"free_gib": total - used,
"peak_gfx": max(gpu["gfx"]) if gpu["gfx"] else None,
"mean_gfx": (sum(gpu["gfx"]) / len(gpu["gfx"]) if gpu["gfx"] else None),
"peak_umc": max(gpu["umc"]) if gpu["umc"] else None,
}
)
del gpu["handle"]
return gpus, peak_concurrent


def main() -> int:
args = parse_args()
try:
amdsmi = import_amdsmi()
except ImportError as error:
print(f"AMD SMI import failed: {error}", file=sys.stderr)
return 2
try:
amdsmi.amdsmi_init()
try:
gpus, peak_concurrent = sample(amdsmi, args.samples, args.interval)
finally:
amdsmi.amdsmi_shut_down()
except (OSError, amdsmi.AmdSmiException) as error:
print(f"AMD SMI probe failed: {error}", file=sys.stderr)
return 2

eligible = [
gpu
for gpu in gpus
if gpu["hip_index"] is not None
and (gpu["peak_gfx"] is None or gpu["peak_gfx"] <= args.max_busy)
and gpu["used_gib"] <= args.max_used_gib
and gpu["free_gib"] >= args.min_free_gib
]
# Prefer GPUs whose idleness was actually measured over ones where the
# activity query failed and only VRAM could be checked.
eligible.sort(
key=lambda gpu: (
gpu["peak_gfx"] is None,
gpu["peak_gfx"] or 0,
gpu["mean_gfx"] or 0.0,
gpu["used_gib"],
-gpu["free_gib"],
)
)

if not args.quiet:
print(
f"Sampled {args.samples} times over {args.samples * args.interval:.0f}s",
file=sys.stderr,
)
print(
f"{'smi':>4} {'hip':>4} {'bdf':<14} {'peak%':>6} {'mean%':>6} "
f"{'umc%':>5} {'used':>9} {'free':>9} verdict",
file=sys.stderr,
)
for gpu in sorted(gpus, key=lambda item: item["smi_index"]):
if gpu["hip_index"] is None:
verdict = "SKIP no hip_id"
elif gpu["peak_gfx"] is not None and gpu["peak_gfx"] > args.max_busy:
verdict = f"BUSY peaked {gpu['peak_gfx']}%"
elif gpu["used_gib"] > args.max_used_gib:
verdict = f"HELD {gpu['used_gib']:.1f} GiB used"
elif gpu["free_gib"] < args.min_free_gib:
verdict = f"FULL {gpu['free_gib']:.1f} GiB free"
elif gpu["peak_gfx"] is None:
verdict = "idle by VRAM only (activity unavailable)"
else:
verdict = "idle"
hip_index = "-" if gpu["hip_index"] is None else gpu["hip_index"]
peak_gfx = "n/a" if gpu["peak_gfx"] is None else str(gpu["peak_gfx"])
mean_gfx = "n/a" if gpu["mean_gfx"] is None else f"{gpu['mean_gfx']:.1f}"
peak_umc = "n/a" if gpu["peak_umc"] is None else str(gpu["peak_umc"])
print(
f"{gpu['smi_index']:>4} {hip_index:>4} {gpu['bdf']:<14} "
f"{peak_gfx:>6} {mean_gfx:>6} "
f"{peak_umc:>5} {gpu['used_gib']:>6.1f} GiB "
f"{gpu['free_gib']:>6.1f} GiB {verdict}",
file=sys.stderr,
)
if gpus and peak_concurrent >= len(gpus) - 1:
print(
f"WARNING: {peak_concurrent}/{len(gpus)} GPUs were busy together; "
"shared fabric/power may perturb the run.",
file=sys.stderr,
)

if not gpus:
# Exit 3, distinct from 1: an absent device is an environment fact, and
# reporting it as "activity unavailable" would blame the validator instead.
print("This host reports no GPUs.", file=sys.stderr)
return 3
if not eligible:
if all(gpu["peak_gfx"] is None for gpu in gpus):
print(
"No GPU stayed below the resident-memory thresholds; GPU activity "
"is unavailable on this host, so only VRAM was considered.",
file=sys.stderr,
)
else:
print(
"No GPU stayed below the activity and resident-memory thresholds.",
file=sys.stderr,
)
return 1
selected = eligible[0]
basis = ACTIVITY_BASIS if selected["peak_gfx"] is not None else VRAM_ONLY_BASIS
# Machine-readable and deliberately outside the --quiet guard: callers record
# this so a report never presents a VRAM-only claim as a measured-idle one.
print(f"idleness-basis: {basis}", file=sys.stderr)
if not args.quiet:
print(
f"Chose HIP index {selected['hip_index']} "
f"(amd-smi {selected['smi_index']}, {selected['bdf']}).",
file=sys.stderr,
)
if args.all:
for gpu in eligible:
print(gpu["hip_index"])
return 0
print(selected["hip_index"])
return 0


if __name__ == "__main__":
raise SystemExit(main())
23 changes: 23 additions & 0 deletions .claude/skills/validate-kernel-pr/production_scale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Production scale — the facts a 32-bit overflow judgement needs

Whether an index x stride product can exceed 2^31 depends on deployment scale, which the
diff does not contain. Without these numbers a reviewer cannot name a triggering case and
correctly clears every candidate above. Snapshot -- keep sourced and current; a stale row
produces a confidently wrong verdict.

The first three rows are partly **in-sample**: they come from the problem statements of the
fix PRs that also supplied the known-defect labels used during development. They demonstrate
that scale facts can make the arithmetic decidable; they do not establish holdout recall or
generalize to deployments with different limits. Replace them with deployment-config sources
before treating this table as production policy.

| quantity | scale | source |
|---|---|---|
| DeepSeek-V4 unified KV pool | ~150M rows | aiter#4680 problem statement |
| Sparse-indexer decode batch | up to 512 concurrent sequences | aiter#4244 problem statement |
| KV stride passed by callers | may be a per-group page size, not a per-token stride, when the cache is a strided view into one shared allocation | aiter#4774 problem statement |
| Production token range | 1 -> 16384 per launch | P2, review-pr |
| MoE production configs | DSv4 E=385/topk=7; GPT-OSS 120B; Kimi-K2.5 | P2, review-pr |

Worked example: `stride = KVBlockSize * index_dim`; at `KVBlockSize=256, index_dim=132` a
block index of ~63.5K puts the product past 2^31 -- well inside a 150M-row pool.
Loading