Skip to content

vulkan: int8 coopmat1 matmul implementation for AMD RDNA3 and RDNA4 - #27952

Open
0cc4m wants to merge 50 commits into
masterfrom
0cc4m/vulkan-coopmat-int8
Open

vulkan: int8 coopmat1 matmul implementation for AMD RDNA3 and RDNA4#27952
0cc4m wants to merge 50 commits into
masterfrom
0cc4m/vulkan-coopmat-int8

Conversation

@0cc4m

@0cc4m 0cc4m commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Overview

Based on @pwilkin's ideas in #27493, I finally managed to get coopmat1 int8 to work with good performance on RDNA3 and 4. This new MMQ cm1 shader supports q4_0, q4_1, q5_0, q5_1, q8_0, q3_k, q4_k, q5_k, q6_k, mxfp4, nvfp4 and iq4_nl on RDNA3 and RDNA4. Strix Halo prompt processing performance is significantly improved, RDNA4 is more neutral, but MoE prompt processing is also up significantly. The shader is limited to those two architectures since it hardcodes their specific coopmat access patterns. More architectures can be added if needed.

q4_1, q5_1, q4_k, q5_k and nvfp4 on RDNA4 are disabled for MUL_MAT since they run slower than existing fp16 matmul. Additionally nvfp4 is also disabled for MUL_MAT_ID.

Benchmarks

AMD Radeon 8060S (Strix Halo, RDNA3.5)

MUL_MAT test-backend-ops perf geomean us (lower = better)

quant vk-master vk-feat rocm-master feat vs master feat vs rocm
q4_0 5183 4016 5064 1.29x 1.26x
q4_1 5123 4157 5189 1.23x 1.25x
q5_0 5881 4340 5273 1.35x 1.21x
q5_1 5574 4271 5362 1.31x 1.26x
q8_0 5645 4443 5421 1.27x 1.22x
iq4_nl 5471 4535 5061 1.21x 1.12x
mxfp4 5205 4329 4903 1.20x 1.13x
q3_K 6352 5718 5974 1.11x 1.04x
q4_K 5535 4749 5304 1.17x 1.12x
q5_K 5637 4940 5437 1.14x 1.10x
q6_K 6545 5747 5323 1.14x 0.93x
nvfp4 5262 5430 6290 0.97x 1.16x

MUL_MAT_ID test-backend-ops perf geomean us (lower = better)

quant vk-master vk-feat rocm-master feat vs master feat vs rocm
q4_0 867 658 817 1.32x 1.24x
q4_1 869 663 875 1.31x 1.32x
q5_0 990 707 799 1.40x 1.13x
q5_1 962 691 785 1.39x 1.14x
q8_0 843 692 853 1.22x 1.23x
iq4_nl 951 723 747 1.32x 1.03x
mxfp4 925 703 727 1.32x 1.03x
q3_K 1138 856 853 1.33x 1.00x
q4_K 990 779 762 1.27x 0.98x
q5_K 994 824 844 1.21x 1.02x
q6_K 1094 899 1089 1.22x 1.21x
nvfp4 969 822 1121 1.18x 1.36x

llama-bench pp512 t/s (higher = better)

model quant kind vk-master vk-feat rocm-master feat vs master feat vs rocm
Meta-Llama-3-8B Q4_0 dense 862.7 1075.7 924.2 1.25x 1.16x
Meta-Llama-3-8B Q4_1 dense 937.3 1073.2 897.9 1.15x 1.20x
Meta-Llama-3.1-8B IQ4_NL dense 901.7 1035.1 934.3 1.15x 1.11x
Meta-Llama-3.1-8B Q3_K_S dense 791.3 867.3 830.0 1.10x 1.04x
Meta-Llama-3.1-8B Q4_K_S dense 874.3 975.1 907.1 1.12x 1.08x
Meta-Llama-3.1-8B Q6_K dense 772.2 862.9 729.4 1.12x 1.18x
Meta-Llama-3.1-8B Q8_0 dense 823.4 1030.5 874.4 1.25x 1.18x
llama2-13b-tiefighter Q5_K_M dense 515.0 547.1 519.6 1.06x 1.05x
Qwen3.8-27B Q4_K_M dense 186.5 254.1 237.6 1.36x 1.07x
gpt-oss-20b MXFP4 MoE 1071.6 1410.5 1005.8 1.32x 1.40x
Qwen3.6-35B-A3B Q4_0 MoE 883.7 1175.9 743.4 1.33x 1.58x
Qwen3.6-35B-A3B Q4_K_M MoE 777.8 1023.6 693.9 1.32x 1.48x
gemma-4-26B-A4B Q6_K MoE 737.2 925.5 723.1 1.26x 1.28x
chart_pp512
AMD Radeon AI PRO R9700 (RDNA4)

MUL_MAT test-backend-ops perf geomean us (lower = better)

quant vk-master vk-feat rocm-master feat vs master feat vs rocm RDNA4 MMQ
q4_0 1146 1120 1036 1.02x 0.93x on
q4_1 1123 1123 1189 1.00x 1.06x off (fallback)
q5_0 1378 1234 1116 1.12x 0.90x on
q5_1 1272 1273 1203 1.00x 0.94x off (fallback)
q8_0 1324 1179 1024 1.12x 0.87x on
iq4_nl 1304 1198 958 1.09x 0.80x on
mxfp4 1326 1202 960 1.10x 0.80x on
q3_K 1974 1616 1466 1.22x 0.91x on
q4_K 1372 1373 1153 1.00x 0.84x off (fallback)
q5_K 1433 1435 1180 1.00x 0.82x off (fallback)
q6_K 1746 1583 2395 1.10x 1.51x on
nvfp4 1330 1332 1554 1.00x 1.17x off (fallback)

MUL_MAT_ID test-backend-ops perf geomean us (lower = better)

quant vk-master vk-feat rocm-master feat vs master feat vs rocm RDNA4 MMQ
q4_0 210 243 202 0.86x 0.83x on
q4_1 205 253 219 0.81x 0.87x on
q5_0 249 265 210 0.94x 0.79x on
q5_1 227 260 219 0.87x 0.84x on
q8_0 228 252 194 0.90x 0.77x on
iq4_nl 237 259 195 0.92x 0.75x on
mxfp4 241 261 195 0.93x 0.75x on
q3_K 364 329 247 1.11x 0.75x on
q4_K 251 307 216 0.82x 0.71x on
q5_K 261 316 218 0.83x 0.69x on
q6_K 312 327 343 0.95x 1.05x on
nvfp4 242 243 282 1.00x 1.16x off (fallback)

llama-bench pp512 t/s (higher = better)

model quant kind vk-master vk-feat rocm-master feat vs master feat vs rocm
Llama-3-8B Q4_0 dense 4656 4584 4370 0.98x 1.05x
Llama-3-8B Q4_1 dense 4751 4771 3911 1.00x 1.22x
Llama-3-8B Q4_K_S dense 3881 3968 3887 1.02x 1.02x
Llama-3.1-8B IQ4_NL dense 4059 4169 4488 1.03x 0.93x
Llama-3.1-8B Q3_K_S dense 2882 3228 3321 1.12x 0.97x
Llama-3.1-8B Q6_K dense 3208 3259 2165 1.02x 1.51x
Llama-3.1-8B Q8_0 dense 4230 4378 4473 1.03x 0.98x
Mistral-Nemo-12B Q4_0 dense 2925 2882 2876 0.99x 1.00x
gemma-4-12B Q4_0 dense 2761 2711 2429 0.98x 1.12x
Qwen3.8-27B Q6_K dense 955 1040 764 1.09x 1.36x
gpt-oss-20B MXFP4 MoE 3936 5631 4231 1.43x 1.33x
Qwen3.6-35B-A3B Q4_0 MoE 3196 4046 2638 1.27x 1.53x
Qwen3.6-35B-A3B Q4_K_M MoE 2760 3365 2240 1.22x 1.50x
Muse-Glimmer-30B Q6_K MoE 995 1065 792 1.07x 1.34x
chart_pp512

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES, AI was used for optimization loops. Code and performance was manually checked/verified.

0cc4m and others added 30 commits August 29, 2026 11:30
Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
@github-actions github-actions Bot added Vulkan Issues specific to the Vulkan backend ggml changes relating to the ggml tensor library for machine learning labels Aug 29, 2026
@0cc4m
0cc4m marked this pull request as ready for review August 29, 2026 12:10
@0cc4m
0cc4m requested a review from a team as a code owner August 29, 2026 12:10
#define ACC_BIAS_F 12582912.0f
const bool USE_MAGIC_BIAS = WARP != 32;

// Accumulator row for element e: RDNA4 blocked, RDNA3/3.5 interleaved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these layouts entirely based on the hardware definition, or do they depend partly on the compiler. For example, at some point I changed the NVIDIA compiler so the layout of a 16x16 matrix in four registers was permuted to 0,2,1,3 vs earlier compiler versions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a little bit of both. I have confirmed that Linux' RADV driver based this layout on what the hardware requires, so it should be fixed. I have also checked that at least RDNA3.5 uses the same layout on the Windows driver, and this branch does improve performance there too.

I think we can replace this with a generic solution once enough drivers support coopmat maintenance1.

return;
}
#else
// L2-friendly workgroup scheduling

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be interesting to separate out what perf gain is from this vs using int8. I've been tempted to do something like this for the other shaders, but with ubatch=512 still being the default it usually doesn't matter much (probably helps more for stable diffusion kind of workloads)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very small, hard to measure. Maybe 2% on RDNA3.5, but my Strix Halo laptop has a lot of thermal noise in benchmarks, so not sure. Might not be worth it. I didn't measure a difference on RDNA4.

@edt-xx

edt-xx commented Sep 2, 2026

Copy link
Copy Markdown

Built b10760 + this pr. Using a RX7900XT (RDNA3) with RADV. Running usloth/Qwen3.8-27B-Q4_0.gguf before applying this PR I was seeing:

[35963] 0.10.092.723 I slot print_timing: id  0 | task 0 | prompt processing, n_tokens =   4096, progress = 0.05, t =   4.25 s / 963.84 tokens per second
...
[35963] 2.42.829.150 I slot print_timing: id  0 | task 0 | prompt processing, n_tokens =  75995, progress = 1.00, t = 156.13 s / 486.73 tokens per second

after the same sort of prefill gets (+8% at start to +3% at end of prefill)

[40189] 181.52.418.736 I slot print_timing: id  0 | task 2568 | prompt processing, n_tokens =   4096, progress = 0.05, t =   3.92 s / 1046.10 tokens per second
...
[40189] 184.24.107.728 I slot print_timing: id  0 | task 2568 | prompt processing, n_tokens =  77865, progress = 1.00, t = 156.04 s / 498.99 tokens per second

There is too much variance in token gen to say anything. This has positive effects in a real use case.

@NickM-27

NickM-27 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Apologies if this is not helpful / spam, but I have been running this on my 7900XTX for a few days and it has been a big improvement, so wanted to share a before / after llama bench run:

master:

ggml_vulkan: Found 1 Vulkan devices:
ggml_vulkan: 0 = AMD Radeon RX 7900 XTX (RADV NAVI31) (radv) | uma: 0 | fp16: 1 | bf16: 0 | fp4: 0 | warp size: 64 | shared memory: 65536 | int dot: 1 | matrix cores: KHR_coopmat
load_backend: loaded Vulkan backend from /app/libggml-vulkan.so
load_backend: loaded CPU backend from /app/libggml-cpu-alderlake.so
| model                          |       size |     params | backend    | ngl | n_ubatch |  fa |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -------: | --: | --------------: | -------------------: |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |           pp512 |      3410.53 ± 22.72 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |           tg128 |        135.64 ± 0.80 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |   pp512 @ d8192 |      2477.27 ± 76.78 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |   tg128 @ d8192 |        120.42 ± 0.46 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |  pp512 @ d16384 |      2130.36 ± 35.16 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |  tg128 @ d16384 |        118.42 ± 0.14 |

this PR:

ggml_vulkan: Found 1 Vulkan devices:
ggml_vulkan: 0 = AMD Radeon RX 7900 XTX (RADV NAVI31) (radv) | uma: 0 | fp16: dot2 | bf16: 1 | fp4: 0 | warp size: 64 | shared memory: 65536 | int dot: 1 | matrix cores: KHR_coopmat
load_backend: loaded Vulkan backend from /app/libggml-vulkan.so
load_backend: loaded CPU backend from /app/libggml-cpu-alderlake.so
| model                          |       size |     params | backend    | ngl | n_ubatch |  fa |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -------: | --: | --------------: | -------------------: |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |           pp512 |     4331.21 ± 132.67 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |           tg128 |        142.76 ± 0.92 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |   pp512 @ d8192 |      2885.67 ± 80.24 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |   tg128 @ d8192 |        125.29 ± 0.14 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |  pp512 @ d16384 |      2402.13 ± 44.16 |
| gemma4 26B.A4B Q4_0            |  13.26 GiB |    25.23 B | Vulkan     |  -1 |     1024 |   1 |  tg128 @ d16384 |        120.82 ± 0.18 |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ggml changes relating to the ggml tensor library for machine learning Vulkan Issues specific to the Vulkan backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants