From 1488dc3a35d21b512437cf3a69cec8c344a637ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:21:30 +0000 Subject: [PATCH 01/12] Initial plan From d3658b02d8f28b4994c602bb5174140f57e63d1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:28:43 +0000 Subject: [PATCH 02/12] Enhance ConvTranspose bias validation with better error messages Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- .../lib/wasm/jsep/webgpu/ops/conv-transpose.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts index 18bf30a325d83..01863d36f4aa7 100644 --- a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts +++ b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts @@ -178,11 +178,19 @@ const validateInputs = (inputs: readonly TensorView[], attributes: ConvTranspose throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL'); } - const featureMaps = inputs[1].dims[1] * attributes.group; - // if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps - if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) { - throw new Error('invalid bias'); + if (inputs.length === 3) { + if (!inputs[2] || !inputs[2].dims) { + throw new Error('invalid bias: bias tensor is malformed'); + } + if (inputs[2].dims.length !== 1) { + throw new Error('invalid bias: bias must be 1D tensor'); + } + const group = attributes.group || 1; // default to 1 if not specified + const featureMaps = inputs[1].dims[1] * group; + if (inputs[2].dims[0] !== featureMaps) { + throw new Error(`invalid bias: bias size (${inputs[2].dims[0]}) must be equal to output channels (${featureMaps})`); + } } const spatialRank = inputs[0].dims.length - 2; From a7b6b3afc63609ee91c10a348c1e3cfa4c2ce886 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:31:43 +0000 Subject: [PATCH 03/12] Address code review feedback - use nullish coalescing and remove redundant check Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts index 01863d36f4aa7..c523e5b9f8beb 100644 --- a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts +++ b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts @@ -180,13 +180,10 @@ const validateInputs = (inputs: readonly TensorView[], attributes: ConvTranspose // if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps if (inputs.length === 3) { - if (!inputs[2] || !inputs[2].dims) { - throw new Error('invalid bias: bias tensor is malformed'); - } if (inputs[2].dims.length !== 1) { throw new Error('invalid bias: bias must be 1D tensor'); } - const group = attributes.group || 1; // default to 1 if not specified + const group = attributes.group ?? 1; // default to 1 if not specified (per ONNX spec) const featureMaps = inputs[1].dims[1] * group; if (inputs[2].dims[0] !== featureMaps) { throw new Error(`invalid bias: bias size (${inputs[2].dims[0]}) must be equal to output channels (${featureMaps})`); From 583f08bba49a958a2e574000a99b9c27d223b737 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:34:20 +0000 Subject: [PATCH 04/12] Fix group attribute default at parse time instead of validation time Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts index c523e5b9f8beb..72bd689f8b19b 100644 --- a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts +++ b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts @@ -132,7 +132,7 @@ export const parseConvTransposeAttributes = (attributes: Record typeof attributes.autoPad == 'undefined' ? 0 : (attributes.autoPad as number) ]; const dilations = attributes.dilations as [number, number]; - const group = attributes.group as number; + const group = (attributes.group as number) ?? 1; // default to 1 per ONNX spec const kernelShape = attributes.kernelShape as [number, number]; const pads = attributes.pads as [number, number, number, number]; const strides = attributes.strides as [number, number]; @@ -183,8 +183,7 @@ const validateInputs = (inputs: readonly TensorView[], attributes: ConvTranspose if (inputs[2].dims.length !== 1) { throw new Error('invalid bias: bias must be 1D tensor'); } - const group = attributes.group ?? 1; // default to 1 if not specified (per ONNX spec) - const featureMaps = inputs[1].dims[1] * group; + const featureMaps = inputs[1].dims[1] * attributes.group; if (inputs[2].dims[0] !== featureMaps) { throw new Error(`invalid bias: bias size (${inputs[2].dims[0]}) must be equal to output channels (${featureMaps})`); } From 0d53e118ab45de14b175a1477278e13e718bbdde Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:44:11 +0000 Subject: [PATCH 05/12] Add bias validation to C++ WebGPU ConvTranspose implementation Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- .../core/providers/webgpu/nn/conv_transpose.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index 84a0afd873d23..92a91c228406f 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -57,6 +57,19 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) bool has_bias = context.InputCount() > 2; const auto* bias = has_bias ? context.Input(2) : nullptr; + + // Validate bias shape if provided + if (has_bias) { + const auto& bias_shape = bias->Shape(); + if (bias_shape.NumDimensions() != 1) { + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias must be 1D tensor"); + } + if (bias_shape[0] != num_output_channels) { + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias size (", bias_shape[0], + ") must be equal to output channels (", num_output_channels, ")"); + } + } + if (input_shape.NumDimensions() == 3 && filter_shape.NumDimensions() == 3) { // ConvTranspose1D TensorShapeVector input_shape_vector = input_shape.AsShapeVector(); From d8dc88ac83371abc1659185435df24fa6b20f704 Mon Sep 17 00:00:00 2001 From: Guenther Schmuelling Date: Fri, 30 Jan 2026 08:51:59 -0800 Subject: [PATCH 06/12] Apply suggestion from @github-actions[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- onnxruntime/core/providers/webgpu/nn/conv_transpose.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index 92a91c228406f..dc116fbf50ac3 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -69,7 +69,6 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) ") must be equal to output channels (", num_output_channels, ")"); } } - if (input_shape.NumDimensions() == 3 && filter_shape.NumDimensions() == 3) { // ConvTranspose1D TensorShapeVector input_shape_vector = input_shape.AsShapeVector(); From 7c969c5c6a516b896f83a405921f08fee4c47d5f Mon Sep 17 00:00:00 2001 From: Guenther Schmuelling Date: Fri, 30 Jan 2026 08:52:09 -0800 Subject: [PATCH 07/12] Apply suggestion from @github-actions[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- onnxruntime/core/providers/webgpu/nn/conv_transpose.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index dc116fbf50ac3..e889b34c3f5c5 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -57,7 +57,6 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) bool has_bias = context.InputCount() > 2; const auto* bias = has_bias ? context.Input(2) : nullptr; - // Validate bias shape if provided if (has_bias) { const auto& bias_shape = bias->Shape(); From cf7246424caf680c6a5caf4d2ca66c7968618b81 Mon Sep 17 00:00:00 2001 From: Guenther Schmuelling Date: Fri, 30 Jan 2026 08:52:21 -0800 Subject: [PATCH 08/12] Apply suggestion from @github-actions[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- onnxruntime/core/providers/webgpu/nn/conv_transpose.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index e889b34c3f5c5..fc37ec9c8bcee 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -64,7 +64,7 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias must be 1D tensor"); } if (bias_shape[0] != num_output_channels) { - return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias size (", bias_shape[0], + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias size (", bias_shape[0], ") must be equal to output channels (", num_output_channels, ")"); } } From 7c55b812412d06a03ff16ccb8b52f4689af292cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:55:17 +0000 Subject: [PATCH 09/12] Run prettier to fix formatting in conv-transpose.ts Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts index 72bd689f8b19b..719f2cf344d09 100644 --- a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts +++ b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts @@ -132,7 +132,7 @@ export const parseConvTransposeAttributes = (attributes: Record typeof attributes.autoPad == 'undefined' ? 0 : (attributes.autoPad as number) ]; const dilations = attributes.dilations as [number, number]; - const group = (attributes.group as number) ?? 1; // default to 1 per ONNX spec + const group = (attributes.group as number) ?? 1; // default to 1 per ONNX spec const kernelShape = attributes.kernelShape as [number, number]; const pads = attributes.pads as [number, number, number, number]; const strides = attributes.strides as [number, number]; @@ -185,7 +185,9 @@ const validateInputs = (inputs: readonly TensorView[], attributes: ConvTranspose } const featureMaps = inputs[1].dims[1] * attributes.group; if (inputs[2].dims[0] !== featureMaps) { - throw new Error(`invalid bias: bias size (${inputs[2].dims[0]}) must be equal to output channels (${featureMaps})`); + throw new Error( + `invalid bias: bias size (${inputs[2].dims[0]}) must be equal to output channels (${featureMaps})`, + ); } } From 4c850b71c1d78b8e86a19975edb1daa0a2240046 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:17:50 +0000 Subject: [PATCH 10/12] Merge bias validation conditions and simplify error message Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts | 14 ++++---------- .../core/providers/webgpu/nn/conv_transpose.cc | 13 ++++--------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts index 719f2cf344d09..994aeb83a0ed5 100644 --- a/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts +++ b/js/web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts @@ -178,17 +178,11 @@ const validateInputs = (inputs: readonly TensorView[], attributes: ConvTranspose throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL'); } + const featureMaps = inputs[1].dims[1] * attributes.group; + // if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps - if (inputs.length === 3) { - if (inputs[2].dims.length !== 1) { - throw new Error('invalid bias: bias must be 1D tensor'); - } - const featureMaps = inputs[1].dims[1] * attributes.group; - if (inputs[2].dims[0] !== featureMaps) { - throw new Error( - `invalid bias: bias size (${inputs[2].dims[0]}) must be equal to output channels (${featureMaps})`, - ); - } + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) { + throw new Error('invalid bias'); } const spatialRank = inputs[0].dims.length - 2; diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index fc37ec9c8bcee..68a905909e767 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -57,17 +57,12 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) bool has_bias = context.InputCount() > 2; const auto* bias = has_bias ? context.Input(2) : nullptr; + // Validate bias shape if provided - if (has_bias) { - const auto& bias_shape = bias->Shape(); - if (bias_shape.NumDimensions() != 1) { - return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias must be 1D tensor"); - } - if (bias_shape[0] != num_output_channels) { - return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias: bias size (", bias_shape[0], - ") must be equal to output channels (", num_output_channels, ")"); - } + if (has_bias && (bias->Shape().NumDimensions() != 1 || bias->Shape()[0] != num_output_channels)) { + return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias"); } + if (input_shape.NumDimensions() == 3 && filter_shape.NumDimensions() == 3) { // ConvTranspose1D TensorShapeVector input_shape_vector = input_shape.AsShapeVector(); From fcdab4f9e9b53c7112205769c495696406f754ad Mon Sep 17 00:00:00 2001 From: Guenther Schmuelling Date: Thu, 5 Feb 2026 11:26:42 -0800 Subject: [PATCH 11/12] Apply suggestion from @github-actions[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- onnxruntime/core/providers/webgpu/nn/conv_transpose.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index 68a905909e767..88bd3545f937a 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -57,7 +57,6 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) bool has_bias = context.InputCount() > 2; const auto* bias = has_bias ? context.Input(2) : nullptr; - // Validate bias shape if provided if (has_bias && (bias->Shape().NumDimensions() != 1 || bias->Shape()[0] != num_output_channels)) { return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias"); From 9c9ef075e4a5fcea1b8419108a2569ab7ea45177 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:00:07 +0000 Subject: [PATCH 12/12] Fix formatting with lintrunner Co-authored-by: guschmue <22941064+guschmue@users.noreply.github.com> --- onnxruntime/core/providers/webgpu/nn/conv_transpose.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc index 88bd3545f937a..c3842a5c875e3 100644 --- a/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/webgpu/nn/conv_transpose.cc @@ -61,7 +61,7 @@ Status ConvTranspose::ComputeInternal(ComputeContext& context) if (has_bias && (bias->Shape().NumDimensions() != 1 || bias->Shape()[0] != num_output_channels)) { return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "invalid bias"); } - + if (input_shape.NumDimensions() == 3 && filter_shape.NumDimensions() == 3) { // ConvTranspose1D TensorShapeVector input_shape_vector = input_shape.AsShapeVector();