Skip to content

[WebGPU] Add 3D ConvTranspose support - #32688

Merged
Jiajia Qin (qjia7) merged 1 commit into
microsoft:mainfrom
gyagp:fix/webgpu-convtranspose3d-28356
Oct 8, 2026
Merged

Jiajia Qin (qjia7) merged 1 commit into
microsoft:mainfrom
gyagp:fix/webgpu-convtranspose3d-28356

Conversation

@gyagp

@gyagp Yang Gu (gyagp) commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Description

Add 3D ConvTranspose support to the WebGPU execution provider. Five-dimensional inputs, including float16 inputs, now execute instead of failing with "Only Conv2d or Conv1d are supported."

  • Implement the WGSL kernel for NCDHW and NDHWC layouts, grouped and depthwise convolution, bias, strides, dilation, asymmetric and automatic padding, output padding, and explicit output shapes. Use signed integer coordinates and float32 accumulation for float16 inputs.
  • Prepack rank-5 initializer weights into [kD, kH, kW, C_out/group, C_in] and use group-aligned scalar/vec2/vec4 channel loads. Preserve the original layout for dynamic weights and distinguish layouts and vector widths in the shader cache.
  • Add 176 parameterized cases under onnxruntime/test/providers/webgpu/nn/conv_transpose_test.cc, comparing WebGPU with CPU results and disabling CPU fallback. Run each case twice and assert the prepacked-weight count. Enable existing 3D ConvTranspose and four float16 Conv3D tests for WebGPU.
  • Update operator support documentation and add the required ConvTranspose3D generated snapshots. The independent source-reference whitespace cleanup was merged separately in [WebGPU] Trim generated WGSL source-reference whitespaceΒ #32736; existing generated shader headers match the upstream base.

Motivation and Context

Fixes #28356. The supplied float16 model requires 3D ConvTranspose, which the WebGPU provider previously rejected.

Validation

  • Windows Release/D3D12, rebuilt with 12 parallel workers on 2026-10-08: onnxruntime_provider_test --gtest_filter="*ConvTranspose*:*Conv3D*:ConvFp16Test.*" β€” 308 passed, 9 expected skips, including all 176 ConvTranspose3D cases and all four enabled FP16 Conv3D cases.
  • Skips cover four CUDA/DML-only cases, two tests requesting unreleased opset 27, one Arm64-only CPU FP16 case, and two CPU prepacking cases unsupported by this configuration.
  • The relocated ConvTranspose test source is registered exactly once. Its test identities, inputs, expected results, and prepack-count assertions are preserved.
  • C++ lintrunner and git diff --check passed.
  • Earlier validation on the same base: 89 WGSL generator tests passed, covering both generation modes. The templates and generated shader code are unchanged by this test cleanup; all fourteen pre-existing generated shader headers match the upstream base.
  • Earlier validation of the initial implementation, before the prepacking follow-up: the supplied model ran with CPU fallback disabled (109 optimized WebGPU nodes, including four ConvTranspose3D dispatches), and all four extracted ConvTranspose layers matched CPU references at atol=rtol=0.001. Full-model output did not meet atol=rtol=0.01 against the supplied PyTorch reference: mean absolute error 0.0267, maximum 0.78125, and channel argmax agreement 99.9863%; differences already appeared before the first ConvTranspose. This full-model comparison has not been rerun after prepacking.
  • Browser/WASM and plugin builds were not rebuilt locally. No performance speedup has been measured.

Copilot AI balanced review requested due to automatic review settings September 18, 2026 08:33
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@gyagp

Copy link
Copy Markdown
Contributor Author

Jiajia Qin (@qjia7) PTAL

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ”΅ Needs a closer look

The new cross-layout GPU kernel and shared FP16 test behavior still need human review, particularly because browser/WASM and plugin builds were not validated.

Pull request overview

Adds WebGPU support for 3D ConvTranspose, addressing #28356.

Changes:

  • Implements NCDHW/NDHWC ConvTranspose3D with FP16 accumulation support.
  • Adds broad kernel and ShaderF16 capability tests.
  • Updates generated WGSL artifacts and operator documentation.
File summaries
File Description
tools/python/wgsl_template/test/test_generator.py Tests whitespace-free source references.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/string_table.h Updates generated shader strings.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/index.h Registers the new template.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/index_impl.h Includes generated ConvTranspose3D code.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/tensor/pad.h Refreshes generated output.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/tensor/oihw_to_ohwi.h Refreshes generated output.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/nn/im2col_matmul.h Refreshes generated output.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/nn/conv_transpose3d.h Adds generated ConvTranspose3D implementation.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/math/subgroup_matrix_matmul_pad_b.h Refreshes generated comments.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/math/subgroup_matrix_matmul_8x16x16.h Refreshes generated comments.
tools/python/wgsl_template/test/in_tree_golden/static-cpp/generated/math/subgroup_matrix_gemm_8x16x16.h Refreshes generated comments.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/index.h Registers the literal template.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/index_impl.h Includes literal generated code.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/tensor/pad.h Refreshes literal output.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/tensor/oihw_to_ohwi.h Refreshes literal output.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/nn/im2col_matmul.h Refreshes literal output.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/nn/conv_transpose3d.h Adds literal ConvTranspose3D implementation.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/math/subgroup_matrix_matmul_pad_b.h Refreshes literal comments.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/math/subgroup_matrix_matmul_8x16x16.h Refreshes literal comments.
tools/python/wgsl_template/test/in_tree_golden/static-cpp-literal/generated/math/subgroup_matrix_gemm_8x16x16.h Refreshes literal comments.
tools/python/wgsl_template/generator.py Removes trailing reference whitespace.
onnxruntime/test/unittest_util/base_tester.h Adds opt-in unsupported-FP16 skipping.
onnxruntime/test/unittest_util/base_tester.cc Implements capability-aware test skipping.
onnxruntime/test/providers/webgpu/fp16_capability_test.cc Tests ShaderF16 capability behavior.
onnxruntime/test/providers/webgpu/conv_transpose_test.cc Adds parameterized ConvTranspose3D coverage.
onnxruntime/test/providers/cpu/nn/conv_transpose_op_test.cc Enables WebGPU in existing 3D tests.
onnxruntime/test/providers/cpu/nn/conv_fp16_test.cc Enables WebGPU Conv3D FP16 tests.
onnxruntime/core/providers/webgpu/nn/conv_transpose3d.wgsl.template Implements the 3D shader.
onnxruntime/core/providers/webgpu/nn/conv_transpose.cc Dispatches rank-five inputs to the kernel.
onnxruntime/core/providers/webgpu/nn/conv_backprop.h Declares the shader program.
onnxruntime/core/providers/webgpu/nn/conv_backprop.cc Generates ConvTranspose3D shader code.
js/web/script/generate-webgpu-operator-md.ts Removes the unsupported annotation.
js/web/docs/webgpu-operators.md Documents ConvTranspose3D support.
Review details
  • Files reviewed: 19/33 changed files
  • Comments generated: 0
  • Review effort level: Balanced

πŸ’‘ Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@qjia7 Jiajia Qin (qjia7) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ConvTranspose3D direction is sound and I found no correctness blocker. I left two actionable non-blocking findings inline: separate unrelated generated-reference cleanup, and use the established WebGPU prepack boundary to vectorize initializer weights.

Comment thread tools/python/wgsl_template/generator.py Resolved
@gyagp

Copy link
Copy Markdown
Contributor Author

/run bots

@qjia7

Copy link
Copy Markdown
Contributor

The request was received. Approve workflow runs. Thanks.

@liqunfu

Copy link
Copy Markdown
Contributor

I confirm this PR has fixed the issue: #28356

@gyagp

Copy link
Copy Markdown
Contributor Author

We will land this soon after holidays.

@qjia7 Jiajia Qin (qjia7) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ConvTranspose3D direction and implementation are sound. The prior generated-scope and initializer-prepacking requests are resolved, and the updated Metal/WebGPU and WGSL evidence covers the material paths.

@qjia7
Jiajia Qin (qjia7) enabled auto-merge (squash) October 1, 2026 13:10
auto-merge was automatically disabled October 8, 2026 08:56

Head branch was pushed to by a user without write access

@gyagp
Yang Gu (gyagp) force-pushed the fix/webgpu-convtranspose3d-28356 branch from 818e960 to 9a2b8eb Compare October 8, 2026 08:56
Support five-dimensional ConvTranspose inputs with a WGSL template for
NCDHW and NDHWC, grouped/depthwise convolution, bias, strides, dilation,
padding, and explicit output shapes. Use signed integer coordinates and
float32 accumulation for float16 inputs.

Prepack rank-5 initializer weights into DHWOI layout and use group-aligned
scalar, vec2, or vec4 channel loads. Recover logical ONNX shapes for
validation and include packed layout and vector width in shader cache
identity. Keep dynamic weights in their original layout.

Add 176 parameterized CPU-reference comparisons under providers/webgpu/nn,
with CPU fallback disabled, repeat execution, and prepack-count assertions.
Enable existing 3D ConvTranspose and four float16 Conv3D tests.

Update the operator support documentation and new-template golden
snapshots. The independent generated-reference whitespace cleanup is in
microsoft#32736.

Validation on Windows Release/D3D12:
- Reconfigured and rebuilt with 12 parallel workers.
- ConvTranspose, Conv3D, and ConvFp16 suites: 308 passed, 9 expected skips.
  All 176 ConvTranspose3D and four existing FP16 Conv3D cases passed.
- C++ lint and git diff --check passed.
- Previously validated unchanged WGSL templates: 89 generator tests passed.
- Browser/WASM, plugin builds, and the supplied full model were not rerun.

Fixes microsoft#28356.
@gyagp
Yang Gu (gyagp) force-pushed the fix/webgpu-convtranspose3d-28356 branch from 1a00ac0 to 68515f2 Compare October 8, 2026 13:01
@gyagp

Copy link
Copy Markdown
Contributor Author

/run bots

@qjia7

Copy link
Copy Markdown
Contributor

The request was received. Approve workflow runs. Thanks.

@ariynislamctg1992

Copy link
Copy Markdown

Jiajia Qin (qjia7) pushed a commit that referenced this pull request Oct 10, 2026
### Description

Prepack constant ConvTranspose1D and ConvTranspose2D weights during
session initialization so repeated inference reuses the layout expected
by the existing 2D shader instead of transposing the same weights on
every run.

- Save an owned copy of the original ONNX filter shape for validation
and output-shape inference, removing inverse-permutation reconstruction
for all packed layouts. Both 1D and 2D weights use HWIO; the saved shape
preserves their original ranks. The 1D representation retains the
synthetic height of one used by the 2D kernel.
- Preserve per-run transposition for dynamic weights and when prepacking
is explicitly disabled, and preserve the existing 3D prepacking path.
- Correct two existing NHWC weight-vector accesses for grouped
convolution with one output channel per group: their input-channel
offsets must be expressed in vector units. The expanded tests reproduced
incorrect results on the unmodified base, including dynamic weights.
- Extend the existing WebGPU fixture with 176 parameterized tests
covering both spatial ranks, layouts, FP32/FP16, groups/depthwise,
scalar/vec2/vec4 and mixed widths, channel remainders, bias,
stride/dilation/padding, initializer/dynamic weights, repeated runs, and
prepack-count assertions. Retain all 176 existing ConvTranspose3D cases.
Additional coverage checks genuine height-one 2D kernels and all 12
initializer/dynamic input-weight rank-mismatch combinations.

### Motivation and Context

Follow-up to the non-blocking prepacking comment on #32688:

#32688 (comment)

### Validation

- Fresh Windows Release/D3D12 build of commit `96f564b873` with 12
parallel workers.
- Final `onnxruntime_provider_test --gtest_filter="*ConvTranspose*"`:
**430 passed, 4 expected CUDA/DML-only skips**, including all 176 new
parameterized tests and all 176 existing 3D cases. CPU fallback is
disabled for the WebGPU fixture.
- All 17 focused shape-regression tests passed; the rank-mismatch test
verifies rejection from the running WebGPU kernel and asserts prepack
counts.
- Before the implementation, 72 parameterized tests failed their
missing-prepack-count assertion. The expanded grouped
single-output-channel cases also exposed a numerical error in the
original shader; the final run passes both initializer and dynamic
variants.
- C++ lintrunner and `git diff --check` passed.
- Synthetic benchmark of the prepacking implementation at `edc3a6a0cc`
on an NVIDIA GeForce RTX 5080: median warmed end-to-end Run speedups of
**1.00x-1.18x** across 16 1D/2D, layout, dtype, and shape scenarios. One
small FP16/NHWC case was effectively unchanged; the other 15 measured
1.06x-1.18x. Warm-context session initialization increased by about
**0.06-0.14 ms**.
- Benchmark uses the same initializer model with
`session.disable_prepacking` toggled, verifies equal outputs and prepack
counts, alternates ordering, and aggregates 25 samples per mode/scenario
from five processes. Each sample averages 60 timed Run calls after 15
warmups, including host input/output transfers. These are
single-operator measurements on one GPU, not a general model-speedup
claim. The benchmark harness is a local artifact, not part of the source
diff.
- Browser/WASM, plugin builds, GPU capture mode, and full-model
performance were not validated locally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Web] ConvTranspose: "Only Conv2d or Conv1d are supported"

5 participants