From b31b709ec81b3e12645fb9291127b5818b67db0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20S=C5=82uszniak?= Date: Sun, 30 Aug 2026 15:12:42 +0200 Subject: [PATCH] [ET-VK] Avoid the near-square local work group on Adreno Adreno drivers miscompute the tiled GEMM family of shaders for 8x8x1 and 4x16x1 local work groups: entire work groups intermittently write garbage while every other block is bit-exact. These shaders have no shared memory and no barriers and their invocations are independent, so the result cannot legitimately depend on the group shape. Fix it in pick_xy_square_lwg, which all thirteen affected dispatches share: linear, matmul, conv2d_gemm, the pointwise convs, SDPA and the quantized variants. On Adreno use a 2:1 x:y shape, which yields 16x4x1 at the default 64 threads and is the cheapest correct shape measured; other vendors keep the square shape. Fixes #22327 --- backends/vulkan/runtime/graph/ops/impl/Common.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backends/vulkan/runtime/graph/ops/impl/Common.cpp b/backends/vulkan/runtime/graph/ops/impl/Common.cpp index a63b58b15b0..35b37dd28f4 100644 --- a/backends/vulkan/runtime/graph/ops/impl/Common.cpp +++ b/backends/vulkan/runtime/graph/ops/impl/Common.cpp @@ -132,6 +132,15 @@ LocalWorkGroup pick_required_lwg( return gwg.required_lwg_size(); } +// Adreno drivers miscompute the tiled GEMM family of shaders for near-square +// local work groups. With an 8x8x1 group (and with 4x16x1) entire work groups +// intermittently write garbage while every other block is bit-exact. These +// shaders have no shared memory and no barriers and their invocations are +// independent, so the result cannot legitimately depend on the group shape. +// A 2:1 x:y ratio, which yields 16x4x1 at the default 64 threads, is correct +// across every run measured and is the cheapest correct shape. See #22327. +const LwgShape kWideXLwg{2u, 1u, 0u}; + LocalWorkGroup pick_xy_square_lwg( ComputeGraph* graph, const vkapi::ShaderInfo& shader, @@ -142,7 +151,8 @@ LocalWorkGroup pick_xy_square_lwg( (void)args; (void)resize_args; LocalWorkGroup lwg( - kSquareLwg, graph->context()->adapter_ptr()->recommended_lwg_nthreads()); + graph->device_is_adreno() ? kWideXLwg : kSquareLwg, + graph->context()->adapter_ptr()->recommended_lwg_nthreads()); lwg.fit_to_global(gwg); return lwg; }