Skip to content

HIP: bound the routed prompt's K-parallel tile by pairs per item, and give it gfx1201's short prompts - #1607

Merged
ashhart merged 8 commits into
ashhart:mainfrom
laudney:hip-routed-pairs
Oct 29, 2026
Merged

ashhart merged 8 commits into
ashhart:mainfrom
laudney:hip-routed-pairs

Conversation

@laudney

@laudney laudney commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #1557.

What this changes

On gfx1201 the routed prompt's K-parallel tile (mlx.routed.prefill.kp3) beats the dot2 GEMM tile for plans that hold few pairs an item and loses for full ones, but the registry could bound a routed plan only by its items, which is a bucket's capacity, so #1527 had to keep gfx1100's 300. This PR:

  1. A pairs-per-item bound (tuning.Row.pairs_per_item, an f32, 0 off; registry.Shape.plan_pairs): Registry.cost refuses a routed plan of more than pairs_per_item * items pairs, compared in f64, exactly for any item count below 2^29. A tuning test keeps the field to mlx.routed.prefill.* rows, finite and from 0 to 8. No table but gfx1201's sets it, so no other GPU's choice changes.
  2. Serving passes each plan's pairs to prefillLaunch beside its items, host-side only: affine.Arg and Routing keep their layout (their size assert stands). The affine fixtures pass theirs, pickable sweeps a routed prompt plan's pair counts, and the prompt path's byte check now compares every launched entry (all of them are the gemm family), so kp3 and the GEMM tile are compared on each routed prompt plan.
  3. hip-affine-tune times every routed MLX model's plans: Qwen3.6 (256 + shared, 9 slots), Nemotron (128, 6) and Flash Next (512 + shared, 11, exact sizing), and a served plan without a shared slot draws distinct experts a token. Its proposal moved into zig/src/hip/tuning/search.zig, host-tested: kp3's items and pairs bound and kp1's pairs bound are searched together (refusing kp3 hands a plan to kp1 before the GEMM tile), candidates are each cell's least admitting f32, the tuner times both sides of every place its proposal changes a choice, and a noisy timing is retaken up to twice.
  4. gfx1201's kp3 row: items = 507, pairs_per_item = 3.5. The tuner proposed 507 and 4.14; served runs lowered the bound to 3.5 (below).

No kernel or arithmetic change: every routed prompt entry is in the gemm family, and replies keep their bytes in every run below.

Why 3.5, and why a fraction

The tuner times each tile in isolation on plans whose experts are drawn uniformly; a trained router concentrates pairs on popular experts, so served items hold more rows, and the tuner admits kp3 further than serving can take it (at Nemotron's 213 tokens it timed kp3 faster, where served it is 8% slower). Served runs on this branch's code, alternated with main on fresh boots:

kp3 row Nemotron 113-128 tokens (3.03-3.43 pairs an item) Nemotron 200 / 213 tokens (3.75 / 3.99)
items 507, pairs 4 (the tuner's) on kp3, as main x1.030 / x1.079
items 507, pairs 3 moved to kp1: x1.057 to x1.077 as main
items 507, pairs 3.5 (this PR) on kp3, as main: x1.003 to x1.005 as main: x1.000 / x1.001

No whole number lies between 3.43 and 3.75, so the bound is a fraction; 3.5 keeps Nemotron's 65 to 128-token plans on kp3 as today, gives it kp3 from 129 to 186 tokens, and keeps 187 to 256 on the GEMM tile.

Receipt

  • Environment: this branch on upstream/main at 1017c5c6, Zig 0.17.0, HIP 7.16 (AMD clang 24.0.0git), one Radeon AI PRO R9700 (gfx1201) that nothing else was using, Linux. Checkpoints mlx-community/Qwen3.6-35B-A3B-4bit at 38740b847e4cb78f352aba30aa41c76e08e6eb46 and TensorFold/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-MLX-4bit at d9d758fb83953437f7263256b0d96157e2a348b8.
  • Tests on this branch's head: zig build test -Dhip=true 466/466 steps, 5687/5716 tests passed (29 skipped); hip-kernel-test 106/106; hip-affine-test 30/30; tf-qwen35-test check on Qwen3.6: 42 passed, 0 failed, 5 skipped. tools/zig/lean_check.py: 425 problems on upstream/main and on this branch, none new. atc overlap: no conflict.
  • The served runs below compare upstream/main at 7c068895 with it plus this PR's code commits and row; 7c068895..1017c5c6 touches no HIP, lane or registry file. Server with --prompt-cache-gib 0, a fresh process each round, rounds alternating main, branch, main, branch, then a reversed pair. Cold prefill: tools/bench_cache.py --require-cold --tokens 16 --repeats 3 --streams 1, median ttft_s a round. Every reply's token_sha256 (cold prompts) and token_sha (greedy and seeded tools/bench_openai.py replies, temperatures 0 and 1.0) is equal between the builds in every round.
  • A size measured right after one whose plans moved to kp3 reads up to 3.7% slow in sequence, even where its own choice is unchanged (Qwen3.6 at 129 tokens after 128, Nemotron at 187 after 186); in boots of their own they are within 0.6% of main (tables below).
  • Qwen3.6 decode, six boots: x0.999 to x1.001. Nemotron decode, ten alternated boots a build: x0.996 to x1.004 (below).
  • zig build hip-affine-tune on the R9700 (raw routed times below): BOUND mlx.routed.prefill kp3 items 300 -> 507, kp3 pairs_per_item 0 -> 4.143750190734863, kp1 pairs_per_item 0 -> 0: 56 cells changed, loss 0.000, saving 91796.99 us, search 5333 ms; every plain prompt bound keeps gfx1100's value.

Not run

Flash Next (TensorFold/Qwen3.8-Flash-Next-MLX-4bit-MTP, 73.3 GiB) needs three of these 32 GB cards, and the others here serve other work. The tuner covers its plan geometry. Its exact plans hold 0.89 pairs an item up to 513 pairs, where Qwen3.6 gains most, and items = 507 gives it kp3 up to 41 rows (24 today). If you'd rather it waited for a served Flash Next run, the last two commits (perf(hip): gfx1201's routed prompt tiles by pairs per item and the test fix after it) drop together, and the rest stands on its own: no other table sets the field. gfx1200 takes the table unmeasured, as before.

Qwen3.6-35B-A3B, cold prefill (median ttft_s of three cold requests a boot)

tokens ms per round: main, branch, main, branch, branch, main branch over main
32 46.1 46.4 46.8 47.0 46.3 46.1 x1.005
33 100.7 56.9 101.1 56.6 56.7 100.7 x0.563
48 122.3 65.1 122.5 65.1 65.3 122.8 x0.532
64 110.3 74.4 110.4 74.2 74.5 110.2 x0.674
65 110.5 77.3 110.8 77.5 77.2 110.7 x0.699
100 124.7 95.7 124.8 95.5 95.3 124.8 x0.765
128 141.2 112.3 141.4 113.1 112.0 141.5 x0.796
129 140.1 145.3 140.1 145.1 145.9 140.6 x1.037
256 179.4 181.0 179.8 181.0 181.2 179.9 x1.008
1000 418.2 419.1 418.9 418.8 418.7 418.6 x1.001
2048 850.9 857.1 851.7 851.4 851.4 852.2 x1.002
8192 3646.7 3654.8 3654.3 3653.8 3656.4 3653.0 x1.001

Nemotron 3.5 Lightning, cold prefill

tokens ms per round: main, branch, main, branch, branch, main branch over main
64 84.6 86.4 86.1 86.5 86.6 86.2 x1.010
65 89.1 90.4 90.4 90.3 90.7 90.5 x1.005
112 124.6 126.6 126.5 126.8 127.2 126.9 x1.007
113 126.1 127.8 127.8 127.7 128.1 128.0 x1.005
120 130.9 132.4 132.8 132.5 132.5 132.7 x1.003
128 137.8 139.0 139.5 139.4 139.5 139.3 x1.003
129 180.1 147.0 180.4 147.5 147.5 180.4 x0.817
160 187.2 170.5 188.0 171.1 171.0 188.0 x0.910
161 185.7 172.3 186.7 172.7 172.8 186.7 x0.926
170 186.0 179.8 186.8 180.2 180.2 186.8 x0.966
180 193.4 188.1 193.6 188.3 188.3 193.6 x0.973
186 193.1 191.3 192.2 192.0 192.3 191.9 x0.997
187 192.9 196.3 193.1 196.5 196.3 192.9 x1.018
200 202.2 202.6 202.6 202.5 202.5 202.7 x1.000
213 202.1 203.1 203.1 202.9 203.3 203.4 x1.001
214 203.3 203.6 205.6 203.7 203.6 203.5 x0.998
256 211.1 211.1 210.6 210.6 210.2 210.9 x0.999
257 217.1 215.7 216.1 216.2 216.8 216.8 x0.998
512 278.6 278.6 278.8 282.4 278.9 278.5 x1.005
1000 419.5 418.6 419.0 419.3 418.9 419.0 x0.999
2048 708.3 708.5 708.4 709.3 708.9 708.6 x1.001
8192 2996.4 3000.4 3002.0 3003.3 3002.0 3001.9 x1.001

Qwen3.6, the size after a moved bound, in boots of its own

tokens ms per round: main, branch, main, branch, branch, main branch over main
129 140.8 140.4 140.4 140.4 140.4 140.4 x0.999
256 180.3 182.3 180.6 180.7 180.9 180.8 x1.004

Nemotron, the sizes after a moved bound, in boots of their own

tokens ms per round: main, branch, main, branch, branch, main branch over main
187 196.7 196.5 196.9 196.2 196.5 198.9 x0.994
214 202.9 203.2 203.7 204.6 204.9 204.6 x1.003
256 210.4 211.2 211.7 211.8 211.6 211.5 x1.002

Nemotron decode, ten alternated boots a build (tools/bench_openai.py --tokens 128 --reps 3, tok/s)

prompt temperature main mean (sd) branch mean (sd) branch over main
fibonacci-raw 1.0 209.5 (6.1) 209.3 (7.2) x0.999
gpu-chat-no-think 1.0 185.4 (2.4) 186.1 (0.9) x1.004
fibonacci-raw 0.0 205.9 (3.6) 204.9 (4.3) x0.996
gpu-chat-no-think 0.0 221.9 (1.1) 222.4 (1.3) x1.002
The tuner's routed prompt times from its last run: median us a launch (noise when above 5%); U marks a cell whose table copies could not reach 512 MiB a rotation

35b served gate_up (1024 x 2048, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
1 U 9 9 1.00 22.4 48.1 194.6 320.3
2 U 162 18 0.11 47.8 86.2 226.3 511.0
4 U 162 36 0.22 89.5 157.5 430.1 866.9
8 U 162 72 0.44 166.3 287.5 787.3 1528.0
16 162 144 0.89 284.4 514.9 1374.0 2738.5
32 293 288 0.98 488.6 845.7 2172.3 4363.1
33 329 297 0.90 501.4 881.2 2232.9 4490.2
36 329 324 0.98 533.9 927.1 2345.4 4704.1
37 329 333 1.01 539.6 941.5 2371.3 4758.0
63 329 567 1.72 770.4 1225.4 2884.3 5764.1
64 329 576 1.75 772.5 1200.6 2798.6 5595.4
65 401 585 1.46 790.9 1226.8 2840.1 5656.2
89 401 801 2.00 968.4 1413.7 3075.4 6099.6
90 401 810 2.02 974.1 1420.1 3075.1 6098.5
128 401 1152 2.87 1255.5 1690.5 3190.4 6288.5
181 545 1629 2.99 1701.5 2088.9 3312.3 6452.7
182 545 1638 3.01 1706.3 2095.2 3307.6 6455.7
242 545 2178 4.00 2141.3 2511.3 3368.9 6507.9
243 545 2187 4.01 2149.9 2520.4 3370.1 6510.3
256 545 2304 4.23 2257.5 2650.4 3373.8 6514.7
257 833 2313 2.78 2309.0 2695.6 3373.6 6525.4
277 833 2493 2.99 2460.6 2846.6 3380.5 6521.4
278 833 2502 3.00 2471.4 2847.9 3379.4 6529.2
370 833 3330 4.00 3136.3 3542.9 3407.5 6581.0
371 833 3339 4.01 3140.2 3546.9 3407.8 6574.0
462 833 4158 4.99 3807.4 4198.3 3441.1 6636.1
463 833 4167 5.00 3813.8 4199.4 3442.7 6632.9
512 833 4608 5.53 4161.5 4514.0 3450.6 6652.3
513 1409 4617 3.28 4266.7 4607.5 3455.5 6673.0
626 1409 5634 4.00 5080.4 5296.2 3479.9 6727.5
627 1409 5643 4.00 5093.4 5305.3 3480.8 6731.7
782 1409 7038 5.00 6224.0 6210.1 3511.5 6794.5
783 1409 7047 5.00 6238.7 6227.9 3512.1 6802.8
939 1409 8451 6.00 7379.4 7178.5 3561.3 6893.7
940 1409 8460 6.00 7386.9 7186.2 3561.7 6892.3
1024 1409 9216 6.54 8001.0 7692.3 3609.3 6912.5
1025 2561 9225 3.60 8176.8 7875.2 3625.9 6940.3
1138 2561 10242 4.00 9003.3 8588.6 3714.4 6977.8
1139 2561 10251 4.00 9022.5 8594.0 3718.7 6977.8
1422 2561 12798 5.00 10964.4 10369.9 3887.7 7102.7
1423 2561 12807 5.00 10981.2 10370.8 3891.1 7103.2
1707 2561 15363 6.00 13030.2 12163.8 4089.1 7259.9
1708 2561 15372 6.00 13023.0 12168.0 4097.5 7265.5
1991 2561 17919 7.00 15065.0 13954.5 4558.1 7370.2
1992 2561 17928 7.00 15073.5 13960.8 4558.8 7371.1
2048 2561 18432 7.20 15467.0 14289.2 4659.9 7393.4

35b served down (2048 x 512, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
1 U 9 9 1.00 14.6 28.4 82.3 146.7
2 U 162 18 0.11 29.9 49.1 137.3 249.7
4 U 162 36 0.22 48.8 82.8 230.3 433.3
8 U 162 72 0.44 86.6 154.0 439.9 837.7
16 162 144 0.89 134.1 248.4 730.1 1356.8
32 293 288 0.98 226.9 401.9 1155.0 2130.4
33 329 297 0.90 235.1 411.3 1175.1 2165.5
36 329 324 0.98 249.5 432.8 1233.7 2264.6
37 329 333 1.01 251.9 438.8 1242.3 2277.4
63 329 567 1.72 349.6 599.9 1639.5 2960.5
64 329 576 1.75 349.2 612.4 1594.3 2899.8
65 401 585 1.46 358.4 621.6 1606.2 2919.9
89 401 801 2.00 431.1 714.3 1770.6 3162.8
90 401 810 2.02 433.8 718.7 1778.3 3176.8
128 401 1152 2.87 553.0 844.1 1891.1 3269.6
181 545 1629 2.99 709.6 1037.9 1994.7 3313.5
182 545 1638 3.01 713.3 1039.5 1995.6 3312.7
242 545 2178 4.00 885.1 1228.4 2068.7 3324.6
243 545 2187 4.01 886.0 1229.9 2068.0 3325.1
256 545 2304 4.23 923.6 1280.7 2079.2 3325.5
257 833 2313 2.78 950.9 1306.8 2083.3 3333.1
277 833 2493 2.99 1012.5 1378.8 2100.3 3340.2
278 833 2502 3.00 1019.5 1383.4 2102.1 3332.9
370 833 3330 4.00 1271.4 1696.9 2144.9 3358.3
371 833 3339 4.01 1276.6 1699.0 2145.3 3360.4
462 833 4158 4.99 1530.7 1982.2 2169.0 3388.4
463 833 4167 5.00 1533.3 1988.9 2169.3 3383.7
512 833 4608 5.53 1670.0 2129.8 2171.8 3407.7
513 1409 4617 3.28 1720.7 2179.2 2203.6 3416.8
626 1409 5634 4.00 2033.5 2515.0 2210.3 3450.2
627 1409 5643 4.00 2037.0 2516.7 2209.7 3451.6
782 1409 7038 5.00 2480.5 2951.2 2236.8 3515.3
783 1409 7047 5.00 2485.4 2953.6 2236.4 3512.3
939 1409 8451 6.00 2928.1 3366.6 2268.8 3556.4
940 1409 8460 6.00 2929.6 3367.5 2268.8 3554.8
1024 1409 9216 6.54 3159.6 3594.1 2278.4 3574.4
1025 2561 9225 3.60 3260.9 3687.2 2337.1 3612.6
1138 2561 10242 4.00 3582.2 4004.9 2351.6 3637.4
1139 2561 10251 4.00 3583.3 4003.0 2351.1 3637.8
1422 2561 12798 5.00 4381.9 4793.4 2412.8 3727.4
1423 2561 12807 5.00 4381.8 4800.3 2411.6 3725.6
1707 2561 15363 6.00 5176.6 5597.7 2511.7 3800.0
1708 2561 15372 6.00 5180.8 5597.9 2515.7 3800.9
1991 2561 17919 7.00 5980.1 6416.9 2716.9 3887.8
1992 2561 17928 7.00 5983.1 6418.6 2716.9 3887.4
2048 2561 18432 7.20 6131.2 6570.0 2760.5 3894.5

nemotron served up (1856 x 2688, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
1 U 6 6 1.00 45.5 84.2 257.3 432.5
2 U 108 12 0.11 90.3 159.4 407.2 846.3
4 U 108 24 0.22 158.1 256.9 677.4 1399.0
8 108 48 0.44 306.5 494.2 1287.7 2638.9
16 108 96 0.89 507.4 808.2 2073.0 4245.9
25 152 150 0.99 690.4 1042.4 2643.9 5395.9
26 152 156 1.03 725.2 1085.3 2739.9 5609.4
32 152 192 1.26 844.6 1207.5 3027.7 6187.7
33 176 198 1.12 866.0 1236.2 3087.4 6306.5
58 176 348 1.98 1287.4 1598.0 3651.4 7429.4
59 176 354 2.01 1296.8 1599.0 3653.6 7430.6
63 176 378 2.15 1368.8 1656.6 3681.7 7473.7
64 176 384 2.18 1387.0 1710.2 3682.9 7478.8
65 224 390 1.74 1413.4 1741.7 3685.1 7479.1
74 224 444 1.98 1575.9 1850.7 3757.4 7609.2
75 224 450 2.01 1592.5 1865.8 3793.9 7685.1
112 224 672 3.00 2221.3 2405.1 3946.9 7920.1
113 224 678 3.03 2230.4 2413.8 3949.0 7924.6
128 224 768 3.43 2467.9 2595.4 3965.6 7933.6
129 320 774 2.42 2508.8 2633.4 3965.2 7935.6
160 320 960 3.00 3013.2 3062.8 3989.7 7953.4
161 320 966 3.02 3038.5 3072.0 3989.2 7951.2
213 320 1278 3.99 3888.4 3766.8 4015.8 7976.4
214 320 1284 4.01 3913.9 3784.2 4012.9 7974.0
256 320 1536 4.80 4581.4 4366.9 4023.1 7998.7
257 512 1542 3.01 4645.2 4426.2 4024.2 8005.2
341 512 2046 4.00 5990.8 5508.9 4031.2 8044.8
342 512 2052 4.01 6028.9 5542.6 4030.8 8045.0
426 512 2556 4.99 7335.5 6600.1 4039.5 8093.1
427 512 2562 5.00 7354.5 6622.2 4039.9 8109.8
512 512 3072 6.00 8690.0 7695.4 4058.9 8151.0
513 896 3078 3.44 8821.0 7802.7 4061.4 8150.1
597 896 3582 4.00 10170.0 8888.6 4092.1 8181.0
598 896 3588 4.00 10200.5 8904.8 4092.0 8187.5
746 896 4476 5.00 12451.0 10720.8 4215.1 8234.9
747 896 4482 5.00 12486.7 10756.9 4218.3 8235.3
896 896 5376 6.00 14848.7 12607.1 4364.9 8315.2
897 896 5382 6.01 14866.6 12626.2 4364.6 8317.8
1024 896 6144 6.86 16865.5 14163.5 4468.5 8385.5
1025 1664 6150 3.70 17068.0 14381.3 4472.8 8381.4
1109 1664 6654 4.00 18360.4 15474.2 4565.4 8410.1
1110 1664 6660 4.00 18388.4 15491.0 4565.2 8401.8
1386 1664 8316 5.00 22774.4 18917.3 5245.0 8505.4
1387 1664 8322 5.00 22809.8 18956.1 5247.1 8512.4
1664 1664 9984 6.00 27146.2 22399.2 5992.3 8655.5
1665 1664 9990 6.00 27169.6 22401.7 5991.4 8654.7
1941 1664 11646 7.00 31518.0 25854.3 6255.1 8790.2
1942 1664 11652 7.00 31530.8 25884.2 6259.4 8791.6
2048 1664 12288 7.38 33201.5 27263.7 6345.2 8835.9

nemotron served down (2688 x 1856, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
1 U 6 6 1.00 36.2 73.9 195.9 448.5
2 U 108 12 0.11 79.6 149.6 377.0 785.7
4 U 108 24 0.22 146.8 263.5 717.1 1468.1
8 108 48 0.44 272.7 474.2 1218.0 2429.7
16 108 96 0.89 474.2 854.5 2157.0 4373.8
25 152 150 0.99 652.0 1139.6 2770.2 5607.9
26 152 156 1.03 662.1 1162.8 2828.1 5724.1
32 152 192 1.26 737.8 1282.4 2987.6 6031.1
33 176 198 1.12 771.9 1333.9 3042.1 6142.2
58 176 348 1.98 1114.2 1817.2 3709.8 7446.4
59 176 354 2.01 1128.8 1830.1 3710.4 7445.2
63 176 378 2.15 1180.8 1882.0 3716.6 7440.9
64 176 384 2.18 1191.0 1759.0 3718.4 7443.1
65 224 390 1.74 1219.4 1786.4 3720.3 7443.9
74 224 444 1.98 1335.2 1889.4 3736.9 7449.9
75 224 450 2.01 1347.9 1908.9 3739.1 7452.4
112 224 672 3.00 1823.6 2336.0 3885.1 7640.2
113 224 678 3.03 1835.3 2340.1 3892.2 7646.0
128 224 768 3.43 2009.4 2530.8 3912.4 7652.8
129 320 774 2.42 2061.1 2566.9 3914.9 7653.9
160 320 960 3.00 2497.9 3011.9 3952.2 7679.9
161 320 966 3.02 2520.3 3050.4 3953.3 7673.6
213 320 1278 3.99 3150.2 3712.8 3987.2 7703.8
214 320 1284 4.01 3164.6 3723.8 3986.9 7705.0
256 320 1536 4.80 3705.9 4358.0 3996.6 7720.6
257 512 1542 3.01 3791.4 4432.2 3998.3 7722.8
341 512 2046 4.00 4813.8 5374.9 4010.0 7774.4
342 512 2052 4.01 4822.2 5384.6 4010.4 7780.4
426 512 2556 4.99 5850.6 6245.6 4021.8 7825.4
427 512 2562 5.00 5859.6 6258.6 4020.2 7831.4
512 512 3072 6.00 6941.5 7124.9 4027.6 7883.4
513 896 3078 3.44 7096.6 7274.5 4029.6 7888.4
597 896 3582 4.00 8147.0 8140.1 4059.0 7909.6
598 896 3588 4.00 8160.4 8155.1 4058.9 7912.0
746 896 4476 5.00 10003.8 9711.4 4198.8 7980.6
747 896 4482 5.00 10025.7 9737.4 4201.7 7978.5
896 896 5376 6.00 11736.2 11275.5 4327.7 8059.0
897 896 5382 6.01 11758.6 11301.0 4332.9 8060.0
1024 896 6144 6.86 13322.1 12717.0 4439.9 8122.9
1025 1664 6150 3.70 13629.3 13016.1 4459.9 8128.3
1109 1664 6654 4.00 14637.9 13903.3 4518.8 8145.6
1110 1664 6660 4.00 14652.5 13915.0 4516.4 8147.6
1386 1664 8316 5.00 18017.1 16885.3 5256.3 8265.0
1387 1664 8322 5.00 18037.1 16891.0 5257.2 8265.0
1664 1664 9984 6.00 21446.0 19874.6 5912.6 8418.3
1665 1664 9990 6.00 21463.0 19886.7 5936.3 8414.9
1941 1664 11646 7.00 24849.6 22856.8 6179.2 8547.6
1942 1664 11652 7.00 24834.4 22873.4 6174.1 8551.5
2048 1664 12288 7.38 26143.5 24011.6 6258.4 8588.7

flash next served gate_up (1280 x 2560, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
1 U 11 11 1.00 53.2 83.8 285.5 759.7
2 U 24 22 0.92 103.3 171.2 515.4 1177.2
4 U 49 44 0.90 209.0 335.7 917.9 2046.1
8 U 99 88 0.89 397.9 636.4 1561.9 3556.0
16 198 176 0.89 748.3 1170.0 2843.6 6598.7
24 297 264 0.89 1080.5 1670.5 4019.3 9357.8
25 309 275 0.89 1125.7 1727.2 4152.3 9688.5
32 396 352 0.89 1352.6 2057.6 4899.2 11420.6
33 408 363 0.89 1393.3 2129.0 5052.7 11751.6
53 585 583 1.00 2045.8 2945.2 6892.6 15928.4
54 587 594 1.01 2078.2 3004.2 7035.1 16258.3
63 599 693 1.16 2344.3 3358.1 7773.6 17944.3
64 601 704 1.17 2358.6 3412.3 7651.6 17677.8
65 602 715 1.19 2392.8 3439.1 7713.9 17765.1
124 683 1364 2.00 3893.4 4708.0 9672.1 22073.0
125 684 1375 2.01 3933.2 4723.9 9669.2 22094.4
128 689 1408 2.04 3984.9 4776.9 9710.2 22190.9
223 819 2453 3.00 6230.0 6588.6 10638.5 24055.6
224 821 2464 3.00 6249.2 6612.2 10654.5 24110.8
256 865 2816 3.26 7014.5 7205.4 10743.8 24235.9
372 1024 4092 4.00 9643.1 9304.0 10912.7 24415.3
373 1025 4103 4.00 9691.0 9334.2 10929.9 24471.0
512 1217 5632 4.63 12882.4 11876.4 11035.2 24622.8
620 1365 6820 5.00 15342.3 13820.8 11078.9 24764.1
621 1366 6831 5.00 15362.1 13837.2 11081.8 24767.5
1024 1921 11264 5.86 24374.5 20863.0 11231.7 25246.5
1118 2050 12298 6.00 26492.6 22506.1 11268.8 25343.2
1119 2051 12309 6.00 26520.1 22533.7 11271.2 25348.6
2048 3329 22528 6.77 47087.6 38042.0 12421.5 26417.3

flash next served down (2560 x 640, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
1 U 11 11 1.00 35.4 72.6 140.6 295.4
2 U 24 22 0.92 69.4 149.9 253.9 534.5
4 U 49 44 0.90 144.1 277.6 463.4 961.2
8 U 99 88 0.89 352.4 564.1 890.8 1826.1
16 198 176 0.89 671.6 1077.6 1636.8 3355.1
24 297 264 0.89 916.8 1438.2 2168.0 4450.3
25 309 275 0.89 937.1 1485.3 2244.5 4609.6
32 396 352 0.89 1165.9 1823.2 2749.1 5659.3
33 408 363 0.89 1201.4 1861.5 2798.4 5768.2
53 585 583 1.00 1708.0 2612.3 3905.3 8001.3
54 587 594 1.01 1722.0 2658.2 3973.8 8129.9
63 599 693 1.16 1901.1 2874.0 4290.4 8775.9
64 601 704 1.17 1902.0 3049.7 4241.7 8696.7
65 602 715 1.19 1905.7 3067.7 4270.9 8740.0
124 683 1364 2.00 2887.5 4098.2 5461.0 10919.1
125 684 1375 2.01 2898.6 4108.5 5473.3 10943.3
128 689 1408 2.04 2949.3 4156.2 5505.3 10987.6
223 819 2453 3.00 4333.7 5724.3 6095.1 11666.8
224 821 2464 3.00 4349.8 5740.0 6098.4 11671.9
256 865 2816 3.26 4813.6 6259.3 6192.3 11712.2
372 1024 4092 4.00 6476.6 8260.1 6466.8 11875.6
373 1025 4103 4.00 6497.5 8282.9 6468.2 11880.7
512 1217 5632 4.63 8433.5 10567.6 6646.9 11983.2
620 1365 6820 5.00 9873.7 12349.8 6716.1 12030.4
621 1366 6831 5.00 9885.0 12358.2 6713.6 12038.5
1024 1921 11264 5.86 15237.5 17975.9 6845.3 12269.2
1118 2050 12298 6.00 16478.9 19224.2 6880.5 12318.9
1119 2051 12309 6.00 16502.1 19227.1 6872.3 12320.8
2048 3329 22528 6.77 28658.3 31363.9 7238.4 12840.6

35b served gate_up (1024 x 2048, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
129 545 1161 2.13 1282.9 1693.8 3197.2 6278.4
154 545 1386 2.54 1480.5 1896.8 3253.3 6371.4
141 545 1269 2.33 1383.3 1807.2 3233.7 6339.3
134 545 1206 2.21 1322.3 1752.2 3215.0 6321.6
131 545 1179 2.16 1304.0 1730.9 3195.4 6286.7

35b served down (2048 x 512, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
129 545 1161 2.13 521.6 850.5 1893.2 3256.0
154 545 1386 2.54 630.5 938.9 1953.5 3290.0
141 545 1269 2.33 593.5 889.4 1931.0 3280.1
134 545 1206 2.21 571.6 873.0 1917.7 3281.5
131 545 1179 2.16 563.8 863.9 1898.5 3255.6

nemotron served up (1856 x 2688, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
215 320 1290 4.03 3925.0 3776.3 4012.2 7926.5
235 320 1410 4.41 4206.5 4024.2 4017.6 7941.7
224 320 1344 4.20 4081.4 3941.0 4015.7 7939.7
219 320 1314 4.11 3985.5 3844.2 4014.6 7941.4
216 320 1296 4.05 3931.8 3785.8 4014.4 7940.2

nemotron served down (2688 x 1856, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
215 320 1290 4.03 3168.6 3734.7 3988.4 7666.9
235 320 1410 4.41 3426.2 4027.0 3997.0 7686.8
224 320 1344 4.20 3273.2 3847.8 3991.0 7684.6
219 320 1314 4.11 3219.6 3783.0 3991.4 7685.6
216 320 1296 4.05 3182.9 3750.9 3987.5 7691.3

flash next served gate_up (1280 x 2560, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
34 420 374 0.89 1416.3 2128.3 5129.8 11895.0
43 532 473 0.89 1747.2 2591.3 6114.9 14158.8
38 470 418 0.89 1567.7 2343.2 5556.6 12880.7
35 433 385 0.89 1464.1 2214.8 5262.1 12242.1

flash next served down (2560 x 640, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
34 420 374 0.89 1216.2 1883.9 2873.2 5900.2
43 532 473 0.89 1480.7 2296.9 3444.9 7085.7
38 470 418 0.89 1337.2 2069.9 3104.2 6380.7
35 433 385 0.89 1248.8 1950.7 2941.3 6044.2

nemotron served up (1856 x 2688, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
220 320 1320 4.12 3994.2 3847.1 4012.4 7898.0
221 320 1326 4.14 4012.2 3857.1 4012.2 7901.6

nemotron served down (2688 x 1856, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
220 320 1320 4.12 3212.3 3769.2 3985.2 7646.5
221 320 1326 4.14 3231.1 3796.7 3984.8 7656.4

flash next served gate_up (1280 x 2560, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
39 482 429 0.89 1591.5 2338.1 5612.2 12964.6
40 495 440 0.89 1619.6 2422.3 5735.2 13259.3

flash next served down (2560 x 640, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
39 482 429 0.89 1355.7 2094.2 3172.3 6500.0
40 495 440 0.89 1385.9 2153.2 3240.5 6643.7

nemotron served up (1856 x 2688, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
222 320 1332 4.16 4022.4 3859.5 4010.4 7884.0

nemotron served down (2688 x 1856, group 64)

tokens items pairs pairs/item kp3 kp1 gemm block
222 320 1332 4.16 3229.3 3738.8 3991.4 7634.6

flash next served gate_up (1280 x 2560, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
41 507 451 0.89 1655.2 2437.4 5852.1 13511.1

flash next served down (2560 x 640, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
41 507 451 0.89 1422.0 2181.8 3300.7 6766.2

flash next served gate_up (1280 x 2560, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
42 519 462 0.89 1685.0 2494.4 5991.6 13819.4

flash next served down (2560 x 640, group 32)

tokens items pairs pairs/item kp3 kp1 gemm block
42 519 462 0.89 1443.4 2221.2 3368.2 6898.5

laudney and others added 8 commits October 29, 2026 23:45
A routed prompt's K-parallel tile on gfx1201 wins or loses by the
pairs a plan holds per item, which its items alone cannot tell. A
tuning row can now say the most pairs per item it takes, and the
registry refuses a plan with more, given the plan's pairs in its
shape. No table sets the field yet, so every choice stays the same;
a test keeps the field to routed prompt rows.
The registry can now bound a routed prompt by its pairs per item, so
serving passes each plan's pairs to the prompt tile's choice beside
its items, host-side only: the kernels' arguments keep their layout.
The affine fixtures pass theirs too, pickable sweeps a routed prompt
plan's pair counts, and the prompt path's byte check now compares
every launched entry, since all of them are the gemm family.
The tuner's routed cells held only Qwen3.6's geometry, so it could
not see that Nemotron's plans run slower on the K-parallel tile. Its
classes now carry each model's plan: Qwen3.6, Nemotron and Flash Next
with their experts, slots, shared slot and bucketed or exact sizing,
and a served plan without a shared slot draws distinct experts a
token, as serving does. Existing cases draw and digest as before.
Moving a routed prompt's items bound alone cannot both give Qwen3.6
the K-parallel tile and keep Nemotron's full plans off it, and when
kp3 refuses a plan, kp1 takes it first. The proposal now lives in a
host-tested search that moves kp3's items and pairs bound and kp1's
pairs bound together, scored with the per-cell veto on each whole
table, and the tuner times both sides of every pairs bound it tries.
Served runs on the R9700 put the routed K-parallel tile's threshold
between 3.43 and 3.75 pairs per item, which no whole number holds, so
the bound is now an f32 compared exactly in f64. The tuner tries the
least bound that takes each timed cell, times both sides of every
place its proposal changes a choice, and retakes a noisy timing, so
one noisy cell no longer vetoes a whole bucket by chance.
On gfx1201 the routed prompt's K-parallel tile beats the GEMM tile
for plans that hold few pairs an item and loses for full ones. Its row
now takes plans of up to 507 items and 3.5 pairs an item, from served
runs on Qwen3.6 and Nemotron: Qwen3.6's 33 to 128-token prompts fill
x0.53 to x0.80 and Nemotron's 129 to 186-token ones x0.82 to x1.00,
other sizes stay within noise, and every reply keeps its bytes.
With gfx1201 now shipping a pairs bound, the joint search's tests and
the entries' unbounded control started from a table that already set
it, so they could pass without the search or the field doing their
work. They now start from gfx1100's rows, the control probes above
3.5 pairs an item, and the registry's and gfx1201's comments say what
the final bound does and where its 3.5 came from.
@ashhart
ashhart merged commit f6aae83 into ashhart:main Oct 29, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HIP: bound the routed prompt's K-parallel tile by pairs per item, so gfx1201 can take it for Qwen3.6's short prompts

2 participants