[Triton/Gluon] Add config-aware repr to the quant kernels - #5100
Conversation
42 launchable quant kernels had no repr, so they appeared in traces under their
bare name with no way to match a row back to its config. Covers
_triton_kernels/quant/{quant,sage_attention_quant,fused_fp8_quant,
fused_mxfp4_quant,fused_mxfp8_quant}.py, the two quant wrapper modules that
define kernels inline, and the gfx1250 gluon copy.
15 jit device helpers in these files are left alone -- they are called from
inside other kernels, never launched with a grid, and the rule exempts them.
Two of them are worth a look on their own: _rotate_quantize_qk_kernel has no
references anywhere in the tree, and _general_quant_kernel is only ever called
as a device function despite the _kernel suffix.
sage_quant_v_fp4_colmajor_kernel and sage_quant_v_mxfp4_colmajor_kernel are
launchable but have no constexpr parameters at all, so a repr could only render
the bare name and would strip Triton's own specialization suffix. Left without
one; say the word if you want them included.
mxfp6_fmha_pack.py defines its kernels inside "if _HAVE_TRITON:" blocks, so its
make_kernel_repr import goes inside the existing try/except -- the module is
designed to import cleanly with no triton installed.
Key lists follow the neighbouring kernels in each subtree: tuned block/tile
sizes and the meaningful compile-time flags, with runtime pointers, strides and
grid-extent constexprs excluded (the launch site was checked before deciding on
each one). A key that is not a real parameter renders as NONE in every trace
name, so every list was re-parsed from the file and cross-checked against the
kernel signature, then rendered through the real make_kernel_repr to confirm no
NONE appears. Bare @triton.jit(repr=...) is used throughout, matching the
majority of the reprs already in the tree.
Full-tree ruff (0.16.0, the CI pin) and black report exactly the same findings
as main.
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
PR title tags: |
There was a problem hiding this comment.
Pull request overview
This PR adds config-aware repr functions (via make_kernel_repr) to a set of Triton and Gluon quantization kernels so compiled artifacts / traces include key constexpr specialization parameters in their names.
Changes:
- Import
make_kernel_reprand define per-kernel repr builders listing relevant constexpr / heuristic keys. - Wire the repr builders into
@triton.jit(repr=...)and@gluon.jit(repr=...)decorators across multiple quant kernel modules.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| aiter/ops/triton/quant/mxfp6_fmha_pack.py | Adds config-aware repr to FP6 packing kernels. |
| aiter/ops/triton/quant/fused_mxfp4_quant.py | Adds config-aware repr to the _fused_quant_fp8_sort_kernel wrapper-local Triton kernel. |
| aiter/ops/triton/_triton_kernels/quant/sage_attention_quant.py | Adds config-aware repr to multiple Sage quant kernels in this module. |
| aiter/ops/triton/_triton_kernels/quant/quant.py | Adds config-aware repr to several per-tensor/token quant kernels. |
| aiter/ops/triton/_triton_kernels/quant/fused_mxfp8_quant.py | Adds config-aware repr to fused RMS/dual-RMS/flatten MXFP8 quant kernels. |
| aiter/ops/triton/_triton_kernels/quant/fused_mxfp4_quant.py | Adds config-aware repr to several fused MXFP4 quant kernels. |
| aiter/ops/triton/_triton_kernels/quant/fused_fp8_quant.py | Adds config-aware repr to multiple fused FP8 quant kernels. |
| aiter/ops/triton/_gluon_kernels/gfx1250/quant/fused_mxfp4_quant.py | Adds config-aware repr to Gluon gfx1250 fused MXFP4 quant kernels. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
PR title tags & labels: |
make_kernel_repr renders each key's value into the kernel name, and Triton uses
that name as a function identifier. A non-integral float becomes "..._2.5" and
breaks at the dot; a negative becomes "..._-448" and breaks at the minus. Either
way the compile fails.
That is what the 513 failures in test_fused_fp8_quant.py and
test_fused_rms_gated_fp8_group_quant.py were:
invalid function identifier: 359654017857143e-06_ACTIVATION_SILU
FP8_MIN_SCALING_FACTOR sat immediately before ACTIVATION in
_fused_rms_fp8_group_quant_kernel's key list, and the test passes
1.0 / (fp8_max * 512) = 4.3596540178571429e-06. Triton parsed the name up to
the first dot and was left with the fragment above.
Removed, all for the same reason:
DTYPE_MAX, DTYPE_MIN, FP8_MAX, FP8_MIN torch.finfo bounds; the MIN pair is
negated at the call site
FP8_MIN_SCALING_FACTOR caller-supplied float
dtype_max mha_v4_per_tensor_scale_kernel takes
`dtype_max / clip`, a true division
Audited exhaustively rather than by name: every one of the 91 remaining keys was
resolved to the expressions its launch sites actually pass, and none is a true
division, a negation, a non-integral float literal or a finfo bound. The kernels
keep their block sizes and compile-time flags, which is what a trace row needs to
identify the specialization.
Two things a reviewer may want to follow up on, both pre-existing and untouched
here: the reprs on main in _triton_kernels/attention/{extend_attention,
mla_decode_rope}.py list logit_cap, which is fine only because every current
caller passes 0.0; and eleven repr keys elsewhere in the tree are not constexpr
parameters of the kernel they name, so they render as NONE in every trace name
(harmless, but the segment carries no information).
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (2)
aiter/ops/triton/_triton_kernels/quant/fused_mxfp4_quant.py:324
ACTIVATIONis passed as a Triton JIT function (see wrapper uses_get_activation_from_str(...)), andmake_kernel_reprfalls back tostr(value)for unknown types. For JIT functions this typically includes a memory address, making the compiled kernel name non-deterministic across runs and harming compile cache reuse / trace readability. Prefer excluding callable constexprs fromconfig_keys(or switch to passing a stable string activation name and dispatch inside the kernel).
_fused_reduce_act_mul_and_dynamic_mxfp4_quant_repr = make_kernel_repr(
"_fused_reduce_act_mul_and_dynamic_mxfp4_quant_kernel",
[
"BLOCK_SIZE_M1",
"BLOCK_SIZE_N1",
"BLOCK_SIZE_M2",
"BLOCK_SIZE_N2",
"NUM_ITER",
"NUM_STAGES",
"MXFP4_QUANT_BLOCK_SIZE",
"EVEN_M_N",
"SCALING_MODE",
"ACTIVATION",
"scaleN",
"scaleM_pad",
"scaleN_pad",
"SHUFFLE",
"X_HAS_SPLITK",
"X_NUM_KSPLIT",
"X_NUM_KSPLIT_POW2",
],
)
aiter/ops/triton/_triton_kernels/quant/fused_fp8_quant.py:502
ACTIVATIONhere is passed as a Triton JIT function in the wrapper path, andmake_kernel_reprwill stringify it (often including a memory address). That makes the kernelreprnon-deterministic across runs and can defeat compile caching / make traces noisy. Exclude callable constexprs fromconfig_keys(or pass an activation name string and dispatch inside the kernel).
_fused_reduce_act_mul_fp8_group_quant_repr = make_kernel_repr(
"_fused_reduce_act_mul_fp8_group_quant",
[
"ACTIVATION",
"BLOCK_SIZE_M2",
"BLOCK_SIZE_N1",
"BLOCK_SIZE_N2",
"QUANT_BLOCK_SIZE",
"X_HAS_SPLITK",
"X_NUM_KSPLIT",
"X_NUM_KSPLIT_POW2",
"X_MASK",
],
)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
aiter/ops/triton/_triton_kernels/quant/fused_mxfp4_quant.py:317
- The kernel repr for
_fused_reduce_act_mul_and_dynamic_mxfp4_quant_kernelomits theACTIVATIONconstexpr, which can make compiled artifact names ambiguous across specializations that differ only by activation behavior. IncludeACTIVATIONin theconfig_keyslist so the repr fully reflects compile-time specialization.
"MXFP4_QUANT_BLOCK_SIZE",
"EVEN_M_N",
"SCALING_MODE",
"scaleN",
"scaleM_pad",
One conflict, in _gluon_kernels/gfx1250/quant/fused_mxfp4_quant.py, and unlike the other two branches it is an add/add rather than a revert: main landed a new kernel, _gluon_fused_reduce_rms_mxfp4_quant_kernel, immediately above _gluon_fused_dynamic_mxfp4_quant_moe_sort_kernel, which is exactly where this branch had put that kernel's repr definition. Kept both -- main's new kernel byte for byte, then the repr, then @gluon.jit(repr=...) in place of the bare decorator main's hunk carried for the kernel below it. All 38 reprs the branch adds survive, and every @triton.jit/@gluon.jit repr=... in the tree resolves to a definition. Note for a follow-up: the kernel main just added has no repr. It is launched from quant/fused_mxfp4_quant.py:560, so it is a candidate for the same treatment, but adding it inside a merge commit would hide it from review.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Suppressed comments (3)
aiter/ops/triton/quant/mxfp6_fmha_pack.py:450
- The config-aware repr doesn’t include the Triton meta-parameter
num_warps, but this kernel is launched withnum_warps=4inreorder_fp6_k_lds_order_triton. Adding it helps distinguish compiled variants in traces (consistent with e.g.aiter/ops/triton/_triton_kernels/gemm/basic/gemm_afp4wfp4.py:11-24).
_gather_k_lds_repr = make_kernel_repr(
"_gather_k_lds_kernel",
[
"DATA_TILE_BYTES",
"BLOCK",
aiter/ops/triton/quant/mxfp6_fmha_pack.py:492
- The config-aware repr doesn’t include the Triton meta-parameter
num_warps, but this kernel is launched withnum_warps=4inreorder_fp6_k_lds_order_triton. Including it keeps compiled artifact names aligned with the specialization (consistent with other kernels’ repr usage).
_fill_k_scale_tail_repr = make_kernel_repr(
"_fill_k_scale_tail_kernel",
[
"TILE_BYTES",
"SCALE_TAIL_OFFSET",
aiter/ops/triton/_triton_kernels/quant/quant.py:672
- This kernel is launched with explicit Triton meta-parameters
num_warps/num_stages(seeaiter/ops/triton/quant/quant.py), but the new repr doesn’t include them. Adding these keys helps ensure trace names differentiate compiled variants even when only meta-parameters change.
_dynamic_nvfp4_quant_repr = make_kernel_repr(
"_dynamic_nvfp4_quant_kernel",
[
"BLOCK_SIZE_M",
"BLOCK_SIZE_N",
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (5)
Previously missed (3) — in code that hasn't changed since the last review.
aiter/ops/triton/_triton_kernels/quant/fused_fp8_quant.py:500
- The repr key list omits ACTIVATION even though it is a tl.constexpr meta-parameter that changes the computation (the kernel calls ACTIVATION(x)). Include it in config_keys so the repr reflects the actual specialization.
"X_HAS_SPLITK",
"X_NUM_KSPLIT",
"X_NUM_KSPLIT_POW2",
"X_MASK",
],
aiter/ops/triton/_triton_kernels/quant/fused_mxfp8_quant.py:29
- This kernel has a tl.constexpr NUM_PRGMS (controls the persistent row loop) but the repr key list doesn’t include it. Omitting it makes the generated kernel name less representative of the actual specialization used at runtime.
This issue also appears on line 121 of the same file.
[
"BLOCK_SIZE_K",
"QUANT_BLOCK_SIZE",
],
aiter/ops/triton/_triton_kernels/quant/quant.py:445
- The kernel repr is meant to be config-aware, but this kernel’s behavior depends on the tl.constexpr NUM_PRGMS (row loop stride) and the wrapper passes different NUM_PRGMS values based on M. Without including NUM_PRGMS in config_keys, compiled artifact names/traces can collide across specializations that only differ by NUM_PRGMS.
This issue also appears on line 510 of the same file.
[
"BLOCK_SIZE_N",
"QUANT_BLOCK_SIZE",
],
aiter/ops/triton/_triton_kernels/quant/quant.py:513
- Same as above: this kernel also has a tl.constexpr NUM_PRGMS that affects its persistent row loop, but the repr key list omits it, making the repr not fully specialization-aware.
[
"BLOCK_SIZE_N",
"QUANT_BLOCK_SIZE",
],
aiter/ops/triton/_triton_kernels/quant/fused_mxfp8_quant.py:125
- This kernel’s specialization includes tl.constexpr NUM_PRGMS (persistent row loop bound), but it’s not included in the repr config_keys. That makes traces/artifact names ambiguous across different NUM_PRGMS settings.
[
"BLOCK_SIZE_KQ",
"BLOCK_SIZE_KK",
"QUANT_BLOCK_SIZE",
],
No description provided.