From 87eddf753e5d7209dc5d30ffbfe9ceec98792cae Mon Sep 17 00:00:00 2001 From: Jianhui Dai Date: Mon, 1 Sep 2025 15:35:35 +0800 Subject: [PATCH 1/5] [webgpu] Normalize `Transpose` dispatch group size --- onnxruntime/core/providers/webgpu/nn/conv.cc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv.cc b/onnxruntime/core/providers/webgpu/nn/conv.cc index 1aa7b5d161b87..858d8327fd56c 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv.cc @@ -8,6 +8,15 @@ #include "core/providers/webgpu/nn/grouped_conv.h" #include "core/providers/webgpu/webgpu_utils.h" #include "core/providers/webgpu/math/matmul.h" + +namespace { + +inline uint32_t ceil_div(int64_t numerator, int32_t denominator) { + return static_cast((numerator + denominator - 1) / denominator); +} + +} // namespace + namespace onnxruntime { namespace webgpu { @@ -19,6 +28,13 @@ Status TransposeKernel(ComputeContext& context, const Tensor* kernel, const Tens transposed_kernel_shape_vector[i] = kernel_shape[perm[i]]; } uint32_t output_size = onnxruntime::narrow(kernel_shape.Size()); + + // Normalize dispatch = ceil_div(output_size, 64) + ORT_ENFORCE(rank == static_cast(4), "Input tensor must have rank 4."); + uint32_t dispatch_x = onnxruntime::narrow(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1]); + uint32_t dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 8); + uint32_t dispatch_z = ceil_div(transposed_kernel_shape_vector[3], 8); + TensorShape transposed_kernel_shape(transposed_kernel_shape_vector); *transposed_kernel = context.CreateGPUTensor(kernel->DataType(), transposed_kernel_shape); bool use_shared = false; @@ -28,7 +44,8 @@ Status TransposeKernel(ComputeContext& context, const Tensor* kernel, const Tens .AddInput({kernel, ProgramTensorMetadataDependency::TypeAndRank, kernel_shape, 1}) .AddOutput({transposed_kernel, ProgramTensorMetadataDependency::TypeAndRank}) .AddUniformVariable({output_size}) - .SetDispatchGroupSize((output_size + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE); + .SetWorkgroupSize(64) + .SetDispatchGroupSize(dispatch_x, dispatch_y, dispatch_z); return context.RunProgram(program); } From ed4e828b96a49d3ad91957b9d0ac42e16ce639f9 Mon Sep 17 00:00:00 2001 From: Jianhui Dai Date: Mon, 1 Sep 2025 16:21:38 +0800 Subject: [PATCH 2/5] Prefer even dispatch --- onnxruntime/core/providers/webgpu/nn/conv.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv.cc b/onnxruntime/core/providers/webgpu/nn/conv.cc index 858d8327fd56c..5ede36d4ed50d 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv.cc @@ -31,8 +31,8 @@ Status TransposeKernel(ComputeContext& context, const Tensor* kernel, const Tens // Normalize dispatch = ceil_div(output_size, 64) ORT_ENFORCE(rank == static_cast(4), "Input tensor must have rank 4."); - uint32_t dispatch_x = onnxruntime::narrow(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1]); - uint32_t dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 8); + uint32_t dispatch_x = ceil_div(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1], 2); + uint32_t dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 4); uint32_t dispatch_z = ceil_div(transposed_kernel_shape_vector[3], 8); TensorShape transposed_kernel_shape(transposed_kernel_shape_vector); From bcda91aaa8b871805680adcb96a506492ae03b8e Mon Sep 17 00:00:00 2001 From: Jianhui Dai Date: Mon, 1 Sep 2025 16:29:59 +0800 Subject: [PATCH 3/5] Limit intel GPUs --- onnxruntime/core/providers/webgpu/nn/conv.cc | 21 +++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv.cc b/onnxruntime/core/providers/webgpu/nn/conv.cc index 5ede36d4ed50d..dbaa98ae66441 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv.cc @@ -29,11 +29,22 @@ Status TransposeKernel(ComputeContext& context, const Tensor* kernel, const Tens } uint32_t output_size = onnxruntime::narrow(kernel_shape.Size()); - // Normalize dispatch = ceil_div(output_size, 64) - ORT_ENFORCE(rank == static_cast(4), "Input tensor must have rank 4."); - uint32_t dispatch_x = ceil_div(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1], 2); - uint32_t dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 4); - uint32_t dispatch_z = ceil_div(transposed_kernel_shape_vector[3], 8); + uint32_t dispatch_x = ceil_div(output_size, 64); + uint32_t dispatch_y = 1; + uint32_t dispatch_z = 1; + + // This temporary workaround addresses a significant performance bottleneck + // (10x slower) for the shape (3, 3, 2560, 1280) due to an issue with Intel's + // GPU drivers. We manually normalize the dispatch group size to restore + // performance. + // + // TODO: Revert this change once the driver issue is fixed. + if (context.AdapterInfo().vendor == std::string_view{"intel"}) { + ORT_ENFORCE(rank == static_cast(4), "Input tensor must have rank 4."); + uint32_t dispatch_x = ceil_div(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1], 2); + uint32_t dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 4); + uint32_t dispatch_z = ceil_div(transposed_kernel_shape_vector[3], 8); + } TensorShape transposed_kernel_shape(transposed_kernel_shape_vector); *transposed_kernel = context.CreateGPUTensor(kernel->DataType(), transposed_kernel_shape); From efff121c0f02bd3238e719d03de95c41b7c84040 Mon Sep 17 00:00:00 2001 From: Jianhui Dai Date: Mon, 1 Sep 2025 16:36:56 +0800 Subject: [PATCH 4/5] fix build --- onnxruntime/core/providers/webgpu/nn/conv.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv.cc b/onnxruntime/core/providers/webgpu/nn/conv.cc index dbaa98ae66441..6c365fde48a7b 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv.cc @@ -41,9 +41,9 @@ Status TransposeKernel(ComputeContext& context, const Tensor* kernel, const Tens // TODO: Revert this change once the driver issue is fixed. if (context.AdapterInfo().vendor == std::string_view{"intel"}) { ORT_ENFORCE(rank == static_cast(4), "Input tensor must have rank 4."); - uint32_t dispatch_x = ceil_div(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1], 2); - uint32_t dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 4); - uint32_t dispatch_z = ceil_div(transposed_kernel_shape_vector[3], 8); + dispatch_x = ceil_div(transposed_kernel_shape_vector[0] * transposed_kernel_shape_vector[1], 2); + dispatch_y = ceil_div(transposed_kernel_shape_vector[2], 4); + dispatch_z = ceil_div(transposed_kernel_shape_vector[3], 8); } TensorShape transposed_kernel_shape(transposed_kernel_shape_vector); From 7261be476030fa84a8e3f8740c450a07884ddddf Mon Sep 17 00:00:00 2001 From: Jianhui Dai Date: Thu, 4 Sep 2025 13:48:46 +0800 Subject: [PATCH 5/5] Update comment --- onnxruntime/core/providers/webgpu/nn/conv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv.cc b/onnxruntime/core/providers/webgpu/nn/conv.cc index 6c365fde48a7b..7f82f85fc8f91 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv.cc @@ -34,7 +34,7 @@ Status TransposeKernel(ComputeContext& context, const Tensor* kernel, const Tens uint32_t dispatch_z = 1; // This temporary workaround addresses a significant performance bottleneck - // (10x slower) for the shape (3, 3, 2560, 1280) due to an issue with Intel's + // (~12x slower) for the shape (3, 3, 2560, 1280) due to an issue with Intel's // GPU drivers. We manually normalize the dispatch group size to restore // performance. //