Skip to content

[BugFix][Relax][ONNX] Honor auto_pad in ConvTranspose converter#19450

Merged
tlopex merged 2 commits into
apache:mainfrom
swjng:fix/onnx-convtranspose-auto-pad
Apr 27, 2026
Merged

[BugFix][Relax][ONNX] Honor auto_pad in ConvTranspose converter#19450
tlopex merged 2 commits into
apache:mainfrom
swjng:fix/onnx-convtranspose-auto-pad

Conversation

@swjng

@swjng swjng commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Motivation

The ConvTranspose ONNX → Relax converter silently drops the auto_pad attribute. Conv has dedicated handling (onnx_frontend.py lines 1383-1404), but ConvTranspose passes pads straight through, defaulting to 0 when the attribute is absent. Models that rely on auto_pad=SAME_UPPER/SAME_LOWER/VALID therefore produce the wrong output shape after import.

Minimal repro (against onnxruntime):

node = helper.make_node(
    "ConvTranspose", ["X", "W"], ["Y"],
    strides=[2, 2], auto_pad="SAME_UPPER",
)
# input  X: [1, 1, 4, 4], W: [1, 1, 3, 3]
# ORT  -> Y.shape = (1, 1, 8, 8)   # input * stride
# TVM  -> Y.shape = (1, 1, 9, 9)   # auto_pad ignored, pads=0

Fix

Compute pads from the ONNX spec equation before delegating to the Relax conv-transpose op:

total_pad[i] = stride[i] * (in[i] - 1)
             + output_padding[i]
             + (kernel[i] - 1) * dilation[i] + 1
             - in[i] * stride[i]

then split begin/end by SAME_UPPER vs SAME_LOWER. VALID becomes pads=0; NOTSET keeps the user-supplied pads. We deliberately do not reuse Conv's autopad() helper because it pads the input data, whereas ConvTranspose subtracts pads from the output.

The output_shape attribute (which, when set, also overrides pads per spec) remains unsupported; leaving that as a follow-up.

Test plan

  • `pytest tests/python/relax/test_frontend_onnx.py::test_conv_transpose_auto_pad` — 6 new cases (3 modes × 2 strides) for 1D/2D/3D pass.
  • `pytest tests/python/relax/test_frontend_onnx.py::test_conv_transpose` — existing 8 parameterizations still pass.

The ConvTranspose ONNX converter ignored the `auto_pad` attribute and
fell back to `pads=0`, producing wrong output shapes for models that
rely on SAME_UPPER / SAME_LOWER / VALID. Spec-conform pads are now
derived from `input_shape`, `strides`, `kernel_shape`, `dilations`,
and `output_padding` per the ONNX ConvTranspose semantics.

Adds `test_conv_transpose_auto_pad` covering the three modes across
1D/2D/3D inputs.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces support for the auto_pad attribute in the ConvTranspose operator within the ONNX frontend, covering SAME_UPPER, SAME_LOWER, and VALID modes, and includes new test cases. Feedback suggests simplifying the padding calculation to avoid dependencies on input spatial dimensions, which prevents potential TypeErrors when handling symbolic shapes in Relax.

Comment thread python/tvm/relax/frontend/onnx/onnx_frontend.py Outdated
…to_pad

Addresses review feedback: the auto_pad SAME_* total_padding formula
simplifies to a value that depends only on kernel_shape, dilations,
strides, and output_padding once the target output size of
`input_size * stride` is substituted in. This keeps the converter
usable when spatial dimensions are symbolic (`tir.Var`), where the
previous `int(s)` would have raised TypeError.

@tlopex tlopex left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@tlopex tlopex merged commit e55e3c3 into apache:main Apr 27, 2026
9 checks passed
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.

2 participants