From c9d2cc098c04afe9b9945e51539f1961ca0aab46 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Mon, 5 Oct 2026 14:07:37 +1000 Subject: [PATCH 1/2] docs(mmq): the #29953 guard under hipcc -- it fires right, with a knock-on error, and a variant without one Answers #455 on gfx1151 (ROCm 7.2.1). mmq-29953-guard-verify-hip.sh runs the nvcc script's six builds of mmq.cu with hipcc, both with CMake's own compile command and with the minimal one. - The guard fails the build in exactly the tables nvcc names, in the host pass only, and costs 0.8 s of compile time and no code: mmq.o is byte-identical with it on and off. - Clang reports one failing type per table, then a knock-on error from the outer static_assert, worded as a constexpr step-limit failure is. VARIANT=instantiate drops that static_assert for an explicitly instantiated class; clang then reports 220 guard errors and nothing else, as nvcc does. - #455's mutation 5 cannot fire on rdna3_5 (J = 64 at 192 threads needs no padding); 160 threads does. Co-Authored-By: Claude Opus 5.5 --- .../tasks/mmq-29953-guard-verify-hip.sh | 210 ++++++++++++++++++ .../rocm-gfx1151/README.md | 32 +++ .../rocm-gfx1151/verify-29953-guard.txt | 123 ++++++++++ 3 files changed, 365 insertions(+) create mode 100755 docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh create mode 100644 docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt diff --git a/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh b/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh new file mode 100755 index 00000000000..12031dbd263 --- /dev/null +++ b/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash +# The HIP counterpart of mmq-29953-guard-verify.sh (MaxusAI/ollama#455): the same builds of mmq.cu, with hipcc for +# gfx1151, on llama.cpp#29953's head (3070d927f) with mmq-29953-y-tile-guard.patch, each scored by WHY it failed: +# 1. the head as is, unpatched -> must compile (baseline time) +# 2. the head with the patch -> must compile +# 3. helper shrunk to J blocks -> must FAIL by the guard, naming every table +# 4. helper rounded to one warp's ints -> must FAIL by the guard, naming every table +# 5a. rdna3_5's first 256-thread config at 192 threads -> must COMPILE. That config has J = 64, and 64*36 ints is +# exactly 12*192, so the bit mask in GGML_PAD happens to round correctly and there is nothing to catch. No +# rdna3_5 config can be made short with 192 threads: only J = 8, 56, 72 and 120 can, and rdna3_5 uses none. +# 5b. the same config at 160 threads -> must FAIL by the guard, naming ONLY rdna3_5: GGML_PAD's +# bit mask gives 9216 B, and the load loop reads 15*160 ints = 9600 B +# 6. the guard compiled out -> must compile (timing); its object code is compared with +# build 2's, to show the guard adds none +# clang stops at 20 errors by default, which would name only the first tables; -ferror-limit=0 lifts it. +# +# Under clang, the patch as published reports ONE failing type per table, and then a knock-on error from the outer +# static_assert(ggml_cuda_mmq_y_tile_all_(...) > 0) at the same line: "static assertion expression is not an +# integral constant expression" -- the same words clang uses when it hits -fconstexpr-steps. The scoring below counts +# the knock-on as not the guard's, as the nvcc script does. VARIANT=instantiate replaces the function template and that +# outer static_assert with an explicitly instantiated class that inherits every per-type guard, so nothing outside +# the per-type assertions is constant-evaluated; clang then reports every failing (table, type) once, and nothing else. +# +# Usage: mmq-29953-guard-verify-hip.sh [cmake|hipcc] +# cmake (default): the compile command CMake generates for mmq.cu (GGML_HIP=ON, gfx1151, Release), run directly, +# with no ccache -- the way compat 903's guard was measured for #451 +# hipcc: hipcc -std=c++17 -DGGML_USE_HIP --offload-arch=gfx1151 -I. -Iggml/include -Iggml/src +# -Iggml/src/ggml-cuda, the minimal command, matching the nvcc script's +# REPEATS=N also times builds 2 and 6, interleaved, N times each. VARIANT=instantiate applies the variant above on top +# of the patch. Results go to ./verify-29953-guard-hip-[-]. +set -u +[ $# -ge 1 ] || { sed -n '2,34p' "$0"; exit 2; } +LC=$(realpath "$1"); MODE=${2:-cmake} +HERE=$(cd "$(dirname "$0")" && pwd) +PATCH=${PATCH:-$HERE/mmq-29953-y-tile-guard.patch} +ROCM=${ROCM_PATH:-/opt/rocm} +VARIANT=${VARIANT:-} +OUT=${OUT:-$PWD/verify-29953-guard-hip-$MODE${VARIANT:+-$VARIANT}} +REPEATS=${REPEATS:-0} +case "$VARIANT" in ''|instantiate) ;; *) echo "VARIANT must be empty or 'instantiate'"; exit 2;; esac +HEAD29953=3070d927f6c172242d56a2c1fb897e838e7b2632 +WT=$OUT/wt +rm -rf "$OUT"; mkdir -p "$OUT" +echo "host load at start (1/5/15 min): $(cut -d' ' -f1-3 /proc/loadavg), $(nproc) cores" +echo "ROCm $(cat "$ROCM/.info/version" 2>/dev/null), $("$ROCM/bin/hipcc" --version 2>&1 | grep -m1 'HIP version'), $("$ROCM/lib/llvm/bin/clang++" --version | head -1)" + +git -C "$LC" worktree prune +git -C "$LC" worktree add --quiet --detach "$WT" "$HEAD29953" || exit 1 +trap 'git -C "$LC" worktree remove --force "$WT" 2>/dev/null' EXIT +cd "$WT" || exit 1 +CU=ggml/src/ggml-cuda/mmq.cu; CUH=ggml/src/ggml-cuda/mmq.cuh; R35=ggml/src/ggml-cuda/mmq-config-rdna3-5.cuh + +if [ "$MODE" = cmake ]; then + cmake -S "$WT" -B "$OUT/build" -G Ninja -DGGML_HIP=ON -DGPU_TARGETS=gfx1151 -DCMAKE_BUILD_TYPE=Release \ + -DGGML_CCACHE=OFF -DCMAKE_HIP_COMPILER="$ROCM/lib/llvm/bin/clang++" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_EXAMPLES=OFF -DLLAMA_BUILD_TOOLS=OFF -DLLAMA_BUILD_SERVER=OFF \ + > "$OUT/cmake.log" 2>&1 || { echo "FAIL: cmake configure, see $OUT/cmake.log"; exit 1; } + # CMake's own command for mmq.cu, minus the dependency-file and output flags, plus -ferror-limit=0 + mapfile -t CMD < <(python3 - "$OUT/build/compile_commands.json" "$WT/$CU" "$OUT/mmq.o" <<'PY' +import json, os, shlex, sys +db, src, out = sys.argv[1:4] +e = next(e for e in json.load(open(db)) if os.path.realpath(e["file"]) == os.path.realpath(src)) +args, keep, skip = e.get("arguments") or shlex.split(e["command"]), [], False +for a in args: + if skip: + skip = False + elif a in ("-o", "-c", "-MT", "-MF"): + skip = True + elif a not in ("-MD", "-MMD"): + keep.append(a) +print("\n".join([e["directory"]] + keep + ["-ferror-limit=0", "-c", src, "-o", out])) +PY +) + RUNDIR=${CMD[0]}; CMD=("${CMD[@]:1}") + [ "${#CMD[@]}" -gt 4 ] || { echo "FAIL: no compile command for $CU"; exit 1; } +else + RUNDIR=$WT + CMD=("$ROCM/bin/hipcc" -std=c++17 -DGGML_USE_HIP --offload-arch=gfx1151 -I. -Iggml/include -Iggml/src + -Iggml/src/ggml-cuda -ferror-limit=0 -c "$WT/$CU" -o "$OUT/mmq.o") +fi +printf '%s\n' "${CMD[@]}" > "$OUT/command.txt" + +secs() { awk -v a="$1" -v b="$2" 'BEGIN{printf "%.2f", b-a}'; } +compile() { # : one compile of mmq.cu; prints the seconds, returns the compiler's exit code + local t0 t1 rc + t0=$(date +%s.%N); (cd "$RUNDIR" && "${CMD[@]}") > "$1" 2>&1; rc=$?; t1=$(date +%s.%N) + secs "$t0" "$t1"; return $rc +} +GUARD_MSG='MMQ: the y tile helper is smaller than the y load' +build() { #
(...) > 0)` fails with "static assertion expression is not an + integral constant expression". Clang prints the same words when it hits `-fconstexpr-steps`, so a reader cannot tell + the two apart without the notes. `VARIANT=instantiate` drops the outer `static_assert`: an explicitly instantiated + class inherits every per-type guard. Clang then reports each failing (table, type) once, as nvcc does. nvcc has not + compiled the variant. +- **#455's mutation 5 cannot fire on rdna3_5.** Its first 256-thread config has `J = 64`, and 64 × 36 ints is + exactly 12 × 192. At 192 threads, `GGML_PAD`'s bit mask is short only for `J` = 8, 56, 72 and 120, and rdna3_5 uses + multiples of 16. At 160 threads the same config is short: 9216 B against 9600 B. +- **The guard costs 0.8 s of compile time and no code.** `mmq.cu` compiles in 2.88 s with it and 2.05 s without + (median of five, interleaved). The object is byte-identical with the guard on and off, and with the variant. + ## Files | file | what | from | @@ -158,6 +185,7 @@ allocation itself calls, and the guard must check that helper. That is the form | [multi-call.txt](multi-call.txt) | 175 guarded calls in one process, pre-fix vs fixed header | `test-backend-ops -o MUL_MAT` | | [padding-invariant.txt](padding-invariant.txt) | every config of all ten tables against four rules | `mmq-padding-invariant.cu` | | [padding-guard.txt](padding-guard.txt) | the compile-time guard under four rules, two trees | `mmq-padding-guard.cu` | +| [verify-29953-guard.txt](verify-29953-guard.txt) | #29953's guard: six builds of `mmq.cu`, as published and as a variant | `mmq-29953-guard-verify-hip.sh` | ## Reproduce @@ -179,6 +207,10 @@ $T/mmq-rocm-table.py out/cases/results.tsv # llama.cpp#29953's head as fetched $T/mmq-rocm-build.sh --head out-head VARIANTS=head REPS=2 $T/mmq-rocm-cases.sh out-head && VARIANTS=head REPS=2 $T/mmq-rocm-route.sh out-head +# #29953's guard: six builds of mmq.cu, GPU-free (about a minute each run) +REPEATS=5 $T/mmq-29953-guard-verify-hip.sh cmake +$T/mmq-29953-guard-verify-hip.sh hipcc +REPEATS=5 VARIANT=instantiate $T/mmq-29953-guard-verify-hip.sh cmake ``` The head runs above also passed `CASES=` with `dense321` appended to the twelve. diff --git a/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt b/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt new file mode 100644 index 00000000000..aa0e09c2637 --- /dev/null +++ b/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt @@ -0,0 +1,123 @@ +# MaxusAI/ollama#455: does llama.cpp#29953's y-tile guard compile, and fire, under hipcc? +# mmq-29953-guard-verify-hip.sh on llama.cpp 3070d927f with mmq-29953-y-tile-guard.patch: mmq.cu compiled for gfx1151 +# with -ferror-limit=0 and no ccache, each build scored by why it failed. Four runs: the patch as published and +# VARIANT=instantiate, each with CMake's own compile command and with the minimal hipcc command. Host: amd-server, the +# same host and toolchain as host-profile_mmq-successor-gfx1151.json (#450). +# +# Build 5 differs from the nvcc script's on purpose. #455 asked for rdna3_5's first 256-thread config at 192 threads. +# That config has J = 64, and 64*36 ints = 12*192, so GGML_PAD's bit mask happens to round correctly: there is +# nothing to catch. At 192 threads the bit mask is short only for J = 8, 56, 72 and 120, and rdna3_5 uses J = 16 to +# 128 in steps of 16, so no rdna3_5 config can fire at 192. Build 5a is #455's mutation and must compile; build 5b +# moves the same config to 160 threads, where the bit mask gives 9216 B and the load reads 15*160 ints = 9600 B. + +== 1. the patch as published, CMake's compile command, five interleaved timing repeats +host load at start (1/5/15 min): 0.28 0.42 0.27, 32 cores +ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) +1-head-unpatched rc=0 ok want=ok as-expected 2.06s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 +2-head-with-guard rc=0 ok want=ok as-expected 2.89s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail WRONG-REASON 1.36s + errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +4-helper-rounded-to-one-warp rc=1 fail want=fail WRONG-REASON 1.36s + errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.88s +mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail WRONG-REASON 2.11s + errors=2, from the guard=1, tables named: rdna3_5 +6-guard-compiled-out rc=0 ok want=ok as-expected 2.05s +object code, build 2 vs build 6 (guard on vs off): byte-identical, 166400 B +timing, 5 interleaved repeats: with the guard 2.88 2.89 2.87 2.86 2.88 s (median 2.88), without 2.05 2.07 2.05 2.04 2.05 s (median 2.05) +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:04:36Z mode=cmake variant=none all_as_expected=0 + +== 2. the patch as published, minimal hipcc +host load at start (1/5/15 min): 0.63 0.50 0.30, 32 cores +ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) +1-head-unpatched rc=0 ok want=ok as-expected 1.99s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 +2-head-with-guard rc=0 ok want=ok as-expected 2.78s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail WRONG-REASON 1.30s + errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +4-helper-rounded-to-one-warp rc=1 fail want=fail WRONG-REASON 1.29s + errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.79s +mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail WRONG-REASON 2.03s + errors=2, from the guard=1, tables named: rdna3_5 +6-guard-compiled-out rc=0 ok want=ok as-expected 1.98s +object code, build 2 vs build 6 (guard on vs off): byte-identical, 165312 B +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:04:51Z mode=hipcc variant=none all_as_expected=0 + +Builds 3, 4 and 5b fail for the right reason, but score WRONG-REASON: clang reports one failing type per table, then a +knock-on error at the same line. The first pair from build 3; every failing table gives the same pair: + ggml/src/ggml-cuda/mmq.cu:530:1: error: static assertion failed due to requirement 'ggml_cuda_mmq_y_tile_ok_pascal_older(42)': MMQ: the y tile helper is smaller than the y load for a config in the pascal_older table + ggml/src/ggml-cuda/mmq.cu:530:1: error: static assertion expression is not an integral constant expression +The knock-on is the outer static_assert(ggml_cuda_mmq_y_tile_all_
(...) > 0, ""): once a per-type assertion +fails, that function's instantiation is invalid, so the call is not a constant expression. In runs 1 and 2, all 42 +knock-on errors sit on a line where the guard failed, and no log has a "maximum step limit" note. But the words are +the ones clang prints when it hits -fconstexpr-steps. + +VARIANT=instantiate replaces the function template and the outer static_assert + template static constexpr size_t ggml_cuda_mmq_y_tile_all_##TABLE(std::integer_sequence) { + return (sizeof(ggml_cuda_mmq_y_tile_guard_##TABLE) + ... + 0); + } + static_assert(ggml_cuda_mmq_y_tile_all_##TABLE(std::make_integer_sequence()) > 0, ""); +with an explicitly instantiated class that inherits every per-type guard, so only the per-type assertions are +constant-evaluated. + +== 3. VARIANT=instantiate, CMake's compile command, five interleaved timing repeats +host load at start (1/5/15 min): 0.72 0.52 0.31, 32 cores +ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) +1-head-unpatched rc=0 ok want=ok as-expected 2.06s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 +variant 'instantiate' applied: the guard's tail is now + template struct ggml_cuda_mmq_y_tile_guards_##TABLE; + template struct ggml_cuda_mmq_y_tile_guards_##TABLE> + : ggml_cuda_mmq_y_tile_guard_##TABLE... {}; + template struct ggml_cuda_mmq_y_tile_guards_##TABLE>; +2-head-with-guard rc=0 ok want=ok as-expected 2.89s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.85s + errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.85s + errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.88s +mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.23s + errors=1, from the guard=1, tables named: rdna3_5 +6-guard-compiled-out rc=0 ok want=ok as-expected 2.05s +object code, build 2 vs build 6 (guard on vs off): byte-identical, 166424 B +timing, 5 interleaved repeats: with the guard 2.87 2.86 2.85 2.91 2.86 s (median 2.86), without 2.07 2.06 2.06 2.05 2.06 s (median 2.06) +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:05:34Z mode=cmake variant=instantiate all_as_expected=1 + +== 4. VARIANT=instantiate, minimal hipcc +host load at start (1/5/15 min): 0.99 0.62 0.36, 32 cores +ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) +1-head-unpatched rc=0 ok want=ok as-expected 1.97s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 +variant 'instantiate' applied: the guard's tail is now + template struct ggml_cuda_mmq_y_tile_guards_##TABLE; + template struct ggml_cuda_mmq_y_tile_guards_##TABLE> + : ggml_cuda_mmq_y_tile_guard_##TABLE... {}; + template struct ggml_cuda_mmq_y_tile_guards_##TABLE>; +2-head-with-guard rc=0 ok want=ok as-expected 2.84s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.78s + errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.77s + errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.81s +mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.09s + errors=1, from the guard=1, tables named: rdna3_5 +6-guard-compiled-out rc=0 ok want=ok as-expected 1.98s +object code, build 2 vs build 6 (guard on vs off): byte-identical, 165336 B +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:05:49Z mode=hipcc variant=instantiate all_as_expected=1 + +== object code across runs +The patch as published vs VARIANT=instantiate, build 2, both compiled in one worktree to one output name with run 1's +CMake command: byte-identical, 166400 B. Objects from different runs are not, because each run has its own worktree +path: a -instantiate run's is 12 characters longer, which adds 24 B to .rodata.str1.1 (two __FILE__ strings; 166424 +and 165336 B above) and changes __hip_cuid_*, which clang hashes from the file path and the command line. Their host +disassembly is identical. From 5ed7bd82995dc5071dc187571fc558f71c0e24a0 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Mon, 5 Oct 2026 14:41:03 +1000 Subject: [PATCH 2/2] docs(mmq): the #29953 guard under hipcc -- blackwell at 192 too, and a script that survives the fold Follows the CUDA host's nvcc run of the instantiate variant on #455 (same counts, so it folds the variant into mmq-29953-y-tile-guard.patch): - build 5c is the nvcc script's build 5, blackwell at 192 threads: hipcc fails it with 1 guard error naming only blackwell, so both compilers agree on both single-table mutations; - VARIANT=instantiate applies nothing to a patch that already has the variant, checked against a local fold; - every run records the patch's blob (729f22c2 as #455 published it), so the results stay true after the fold; - the README says nvcc gives the same counts with either form. Co-Authored-By: Claude Opus 5.5 --- .../tasks/mmq-29953-guard-verify-hip.sh | 38 +++-- .../rocm-gfx1151/README.md | 24 ++-- .../rocm-gfx1151/verify-29953-guard.txt | 132 ++++++++++++------ 3 files changed, 130 insertions(+), 64 deletions(-) diff --git a/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh b/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh index 12031dbd263..ff6582e606a 100755 --- a/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh +++ b/docs/maxusai/tasks/mmq-29953-guard-verify-hip.sh @@ -10,16 +10,20 @@ # rdna3_5 config can be made short with 192 threads: only J = 8, 56, 72 and 120 can, and rdna3_5 uses none. # 5b. the same config at 160 threads -> must FAIL by the guard, naming ONLY rdna3_5: GGML_PAD's # bit mask gives 9216 B, and the load loop reads 15*160 ints = 9600 B +# 5c. blackwell's first 256-thread config at 192 threads -> must FAIL by the guard, naming ONLY blackwell: the nvcc +# script's build 5 (J = 8: the bit mask gives 1280 B, the load reads 2*192 ints = 1536 B). The host pass checks +# every table whatever the offload target, so hipcc must catch an NVIDIA table too # 6. the guard compiled out -> must compile (timing); its object code is compared with # build 2's, to show the guard adds none # clang stops at 20 errors by default, which would name only the first tables; -ferror-limit=0 lifts it. # -# Under clang, the patch as published reports ONE failing type per table, and then a knock-on error from the outer -# static_assert(ggml_cuda_mmq_y_tile_all_
(...) > 0) at the same line: "static assertion expression is not an -# integral constant expression" -- the same words clang uses when it hits -fconstexpr-steps. The scoring below counts -# the knock-on as not the guard's, as the nvcc script does. VARIANT=instantiate replaces the function template and that -# outer static_assert with an explicitly instantiated class that inherits every per-type guard, so nothing outside -# the per-type assertions is constant-evaluated; clang then reports every failing (table, type) once, and nothing else. +# The guard as #455 first published it ends in an outer static_assert(ggml_cuda_mmq_y_tile_all_
(...) > 0). +# Under clang that form reports ONE failing type per table, and then a knock-on error from the outer static_assert at +# the same line: "static assertion expression is not an integral constant expression" -- the same words clang uses +# when it hits -fconstexpr-steps. The scoring below counts the knock-on as not the guard's, as the nvcc script does. +# VARIANT=instantiate replaces the function template and that outer static_assert with an explicitly instantiated +# class that inherits every per-type guard, so nothing outside the per-type assertions is constant-evaluated; clang +# then reports every failing (table, type) once, and nothing else. A patch that already has that form needs no VARIANT. # # Usage: mmq-29953-guard-verify-hip.sh [cmake|hipcc] # cmake (default): the compile command CMake generates for mmq.cu (GGML_HIP=ON, gfx1151, Release), run directly, @@ -29,7 +33,7 @@ # REPEATS=N also times builds 2 and 6, interleaved, N times each. VARIANT=instantiate applies the variant above on top # of the patch. Results go to ./verify-29953-guard-hip-[-]. set -u -[ $# -ge 1 ] || { sed -n '2,34p' "$0"; exit 2; } +[ $# -ge 1 ] || { sed -n '2,38p' "$0"; exit 2; } LC=$(realpath "$1"); MODE=${2:-cmake} HERE=$(cd "$(dirname "$0")" && pwd) PATCH=${PATCH:-$HERE/mmq-29953-y-tile-guard.patch} @@ -49,6 +53,7 @@ git -C "$LC" worktree add --quiet --detach "$WT" "$HEAD29953" || exit 1 trap 'git -C "$LC" worktree remove --force "$WT" 2>/dev/null' EXIT cd "$WT" || exit 1 CU=ggml/src/ggml-cuda/mmq.cu; CUH=ggml/src/ggml-cuda/mmq.cuh; R35=ggml/src/ggml-cuda/mmq-config-rdna3-5.cuh +BW=ggml/src/ggml-cuda/mmq-config-blackwell.cuh if [ "$MODE" = cmake ]; then cmake -S "$WT" -B "$OUT/build" -G Ninja -DGGML_HIP=ON -DGPU_TARGETS=gfx1151 -DCMAKE_BUILD_TYPE=Release \ @@ -124,13 +129,17 @@ ok=1 build "1-head-unpatched" ok || ok=0 git apply "$PATCH" || { echo "FAIL: the patch does not apply to $HEAD29953"; exit 1; } -echo "patch applies to a pristine $HEAD29953" +echo "patch applies to a pristine $HEAD29953 (patch blob $(git hash-object "$PATCH"))" if [ "$VARIANT" = instantiate ]; then python3 - "$CU" <<'PY' || exit 1 import sys p = sys.argv[1]; s = open(p).read() head = " template static constexpr size_t ggml_cuda_mmq_y_tile_all_##TABLE(" tail = 'static_assert(ggml_cuda_mmq_y_tile_all_##TABLE(std::make_integer_sequence()) > 0, "");' +done = " template struct ggml_cuda_mmq_y_tile_guards_##TABLE>;" +if s.count(head) == 0 and s.count(tail) == 0 and "template struct ggml_cuda_mmq_y_tile_guards_##TABLE<" in s: + print("variant 'instantiate': the patch already has it, nothing to apply") + sys.exit(0) if s.count(head) != 1 or s.count(tail) != 1: sys.exit("variant anchors found %d and %d times, expected once each" % (s.count(head), s.count(tail))) a = s.index(head); b = s.index(tail) + len(tail) @@ -138,15 +147,16 @@ new = [ " template struct ggml_cuda_mmq_y_tile_guards_##TABLE;", " template struct ggml_cuda_mmq_y_tile_guards_##TABLE>", " : ggml_cuda_mmq_y_tile_guard_##TABLE... {};", - " template struct ggml_cuda_mmq_y_tile_guards_##TABLE>;", + done, ] new = "\n".join([l.ljust(120) + "\\" for l in new[:-1]] + new[-1:]) open(p, "w").write(s[:a] + new + s[b:]) +print("variant 'instantiate' applied") PY - echo "variant 'instantiate' applied: the guard's tail is now" + echo "the guard's tail is now" grep -A3 -F ' template struct ggml_cuda_mmq_y_tile_guards_##TABLE;' "$CU" | sed 's/ *\\$//; s/^/ /' fi -cp "$CU" "$OUT/mmq.cu.patched"; cp "$CUH" "$OUT/mmq.cuh.patched"; cp "$R35" "$OUT/rdna3-5.orig" +cp "$CU" "$OUT/mmq.cu.patched"; cp "$CUH" "$OUT/mmq.cuh.patched"; cp "$R35" "$OUT/rdna3-5.orig"; cp "$BW" "$OUT/blackwell.orig" build "2-head-with-guard" ok || ok=0 cp "$OUT/mmq.o" "$OUT/mmq-2.o" 2>/dev/null @@ -171,6 +181,12 @@ echo "mutation 5b rewrote: $first -> ${first/256,/160,}" build "5b-rdna3_5-config-at-160-threads" fail "rdna3_5" || ok=0 cp "$OUT/rdna3-5.orig" "$R35" +firstbw=$(grep -m1 -E '^ *CASE\(GGML_TYPE_[A-Z0-9_]+, *256,' "$BW") +swap "$BW" "$firstbw" "${firstbw/256,/192,}" +echo "mutation 5c rewrote: $firstbw -> ${firstbw/256,/192,}" +build "5c-blackwell-config-at-192-threads" fail "blackwell" || ok=0 +cp "$OUT/blackwell.orig" "$BW" + sed 's/^# define GGML_CUDA_MMQ_Y_TILE_GUARD_ON$/\/\/ guard disabled for timing/; s/^# define GGML_CUDA_MMQ_Y_TILE_GUARD_ON$/\/\/ guard disabled for timing/' \ "$OUT/mmq.cu.patched" > "$OUT/mmq.cu.unguarded" cmp -s "$OUT/mmq.cu.patched" "$OUT/mmq.cu.unguarded" && { echo "FAIL: the guard's defines were not found"; exit 1; } diff --git a/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/README.md b/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/README.md index 0c9c5a95385..13f32264732 100644 --- a/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/README.md +++ b/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/README.md @@ -145,28 +145,34 @@ allocation itself calls, and the guard must check that helper. That is the form #455 asked whether `mmq-29953-y-tile-guard.patch` compiles, and fires, under hipcc as it does under nvcc. The patch is compat 903's guard, rebuilt for llama.cpp#29953's head. [verify-29953-guard.txt](verify-29953-guard.txt) holds -the six builds of `mmq.cu` from `mmq-29953-guard-verify-hip.sh`, with ROCm 7.2.1 for gfx1151: +the eight builds of `mmq.cu` from `mmq-29953-guard-verify-hip.sh`, with ROCm 7.2.1 for gfx1151: -| build | nvcc, sm_120 (#454) | hipcc, the patch as published | hipcc, `VARIANT=instantiate` | +| build | nvcc, sm_120, either form | hipcc, the patch as published | hipcc, `VARIANT=instantiate` | |---|---|---|---| | 1, 2, 6: head; with the guard; guard compiled out | ok | ok | ok | | 3: helper shrunk to `J` blocks | 220 guard errors, 10 tables | 10 guard + 10 knock-on errors, 10 tables | 220 guard errors, 10 tables | | 4: helper rounded to one warp | 220 guard errors, 10 tables | 10 guard + 10 knock-on errors, 10 tables | 220 guard errors, 10 tables | -| 5: one config at a non-power-of-two `nthreads` | blackwell at 192: 1 guard error | rdna3_5 at 192: ok; at 160: 1 guard + 1 knock-on error | rdna3_5 at 192: ok; at 160: 1 guard error | +| 5a: an rdna3_5 config at 192 threads (#455's mutation) | not run | ok: nothing to catch | ok: nothing to catch | +| 5b: the same config at 160 threads | 1 guard error, rdna3_5 (variant only) | 1 guard + 1 knock-on error, rdna3_5 | 1 guard error, rdna3_5 | +| 5c: a blackwell config at 192 threads (the nvcc script's build 5) | 1 guard error, blackwell | 1 guard + 1 knock-on error, blackwell | 1 guard error, blackwell | - **The guard works under hipcc.** It fails the build in exactly the tables nvcc names, and only in the host pass. - CMake's own compile command and the minimal `hipcc` command agree on every build. + The host pass checks every table, whatever the target, so hipcc catches the blackwell mutation too. CMake's own + compile command and the minimal `hipcc` command agree on every build. - **Clang adds a knock-on error.** It reports one failing type per table, and then the outer `static_assert(ggml_cuda_mmq_y_tile_all_
(...) > 0)` fails with "static assertion expression is not an integral constant expression". Clang prints the same words when it hits `-fconstexpr-steps`, so a reader cannot tell the two apart without the notes. `VARIANT=instantiate` drops the outer `static_assert`: an explicitly instantiated - class inherits every per-type guard. Clang then reports each failing (table, type) once, as nvcc does. nvcc has not - compiled the variant. + class inherits every per-type guard. Clang then reports each failing (table, type) once, as nvcc does. nvcc gives + the same counts with either form + ([#455](https://github.com/MaxusAI/ollama/issues/455#issuecomment-5988160612)). - **#455's mutation 5 cannot fire on rdna3_5.** Its first 256-thread config has `J = 64`, and 64 × 36 ints is exactly 12 × 192. At 192 threads, `GGML_PAD`'s bit mask is short only for `J` = 8, 56, 72 and 120, and rdna3_5 uses multiples of 16. At 160 threads the same config is short: 9216 B against 9600 B. -- **The guard costs 0.8 s of compile time and no code.** `mmq.cu` compiles in 2.88 s with it and 2.05 s without +- **The guard costs 0.8 s of compile time and no code.** `mmq.cu` compiles in 2.89 s with it and 2.06 s without (median of five, interleaved). The object is byte-identical with the guard on and off, and with the variant. +- **The script survives the fold.** With a patch that already has the variant, `VARIANT=instantiate` applies + nothing, and every build scores as expected. ## Files @@ -185,7 +191,7 @@ the six builds of `mmq.cu` from `mmq-29953-guard-verify-hip.sh`, with ROCm 7.2.1 | [multi-call.txt](multi-call.txt) | 175 guarded calls in one process, pre-fix vs fixed header | `test-backend-ops -o MUL_MAT` | | [padding-invariant.txt](padding-invariant.txt) | every config of all ten tables against four rules | `mmq-padding-invariant.cu` | | [padding-guard.txt](padding-guard.txt) | the compile-time guard under four rules, two trees | `mmq-padding-guard.cu` | -| [verify-29953-guard.txt](verify-29953-guard.txt) | #29953's guard: six builds of `mmq.cu`, as published and as a variant | `mmq-29953-guard-verify-hip.sh` | +| [verify-29953-guard.txt](verify-29953-guard.txt) | #29953's guard: eight builds of `mmq.cu`, as published and as a variant | `mmq-29953-guard-verify-hip.sh` | ## Reproduce @@ -207,7 +213,7 @@ $T/mmq-rocm-table.py out/cases/results.tsv # llama.cpp#29953's head as fetched $T/mmq-rocm-build.sh --head out-head VARIANTS=head REPS=2 $T/mmq-rocm-cases.sh out-head && VARIANTS=head REPS=2 $T/mmq-rocm-route.sh out-head -# #29953's guard: six builds of mmq.cu, GPU-free (about a minute each run) +# #29953's guard: eight builds of mmq.cu, GPU-free (about a minute each run) REPEATS=5 $T/mmq-29953-guard-verify-hip.sh cmake $T/mmq-29953-guard-verify-hip.sh hipcc REPEATS=5 VARIANT=instantiate $T/mmq-29953-guard-verify-hip.sh cmake diff --git a/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt b/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt index aa0e09c2637..fbcc9084284 100644 --- a/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt +++ b/docs/maxusai/tasks/mmq-successor-results/rocm-gfx1151/verify-29953-guard.txt @@ -1,60 +1,67 @@ # MaxusAI/ollama#455: does llama.cpp#29953's y-tile guard compile, and fire, under hipcc? -# mmq-29953-guard-verify-hip.sh on llama.cpp 3070d927f with mmq-29953-y-tile-guard.patch: mmq.cu compiled for gfx1151 -# with -ferror-limit=0 and no ccache, each build scored by why it failed. Four runs: the patch as published and -# VARIANT=instantiate, each with CMake's own compile command and with the minimal hipcc command. Host: amd-server, the -# same host and toolchain as host-profile_mmq-successor-gfx1151.json (#450). +# mmq-29953-guard-verify-hip.sh on llama.cpp 3070d927f with mmq-29953-y-tile-guard.patch as #455 published it (blob +# 729f22c2): mmq.cu compiled for gfx1151 with -ferror-limit=0 and no ccache, each build scored by why it failed. Four +# runs: the patch as published and VARIANT=instantiate, each with CMake's own compile command and with the minimal +# hipcc command. Host: amd-server, the same host and toolchain as host-profile_mmq-successor-gfx1151.json (#450). # # Build 5 differs from the nvcc script's on purpose. #455 asked for rdna3_5's first 256-thread config at 192 threads. # That config has J = 64, and 64*36 ints = 12*192, so GGML_PAD's bit mask happens to round correctly: there is # nothing to catch. At 192 threads the bit mask is short only for J = 8, 56, 72 and 120, and rdna3_5 uses J = 16 to # 128 in steps of 16, so no rdna3_5 config can fire at 192. Build 5a is #455's mutation and must compile; build 5b -# moves the same config to 160 threads, where the bit mask gives 9216 B and the load reads 15*160 ints = 9600 B. +# moves the same config to 160 threads, where the bit mask gives 9216 B and the load reads 15*160 ints = 9600 B; +# build 5c is the nvcc script's build 5, blackwell's first 256-thread config (J = 8) at 192 threads. == 1. the patch as published, CMake's compile command, five interleaved timing repeats -host load at start (1/5/15 min): 0.28 0.42 0.27, 32 cores +host load at start (1/5/15 min): 0.46 0.19 0.13, 32 cores ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) 1-head-unpatched rc=0 ok want=ok as-expected 2.06s -patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 -2-head-with-guard rc=0 ok want=ok as-expected 2.89s -3-helper-shrunk-to-J-blocks rc=1 fail want=fail WRONG-REASON 1.36s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 (patch blob 729f22c2727a0af9938def9798e2997f4a193924) +2-head-with-guard rc=0 ok want=ok as-expected 2.90s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail WRONG-REASON 1.39s errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 -4-helper-rounded-to-one-warp rc=1 fail want=fail WRONG-REASON 1.36s +4-helper-rounded-to-one-warp rc=1 fail want=fail WRONG-REASON 1.39s errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.88s +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.89s mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -5b-rdna3_5-config-at-160-threads rc=1 fail want=fail WRONG-REASON 2.11s +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail WRONG-REASON 2.10s errors=2, from the guard=1, tables named: rdna3_5 -6-guard-compiled-out rc=0 ok want=ok as-expected 2.05s +mutation 5c rewrote: CASE(GGML_TYPE_MXFP4, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); -> CASE(GGML_TYPE_MXFP4, 192, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); +5c-blackwell-config-at-192-threads rc=1 fail want=fail WRONG-REASON 2.08s + errors=2, from the guard=1, tables named: blackwell +6-guard-compiled-out rc=0 ok want=ok as-expected 2.07s object code, build 2 vs build 6 (guard on vs off): byte-identical, 166400 B -timing, 5 interleaved repeats: with the guard 2.88 2.89 2.87 2.86 2.88 s (median 2.88), without 2.05 2.07 2.05 2.04 2.05 s (median 2.05) -VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:04:36Z mode=cmake variant=none all_as_expected=0 +timing, 5 interleaved repeats: with the guard 2.88 2.89 3.00 2.89 2.89 s (median 2.89), without 2.07 2.06 2.07 2.06 2.06 s (median 2.06) +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:37:58Z mode=cmake variant=none all_as_expected=0 == 2. the patch as published, minimal hipcc -host load at start (1/5/15 min): 0.63 0.50 0.30, 32 cores +host load at start (1/5/15 min): 0.85 0.33 0.18, 32 cores ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) 1-head-unpatched rc=0 ok want=ok as-expected 1.99s -patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 (patch blob 729f22c2727a0af9938def9798e2997f4a193924) 2-head-with-guard rc=0 ok want=ok as-expected 2.78s -3-helper-shrunk-to-J-blocks rc=1 fail want=fail WRONG-REASON 1.30s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail WRONG-REASON 1.29s errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 -4-helper-rounded-to-one-warp rc=1 fail want=fail WRONG-REASON 1.29s +4-helper-rounded-to-one-warp rc=1 fail want=fail WRONG-REASON 1.28s errors=20, from the guard=10, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); 5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.79s mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); 5b-rdna3_5-config-at-160-threads rc=1 fail want=fail WRONG-REASON 2.03s errors=2, from the guard=1, tables named: rdna3_5 -6-guard-compiled-out rc=0 ok want=ok as-expected 1.98s +mutation 5c rewrote: CASE(GGML_TYPE_MXFP4, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); -> CASE(GGML_TYPE_MXFP4, 192, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); +5c-blackwell-config-at-192-threads rc=1 fail want=fail WRONG-REASON 2.00s + errors=2, from the guard=1, tables named: blackwell +6-guard-compiled-out rc=0 ok want=ok as-expected 1.99s object code, build 2 vs build 6 (guard on vs off): byte-identical, 165312 B -VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:04:51Z mode=hipcc variant=none all_as_expected=0 +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:38:15Z mode=hipcc variant=none all_as_expected=0 -Builds 3, 4 and 5b fail for the right reason, but score WRONG-REASON: clang reports one failing type per table, then a -knock-on error at the same line. The first pair from build 3; every failing table gives the same pair: +Builds 3, 4, 5b and 5c fail for the right reason, but score WRONG-REASON: clang reports one failing type per table, +then a knock-on error at the same line. The first pair from build 3; every failing table gives the same pair: ggml/src/ggml-cuda/mmq.cu:530:1: error: static assertion failed due to requirement 'ggml_cuda_mmq_y_tile_ok_pascal_older(42)': MMQ: the y tile helper is smaller than the y load for a config in the pascal_older table ggml/src/ggml-cuda/mmq.cu:530:1: error: static assertion expression is not an integral constant expression The knock-on is the outer static_assert(ggml_cuda_mmq_y_tile_all_
(...) > 0, ""): once a per-type assertion -fails, that function's instantiation is invalid, so the call is not a constant expression. In runs 1 and 2, all 42 +fails, that function's instantiation is invalid, so the call is not a constant expression. In runs 1 and 2, all 44 knock-on errors sit on a line where the guard failed, and no log has a "maximum step limit" note. But the words are the ones clang prints when it hits -fconstexpr-steps. @@ -67,53 +74,90 @@ with an explicitly instantiated class that inherits every per-type guard, so onl constant-evaluated. == 3. VARIANT=instantiate, CMake's compile command, five interleaved timing repeats -host load at start (1/5/15 min): 0.72 0.52 0.31, 32 cores +host load at start (1/5/15 min): 0.88 0.37 0.20, 32 cores ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) -1-head-unpatched rc=0 ok want=ok as-expected 2.06s -patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 -variant 'instantiate' applied: the guard's tail is now +1-head-unpatched rc=0 ok want=ok as-expected 2.07s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 (patch blob 729f22c2727a0af9938def9798e2997f4a193924) +variant 'instantiate' applied +the guard's tail is now template struct ggml_cuda_mmq_y_tile_guards_##TABLE; template struct ggml_cuda_mmq_y_tile_guards_##TABLE> : ggml_cuda_mmq_y_tile_guard_##TABLE... {}; template struct ggml_cuda_mmq_y_tile_guards_##TABLE>; 2-head-with-guard rc=0 ok want=ok as-expected 2.89s -3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.85s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.86s errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 -4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.85s +4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.86s errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); 5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.88s mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.23s +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.17s errors=1, from the guard=1, tables named: rdna3_5 -6-guard-compiled-out rc=0 ok want=ok as-expected 2.05s +mutation 5c rewrote: CASE(GGML_TYPE_MXFP4, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); -> CASE(GGML_TYPE_MXFP4, 192, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); +5c-blackwell-config-at-192-threads rc=1 fail want=fail as-expected 2.17s + errors=1, from the guard=1, tables named: blackwell +6-guard-compiled-out rc=0 ok want=ok as-expected 2.07s object code, build 2 vs build 6 (guard on vs off): byte-identical, 166424 B -timing, 5 interleaved repeats: with the guard 2.87 2.86 2.85 2.91 2.86 s (median 2.86), without 2.07 2.06 2.06 2.05 2.06 s (median 2.06) -VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:05:34Z mode=cmake variant=instantiate all_as_expected=1 +timing, 5 interleaved repeats: with the guard 2.89 2.90 2.88 2.89 2.87 s (median 2.89), without 2.06 2.06 2.08 2.06 2.06 s (median 2.06) +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:39:00Z mode=cmake variant=instantiate all_as_expected=1 == 4. VARIANT=instantiate, minimal hipcc -host load at start (1/5/15 min): 0.99 0.62 0.36, 32 cores +host load at start (1/5/15 min): 1.00 0.47 0.24, 32 cores +ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) +1-head-unpatched rc=0 ok want=ok as-expected 1.99s +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 (patch blob 729f22c2727a0af9938def9798e2997f4a193924) +variant 'instantiate' applied +the guard's tail is now + template struct ggml_cuda_mmq_y_tile_guards_##TABLE; + template struct ggml_cuda_mmq_y_tile_guards_##TABLE> + : ggml_cuda_mmq_y_tile_guard_##TABLE... {}; + template struct ggml_cuda_mmq_y_tile_guards_##TABLE>; +2-head-with-guard rc=0 ok want=ok as-expected 2.83s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.77s + errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.78s + errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 +mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.80s +mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.10s + errors=1, from the guard=1, tables named: rdna3_5 +mutation 5c rewrote: CASE(GGML_TYPE_MXFP4, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); -> CASE(GGML_TYPE_MXFP4, 192, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); +5c-blackwell-config-at-192-threads rc=1 fail want=fail as-expected 2.09s + errors=1, from the guard=1, tables named: blackwell +6-guard-compiled-out rc=0 ok want=ok as-expected 1.97s +object code, build 2 vs build 6 (guard on vs off): byte-identical, 165336 B +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:39:17Z mode=hipcc variant=instantiate all_as_expected=1 + +== 5. a patch that already has the variant, VARIANT=instantiate, minimal hipcc +The published patch with the variant folded in (blob 7261da53), to check that the script still runs after the fold. +host load at start (1/5/15 min): 1.00 0.51 0.26, 32 cores ROCm 7.2.1, HIP version: 7.2.53211-e1a6bc5663, AMD clang version 22.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-7.2.1 26084 f58b06dce1f9c15707c5f808fd002e18c2accf7e) 1-head-unpatched rc=0 ok want=ok as-expected 1.97s -patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 -variant 'instantiate' applied: the guard's tail is now +patch applies to a pristine 3070d927f6c172242d56a2c1fb897e838e7b2632 (patch blob 7261da53931b3e25940af3a1a01994784c56649b) +variant 'instantiate': the patch already has it, nothing to apply +the guard's tail is now template struct ggml_cuda_mmq_y_tile_guards_##TABLE; template struct ggml_cuda_mmq_y_tile_guards_##TABLE> : ggml_cuda_mmq_y_tile_guard_##TABLE... {}; template struct ggml_cuda_mmq_y_tile_guards_##TABLE>; -2-head-with-guard rc=0 ok want=ok as-expected 2.84s -3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.78s +2-head-with-guard rc=0 ok want=ok as-expected 2.82s +3-helper-shrunk-to-J-blocks rc=1 fail want=fail as-expected 1.81s errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 -4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.77s +4-helper-rounded-to-one-warp rc=1 fail want=fail as-expected 1.78s errors=220, from the guard=220, tables named: ampere blackwell cdna gcn pascal_dp4a pascal_older rdna2 rdna3 rdna3_5 rdna4 mutation 5a rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 192, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.81s +5a-rdna3_5-config-at-192-threads rc=0 ok want=ok as-expected 2.82s mutation 5b rewrote: CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -> CASE(GGML_TYPE_Q1_0, 160, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true); -5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.09s +5b-rdna3_5-config-at-160-threads rc=1 fail want=fail as-expected 2.11s errors=1, from the guard=1, tables named: rdna3_5 +mutation 5c rewrote: CASE(GGML_TYPE_MXFP4, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); -> CASE(GGML_TYPE_MXFP4, 192, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true); +5c-blackwell-config-at-192-threads rc=1 fail want=fail as-expected 2.10s + errors=1, from the guard=1, tables named: blackwell 6-guard-compiled-out rc=0 ok want=ok as-expected 1.98s -object code, build 2 vs build 6 (guard on vs off): byte-identical, 165336 B -VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:05:49Z mode=hipcc variant=instantiate all_as_expected=1 +object code, build 2 vs build 6 (guard on vs off): byte-identical, 165272 B +VERIFY29953GUARD-HIP COMPLETE 2026-10-05T04:39:35Z mode=hipcc variant=instantiate all_as_expected=1 == object code across runs The patch as published vs VARIANT=instantiate, build 2, both compiled in one worktree to one output name with run 1's