Skip to content

Misc. bug: Vulkan im2col / im2col_3d shaders write through buffer_reference without buffer_reference_align (VUID-RuntimeSpirv-PhysicalStorageBuffer64-06315) #28960

Description

@apollo-2006

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

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions