Version
- Executed revision:
e269315c90e3a061c9e1c77b370ce883b1b223f4
- Current
main source rechecked: 0587e59a696cb435ad4d328726a07daa8d966f3c; ConvTranspose still does not read output_shape
- TVM:
0.26.dev0
- Host: Ubuntu 24.04 x86-64, LLVM CPU
Reproducer
Run the complete script below
from a TVM source environment. It creates a valid opset-11 model whose transposed
convolution requests spatial output_shape=[4,4], then compares ONNX Runtime with the
compiled Relax function.
Observed output:
output_shape [4, 4] ORT (1, 1, 4, 4) TVM (1, 1, 5, 5)
output_shape None ORT (1, 1, 5, 5) TVM (1, 1, 5, 5)
The first line is the failing case. The second line removes only output_shape and is
the passing control.
Expected behavior
ONNX defines output_shape as the requested spatial output shape and derives the needed
padding from the input, stride, dilation, kernel, and output padding. The imported
function should therefore return shape (1,1,4,4).
Actual behavior and likely cause
The converter reads strides, dilations, output_padding, kernel_shape, auto_pad,
pads, and group, but never reads output_shape. It lowers this model with zero
padding, producing the default (1,1,5,5) output instead. Current main retains the
same omission.
Duplicate check
GitHub searches for TVM Relax, ONNX ConvTranspose, and output_shape found no report of
the current Relax converter ignoring this attribute as of 2026-09-30. TVM PR #19450
fixed auto_pad, a separate attribute. ONNX issues #4159 and #4527 discuss ONNX shape
inference/documentation and pad distribution; this reproducer is accepted by ONNX
checker and ONNX Runtime and isolates the missing Relax frontend handling.
Complete reproducer
import numpy as np
import onnx
import onnxruntime as ort
import tvm
from onnx import TensorProto, helper
from tvm import relax
from tvm.relax.frontend.onnx import from_onnx
def run(output_shape):
inputs = [
helper.make_tensor_value_info("x", TensorProto.FLOAT, [1, 1, 2, 2]),
helper.make_tensor_value_info("w", TensorProto.FLOAT, [1, 1, 3, 3]),
]
expected_side = 4 if output_shape else 5
output = helper.make_tensor_value_info(
"y", TensorProto.FLOAT, [1, 1, expected_side, expected_side]
)
attrs = {"strides": [2, 2]}
if output_shape:
attrs["output_shape"] = output_shape
node = helper.make_node("ConvTranspose", ["x", "w"], ["y"], **attrs)
model = helper.make_model(
helper.make_graph([node], "convtranspose_output_shape", inputs, [output]),
opset_imports=[helper.make_opsetid("", 11)],
)
onnx.checker.check_model(model)
feeds = {
"x": np.arange(1, 5, dtype="float32").reshape(1, 1, 2, 2),
"w": np.ones((1, 1, 3, 3), dtype="float32"),
}
expected = ort.InferenceSession(
model.SerializeToString(), providers=["CPUExecutionProvider"]
).run(None, feeds)[0]
mod = from_onnx(model, keep_params_in_input=True)
executable = relax.build(mod, target="llvm", relax_pipeline="default", exec_mode="bytecode")
vm = relax.VirtualMachine(executable, tvm.cpu())
actual = vm["main"](*(tvm.runtime.tensor(feeds[x.name]) for x in inputs)).numpy()
print("output_shape", output_shape, "ORT", expected.shape, "TVM", actual.shape)
return actual, expected
risk_actual, risk_expected = run([4, 4])
control_actual, control_expected = run(None)
assert risk_actual.shape != risk_expected.shape
np.testing.assert_allclose(control_actual, control_expected)
Version
e269315c90e3a061c9e1c77b370ce883b1b223f4mainsource rechecked:0587e59a696cb435ad4d328726a07daa8d966f3c;ConvTransposestill does not readoutput_shape0.26.dev0Reproducer
Run the complete script below
from a TVM source environment. It creates a valid opset-11 model whose transposed
convolution requests spatial
output_shape=[4,4], then compares ONNX Runtime with thecompiled Relax function.
Observed output:
The first line is the failing case. The second line removes only
output_shapeand isthe passing control.
Expected behavior
ONNX defines
output_shapeas the requested spatial output shape and derives the neededpadding from the input, stride, dilation, kernel, and output padding. The imported
function should therefore return shape
(1,1,4,4).Actual behavior and likely cause
The converter reads
strides,dilations,output_padding,kernel_shape,auto_pad,pads, andgroup, but never readsoutput_shape. It lowers this model with zeropadding, producing the default
(1,1,5,5)output instead. Currentmainretains thesame omission.
Duplicate check
GitHub searches for TVM Relax, ONNX ConvTranspose, and
output_shapefound no report ofthe current Relax converter ignoring this attribute as of 2026-09-30. TVM PR #19450
fixed
auto_pad, a separate attribute. ONNX issues #4159 and #4527 discuss ONNX shapeinference/documentation and pad distribution; this reproducer is accepted by ONNX
checker and ONNX Runtime and isolates the missing Relax frontend handling.
Complete reproducer