Skip to content

Commit c70b342

Browse files
committed
Fix WebGPU Conv auto_pad=SAME_UPPER padding calculation
The WebGPU Conv and ConvTranspose operators were producing incorrect results when using auto_pad=SAME_UPPER with strides > 1. Root cause: The head padding values were being unnecessarily recalculated after InferPadsAndOutputShape() had already computed the correct values. The recalculation formula could produce incorrect results. Fix: Simply use pads[0] and pads[1] directly, which already contain the correct head padding values computed upstream. This matches the behavior of the TypeScript implementation. Fixes #26734
1 parent 260a48c commit c70b342

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

onnxruntime/core/providers/webgpu/nn/conv.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ Status Conv<is_channels_last, is_fused>::ComputeInternal(ComputeContext& context
119119
const auto output_height = output_shape_vector[is_channels_last ? 1 : 2];
120120
const auto output_width = output_shape_vector[is_channels_last ? 2 : 3];
121121

122-
uint32_t auto_pad_adjust = conv_attrs_.auto_pad == AutoPadType::SAME_LOWER ? 1 : 0;
123-
auto pad0 = conv_attrs_.auto_pad == AutoPadType::NOTSET ? pads[0] : (pads[0] + pads[2] + auto_pad_adjust) / 2;
124-
auto pad1 = conv_attrs_.auto_pad == AutoPadType::NOTSET ? pads[1] : (pads[1] + pads[3] + auto_pad_adjust) / 2;
125-
std::vector<uint32_t> updated_pads{pad0, pad1};
122+
// pads[0] and pads[1] already contain the correct head (beginning) padding values
123+
// computed by InferPadsAndOutputShape() which handles auto_pad correctly.
124+
// For SAME_UPPER: head gets less padding (pad_needed / 2)
125+
// For SAME_LOWER: head gets more padding ((pad_needed + 1) / 2)
126+
std::vector<uint32_t> updated_pads{pads[0], pads[1]};
126127

127128
if (CanApplyIm2ColMatMulProgram(context,
128129
is_channels_last,

onnxruntime/core/providers/webgpu/nn/conv_transpose.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,11 @@ Status ConvTranspose<is_channels_last>::ComputeInternal(ComputeContext& context)
8787
inputs.push_back(bias);
8888
input_output_shapes.push_back(bias->Shape());
8989
}
90-
uint32_t auto_pad_adjust = conv_transpose_attrs_.auto_pad == AutoPadType::SAME_LOWER ? 1 : 0;
91-
auto pad0 = conv_transpose_attrs_.auto_pad == AutoPadType::NOTSET ? pads[0] : (pads[0] + pads[2] + auto_pad_adjust) / 2;
92-
auto pad1 = conv_transpose_attrs_.auto_pad == AutoPadType::NOTSET ? pads[1] : (pads[1] + pads[3] + auto_pad_adjust) / 2;
90+
// pads[0] and pads[1] already contain the correct head (beginning) padding values
91+
// computed by ComputePadsAndOutputShape() which handles auto_pad correctly.
9392
Tensor* output = context.Output(0, computed_output_shape);
9493
input_output_shapes.push_back(output_shape);
95-
auto program = CreateConvTranspose2DProgram(inputs, {pad0, pad1}, strides, dilations, output, is_channels_last, input_output_shapes, static_cast<uint32_t>(conv_transpose_attrs_.group));
94+
auto program = CreateConvTranspose2DProgram(inputs, {pads[0], pads[1]}, strides, dilations, output, is_channels_last, input_output_shapes, static_cast<uint32_t>(conv_transpose_attrs_.group));
9695
return context.RunProgram(program);
9796
}
9897

0 commit comments

Comments
 (0)