loopyt 4f3edbf604 feat(triton): complete P1 with norm, lookup and metadata kernels
norm, map_lookup, expand_sampling_params, prepare_verification_metadata, copy_block_tables.
Plus the measured parameterisation that made the port tractable: `DEEPINFER_TRACE_KERNEL_ARGS=1`
records each factory's construction arguments, which showed that e.g. `norm_tl` is only ever built
as one combination on this path (d=5120, bf16 source, fp8 out, per-128 fp32 scales, col-major,
round_sf, no residual) rather than the dozen the signature allows.

Three findings worth keeping:

`norm` has to round the fp32 normalised value back to bf16 *before* computing the per-block amax
and the scale. That is what makes its fp8 output bit-identical to quantising the bf16 result
separately, which is how the engine defines the reference. Without it the fp8 bytes scatter by an
ulp wherever a value lands on a rounding boundary -- which looked like a scale bug at first
(224 vs 240) and was not.

With `round_sf=True`, which is the production setting, fp8 output and every scale factor come out
byte-identical. With `round_sf=False` 240 of 327680 bytes differ by one ulp, because `amax/448`
depends on the order of a 5120-element reduction and two compilers will not agree on that order.
For the same reason the bf16 output differs on 10 of 655360 elements by one ulp. Both are
documented, and the A/B harness now picks its tolerance from the dtype instead of one global pair.

`map_lookup` resolves duplicate keys by taking the last match, not the maximum: the TileLang kernel
overwrites on every hit while its own Python reference uses `max`, and the two agree only when keys
are unique. Top-k indices always are, so the Triton version matches the kernel -- and the case
generator now produces unique keys, with a comment saying why.

13 kernels and 53 cases now agree with the baseline.
2026-10-22 00:28:38 +08:00
..
ab_cases.py feat(triton): complete P1 with norm, lookup and metadata kernels 2026-10-22 00:28:38 +08:00
build_vendor.sh initial commit 2026-10-20 12:09:42 +08:00
build.sh initial commit 2026-10-20 12:09:42 +08:00
compare_layers.py fix(sm90): expand expert scales on the contraction axis only 2026-10-21 16:50:31 +08:00
format_csrc.sh initial commit 2026-10-20 12:09:42 +08:00
gen_stub.sh initial commit 2026-10-20 12:09:42 +08:00
h20_ask.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
h20_attn_check.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
h20_engram_check.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
h20_expert_weight_check.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
h20_index_decode_check.py test(sm90): rule out the KV cache and the decode indexer 2026-10-21 20:02:19 +08:00
h20_kv_roundtrip.py test(sm90): rule out the KV cache and the decode indexer 2026-10-21 20:02:19 +08:00
h20_ops_ab.py feat(triton): complete P1 with norm, lookup and metadata kernels 2026-10-22 00:28:38 +08:00
h20_quant_check.py test(sm90): decode FP4 by table lookup in the quant check 2026-10-21 17:15:16 +08:00
h20_real_requant_check.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
h20_recipe_probe.py debug: capture final logits, and keep the profile forward out of the dumps 2026-10-21 17:44:21 +08:00
h20_smoke_check.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
h20_topk_check.py style(sm90): satisfy ruff and add the missing type annotations 2026-10-21 17:09:08 +08:00
ref_layer_dump.py debug: capture final logits, and keep the profile forward out of the dumps 2026-10-21 17:44:21 +08:00
ref_next_token.py debug: per-step decode dumps, and prove the flip is decode-only 2026-10-21 19:07:49 +08:00