Name and Version
commit 96ffdc4 (master, 2026-09-14), built locally with -DGGML_VULKAN=ON, GNU 16.2.1, Linux x86_64
ggml_vulkan: 0 = AMD Radeon RX 9070 XT (RADV GFX1201) (radv) | uma: 0 | fp16: dot2 | bf16: 1 | fp4: 0 | warp size: 64 | shared memory: 65536 | int dot: 1 | matrix cores: KHR_coopmat
Operating systems
Linux
Which llama.cpp modules do you know to be affected?
Other (Please specify in the next section)
Command line
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation VK_LAYER_GPUAV_ENABLE=1 \
./build/bin/test-backend-ops test -b Vulkan0 -o IM2COL
# same for -o IM2COL_3D
Problem description & steps to reproduce
Affected module: ggml-vulkan, the im2col and im2col_3d compute shaders.
Both shaders declare their output pointer type with buffer_reference but no buffer_reference_align. Without it, glslang emits every OpStore through that pointer with Aligned 16, but the shaders advance the pointer by D_SIZE (4 bytes for f32, 2 for f16), so most writes land on addresses that aren't 16-byte aligned. Under the PhysicalStorageBuffer64 addressing model the spec requires the pointer to be at least as aligned as the Aligned operand says, so this is undefined behavior. RADV happens to produce correct results today, which is why tests pass, but another driver (or a future RADV) is free to miscompile or fault on it.
Found by running test-backend-ops with Vulkan validation layers and GPU-AV enabled.
Declarations:
ggml/src/ggml-vulkan/vulkan-shaders/im2col.comp:34
ggml/src/ggml-vulkan/vulkan-shaders/im2col_3d.comp:53
layout (buffer_reference) buffer D_ptr {D_TYPE d;};
- Writes:
D_ptr(current_dst_addr).d = D_TYPE(val); with current_dst_addr += bda_step; where bda_step = D_SIZE * BLOCK_SIZE and D_SIZE is 4 (f32) or 2 (f16), see vulkan-shaders-gen.cpp:1109-1110
- VUID:
VUID-RuntimeSpirv-PhysicalStorageBuffer64-06315
| op |
as is |
with buffer_reference_align = D_SIZE |
| IM2COL |
92/92 tests passed, 06315 reported |
92/92 tests passed, 0 validation messages |
| IM2COL_3D |
2051/2051 tests passed, 06315 reported |
2051/2051 tests passed, 0 validation messages |
Candidate change (both files):
-layout (buffer_reference) buffer D_ptr {D_TYPE d;};
+layout (buffer_reference, buffer_reference_align = D_SIZE) buffer D_ptr {D_TYPE d;};
This only tells the compiler the real alignment of the pointer, so it shouldn't change results on drivers that already behave. I'm happy to open the PR with this change if it looks right.
First Bad Commit
d8359f5 vulkan: 64-bit im2col (#16135)
Relevant log output
Logs
Validation Error: [ VUID-RuntimeSpirv-PhysicalStorageBuffer64-06315 ] | MessageID = 0x74774701
vkCmdDispatch(): Unaligned pointer access: The OpStore at buffer device address 0xffff8001045e3304 is not aligned to the instruction Aligned operand of 16.
Address belongs to the follwing buffer(s):
VkBuffer 0x120000000012, size: 8126464 bytes, range: [0xffff800104200000, 0xffff8001049c0000)
Stage = Compute. Global invocation ID (x, y, z) = (1, 365, 0)
Command buffer (0x5589bab1c900)
Compute Dispatch Index 0
SPIR-V Instruction: OpStore %572 %650 2 16
The Vulkan spec states: If the PhysicalStorageBuffer64 addressing model is enabled the pointer value of a memory access instruction must be at least as aligned as specified by the Aligned memory access operand
Name and Version
commit 96ffdc4 (master, 2026-09-14), built locally with -DGGML_VULKAN=ON, GNU 16.2.1, Linux x86_64
ggml_vulkan: 0 = AMD Radeon RX 9070 XT (RADV GFX1201) (radv) | uma: 0 | fp16: dot2 | bf16: 1 | fp4: 0 | warp size: 64 | shared memory: 65536 | int dot: 1 | matrix cores: KHR_coopmat
Operating systems
Linux
Which llama.cpp modules do you know to be affected?
Other (Please specify in the next section)
Command line
Problem description & steps to reproduce
Affected module: ggml-vulkan, the
im2colandim2col_3dcompute shaders.Both shaders declare their output pointer type with
buffer_referencebut nobuffer_reference_align. Without it, glslang emits everyOpStorethrough that pointer withAligned 16, but the shaders advance the pointer byD_SIZE(4 bytes for f32, 2 for f16), so most writes land on addresses that aren't 16-byte aligned. Under the PhysicalStorageBuffer64 addressing model the spec requires the pointer to be at least as aligned as theAlignedoperand says, so this is undefined behavior. RADV happens to produce correct results today, which is why tests pass, but another driver (or a future RADV) is free to miscompile or fault on it.Found by running
test-backend-opswith Vulkan validation layers and GPU-AV enabled.Declarations:
ggml/src/ggml-vulkan/vulkan-shaders/im2col.comp:34ggml/src/ggml-vulkan/vulkan-shaders/im2col_3d.comp:53D_ptr(current_dst_addr).d = D_TYPE(val);withcurrent_dst_addr += bda_step;wherebda_step = D_SIZE * BLOCK_SIZEandD_SIZEis 4 (f32) or 2 (f16), seevulkan-shaders-gen.cpp:1109-1110VUID-RuntimeSpirv-PhysicalStorageBuffer64-06315buffer_reference_align = D_SIZECandidate change (both files):
This only tells the compiler the real alignment of the pointer, so it shouldn't change results on drivers that already behave. I'm happy to open the PR with this change if it looks right.
First Bad Commit
d8359f5 vulkan: 64-bit im2col (#16135)
Relevant log output
Logs