From 00f94a2c2f1e5769f67fcba09a507f5582d72c68 Mon Sep 17 00:00:00 2001 From: Mohammed Alkindi Date: Sun, 30 Aug 2026 01:08:31 +0400 Subject: [PATCH 1/2] Materialize the DFT axis default when converting opset 19 to 20 Opset 19 defines DFT axis as an attribute defaulting to 1. Opset 20 moved it to an input defaulting to -2. dft_19_20 read the attribute with a None default and returned early when it was absent, so the node was left untouched while the model opset was bumped, silently retargeting the transform from axis 1 to axis -2 for any input of rank greater than 3. The None guard is kept because _get_int_attribute also returns None for an attribute of unexpected type. --- .../version_converter/_version_converter.py | 13 +++++++---- .../_version_converter_test.py | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/onnxscript/version_converter/_version_converter.py b/onnxscript/version_converter/_version_converter.py index 99e30417d4..9b0d941e5f 100644 --- a/onnxscript/version_converter/_version_converter.py +++ b/onnxscript/version_converter/_version_converter.py @@ -160,11 +160,14 @@ def dft_19_20(node: ir.Node, op): dft_length = node.inputs[1] if len(node.inputs) > 1 else None inverse = _get_int_attribute(node, "inverse", 0) onesided = _get_int_attribute(node, "onesided", 0) - axis = _get_int_attribute(node, "axis", None) - if axis is not None: - axis_value = op.Constant(value_int=axis) - return op.DFT(input, dft_length, axis_value, inverse=inverse, onesided=onesided) - return None + # In opset 19 `axis` is an attribute defaulting to 1; in opset 20 it became an + # input defaulting to -2. An omitted attribute must therefore be materialized + # explicitly, or the converted node silently transforms a different axis. + axis = _get_int_attribute(node, "axis", 1) + if axis is None: + return None + axis_value = op.Constant(value_int=axis) + return op.DFT(input, dft_length, axis_value, inverse=inverse, onesided=onesided) @register("GridSample", node_version=19, up_conversion=True) diff --git a/onnxscript/version_converter/_version_converter_test.py b/onnxscript/version_converter/_version_converter_test.py index 2635635557..2fea80068c 100644 --- a/onnxscript/version_converter/_version_converter_test.py +++ b/onnxscript/version_converter/_version_converter_test.py @@ -146,6 +146,29 @@ def test_version_convert_compatible(self): self.assertEqual(model.graph.node(3).version, 20) self.assertEqual(len(model.graph.node(3).inputs), 3) + def test_version_convert_dft_without_axis_attribute(self): + # Opset 19 defines DFT axis as an attribute defaulting to 1. Opset 20 moved + # it to an input defaulting to -2, so an omitted attribute has to be + # materialized or the converted node transforms a different axis. + model = ir.from_onnx_text( + """ + + agraph (float[2, 3, 4, 2] input_x) => (float[2, 3, 4, 2] output) + { + output = DFT (input_x) + } + """ + ) + version_converter.convert_version(model, target_version=20) + self.assertEqual(model.opset_imports[""], 20) + + dft_node = next(node for node in model.graph if node.op_type == "DFT") + self.assertEqual(len(dft_node.inputs), 3) + axis_input = dft_node.inputs[2] + self.assertIsNotNone(axis_input) + self.assertEqual(axis_input.producer().attributes["value_int"].value, 1) + + def test_version_convert_gridsample_linear(self): model = ir.from_onnx_text( """ From a33e8bf7599549b1c26a5c9c757aa8a020fe1e45 Mon Sep 17 00:00:00 2001 From: Mohammed Alkindi Date: Tue, 1 Sep 2026 00:36:33 +0400 Subject: [PATCH 2/2] chore: apply ruff format to the version converter test --- onnxscript/version_converter/_version_converter_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/onnxscript/version_converter/_version_converter_test.py b/onnxscript/version_converter/_version_converter_test.py index 2fea80068c..35db893dbf 100644 --- a/onnxscript/version_converter/_version_converter_test.py +++ b/onnxscript/version_converter/_version_converter_test.py @@ -168,7 +168,6 @@ def test_version_convert_dft_without_axis_attribute(self): self.assertIsNotNone(axis_input) self.assertEqual(axis_input.producer().attributes["value_int"].value, 1) - def test_version_convert_gridsample_linear(self): model = ir.from_onnx_text( """