public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/onnx] test-1.21.0: Release 1.21.0
@ 2026-06-08 15:18 Diego Herrera
  0 siblings, 0 replies; only message in thread
From: Diego Herrera @ 2026-06-08 15:18 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/onnx
Branch : test-1.21.0
Commit : 33d4cf6b4f12eb5ede11eaa4c808ad5fe5f8dc83
Author : Diego Herrera <dherrera@redhat.com>
Date   : 2026-06-07T22:42:01-04:00
Stats  : +5924/-5997 in 10 file(s)
URL    : https://src.fedoraproject.org/rpms/onnx/c/33d4cf6b4f12eb5ede11eaa4c808ad5fe5f8dc83?branch=test-1.21.0

Log:
Release 1.21.0

---
diff --git a/.gitignore b/.gitignore
index 7102235..36cd583 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
 results_*
-*.rpm
+review-*
+*.src.rpm
+*.tar.gz
 /onnx-1.13.0.tar.gz
 /onnx-1.14.0.tar.gz
 /onnx-1.14.1.tar.gz

diff --git a/0000-Build-shared-libraries-and-fix-install-location.patch b/0000-Build-shared-libraries-and-fix-install-location.patch
index 39511d1..5423755 100644
--- a/0000-Build-shared-libraries-and-fix-install-location.patch
+++ b/0000-Build-shared-libraries-and-fix-install-location.patch
@@ -1,73 +1,72 @@
-From 8a2a2327e89fb62bb74ced121cbdf8c3a59ad04f Mon Sep 17 00:00:00 2001
+From a48f42b1e3dd972cf2c5ad9b9227da9e2b1c9fab Mon Sep 17 00:00:00 2001
 From: Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com>
 Date: Sat, 24 Feb 2024 14:48:45 +0100
-Subject: [PATCH 0/6] Build shared libraries and fix install location
+Subject: [PATCH 0/2] Build shared libraries and fix install location
+
+This patch was updated to be able to be used on modern versions of the library.
+
+Co-authored-by: Diego Herrera <dherrera@redhat.com>
 
 ---
- CMakeLists.txt | 22 ++++++++++++++++++++--
- 1 file changed, 20 insertions(+), 2 deletions(-)
 
 diff --git a/CMakeLists.txt b/CMakeLists.txt
-index d15d97edc..d6e04d2e9 100644
+index 044996e1b..3a08d3289 100644
 --- a/CMakeLists.txt
 +++ b/CMakeLists.txt
-@@ -466,7 +466,7 @@ list(REMOVE_ITEM __tmp_srcs "${ONNX_ROOT}/onnx/cpp2py_export.cc")
- list(REMOVE_ITEM __tmp_srcs ${onnx_gtests_src})
- list(APPEND ONNX_SRCS ${__tmp_srcs})
- 
--add_library(onnx_proto ${ONNX_PROTO_SRCS} ${ONNX_PROTO_HDRS})
-+add_library(onnx_proto SHARED ${ONNX_PROTO_SRCS} ${ONNX_PROTO_HDRS})
- add_dependencies(onnx_proto gen_onnx_operators_proto gen_onnx_data_proto)
- target_include_directories(onnx_proto PUBLIC
-   $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-@@ -499,6 +499,8 @@ else()
-   set(ONNX_API_DEFINE "-DONNX_API=__attribute__\(\(__visibility__\(\"default\"\)\)\)")
-   set_target_properties(onnx_proto PROPERTIES CXX_VISIBILITY_PRESET hidden)
-   set_target_properties(onnx_proto PROPERTIES VISIBILITY_INLINES_HIDDEN 1)
-+  set_target_properties(onnx_proto PROPERTIES VERSION ${ONNX_VERSION}
-+                                            SOVERSION ${ONNX_VERSION})
+@@ -414,19 +414,21 @@ if(ONNX_USE_LITE_PROTO)
+     set(LINKED_PROTOBUF_TARGET protobuf::libprotobuf-lite)
+   endif()
  endif()
- target_compile_definitions(onnx_proto PRIVATE ${ONNX_API_DEFINE})
- 
-@@ -522,7 +524,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
-   # So, create a object library
-   add_library(onnx OBJECT ${ONNX_SRCS})
- else()
--  add_library(onnx ${ONNX_SRCS})
-+  add_library(onnx SHARED ${ONNX_SRCS})
-+  set_target_properties(onnx PROPERTIES VERSION ${ONNX_VERSION}
+-add_library(onnx_proto ${ONNX_PROTO_SRCS})
++add_library(onnx_proto SHARED ${ONNX_PROTO_SRCS})
+ add_onnx_global_defines(onnx_proto)
+-
+-add_library(onnx ${ONNX_SRCS} ${ONNX_PROTO_SRCS})
++set_target_properties(onnx_proto PROPERTIES VERSION ${ONNX_VERSION}
++                                            SOVERSION ${ONNX_VERSION})
++add_library(onnx SHARED ${ONNX_SRCS} ${ONNX_PROTO_SRCS})
+ add_dependencies(onnx onnx_proto)
+ set_source_files_properties(${ONNX_SRCS} PROPERTIES CXX_VISIBILITY_PRESET hidden)
+ add_onnx_global_defines(onnx)
+-
++set_target_properties(onnx PROPERTIES VERSION ${ONNX_VERSION}
 +                                        SOVERSION ${ONNX_VERSION})
+ if(ONNX_BUILD_PYTHON)
+   # find system nanobind
+   if(NOT DEFINED nanobind_DIR OR "${nanobind_DIR}" STREQUAL "")
+     execute_process(
+-      COMMAND ${Python_EXECUTABLE} -m nanobind --cmake-dir
++      COMMAND ${Python_EXECUTABLE} -m nanobind --cmake_dir
+       RESULT_VARIABLE NANOBIND_CMAKE_RESULT
+       OUTPUT_VARIABLE NANOBIND_CMAKE_DIR
+       OUTPUT_STRIP_TRAILING_WHITESPACE
+@@ -491,6 +493,16 @@ if(ONNX_INSTALL)
+           DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+           FILES_MATCHING
+           PATTERN "*.h")
++  install(DIRECTORY ${ONNX_ROOT}/onnx
++          DESTINATION "${PY_SITEARCH}"
++          FILES_MATCHING
++          PATTERN "*.py"
++          PATTERN "test/*" EXCLUDE )
++  install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
++          DESTINATION  "${PY_SITEARCH}"
++          FILES_MATCHING
++          PATTERN "*.py"
++          PATTERN "test/*" EXCLUDE )
  endif()
  
- target_include_directories(onnx PUBLIC
-@@ -689,6 +693,17 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
-         FILES_MATCHING
-         PATTERN "*.h")
- 
-+install(DIRECTORY ${ONNX_ROOT}/onnx
-+        DESTINATION "${PY_SITEARCH}"
-+        FILES_MATCHING
-+        PATTERN "*.py"
-+        PATTERN "test/*" EXCLUDE )
-+install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
-+        DESTINATION  "${PY_SITEARCH}"
-+        FILES_MATCHING
-+        PATTERN "*.py"
-+        PATTERN "test/*" EXCLUDE )
-+
  configure_file(
-   ${PROJECT_SOURCE_DIR}/cmake/ONNXConfigVersion.cmake.in
-   ${PROJECT_BINARY_DIR}/ONNXConfigVersion.cmake
-@@ -747,6 +762,9 @@ endif()
- install(TARGETS
-   onnx onnx_proto
-   EXPORT ONNXTargets DESTINATION ${CMAKE_INSTALL_LIBDIR})
-+install(TARGETS
-+  onnx_cpp2py_export
-+  DESTINATION "${PY_SITEARCH}/onnx")
+@@ -544,6 +556,9 @@ if(ONNX_INSTALL)
+   install(TARGETS
+     onnx onnx_proto
+     EXPORT ONNXTargets DESTINATION ${CMAKE_INSTALL_LIBDIR})
++  install(TARGETS
++    onnx_cpp2py_export
++    DESTINATION "${PY_SITEARCH}/onnx")
  
- if(ONNX_BUILD_TESTS)
-   include(${ONNX_ROOT}/cmake/unittest.cmake)
+   install(EXPORT ONNXTargets
+     DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ONNX"
 -- 
-2.52.0
+2.54.0
 

diff --git a/0001-Use-system-protobuf-and-require-parameterized.patch b/0001-Use-system-protobuf-and-require-parameterized.patch
deleted file mode 100644
index 76d5007..0000000
--- a/0001-Use-system-protobuf-and-require-parameterized.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 30745ee623fb1fe7531d6399e54b5ffe411446f5 Mon Sep 17 00:00:00 2001
-From: Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com>
-Date: Sat, 24 Feb 2024 14:52:25 +0100
-Subject: [PATCH 2/4] Use system protobuf and require parameterized
-
----
- requirements.txt | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/requirements.txt b/requirements.txt
-index 7f3a9ad03..46dd7f7fd 100644
---- a/requirements.txt
-+++ b/requirements.txt
-@@ -1,2 +1,3 @@
- numpy>=1.20
--protobuf>=3.20.2
-+protobuf >= 3.14.0, < 4
-+parameterized >= 0.8.1, < 1
--- 
-2.52.0
-

diff --git a/0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch b/0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
deleted file mode 100644
index cae7fed..0000000
--- a/0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 75e1082f2d17c2c2ccb3c38b429fa24a4b45bbea Mon Sep 17 00:00:00 2001
-From: Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com>
-Date: Sat, 24 Feb 2024 14:53:10 +0100
-Subject: [PATCH 3/4] Let pyproject_wheel use binaries from cmake_build
-
----
- setup.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/setup.py b/setup.py
-index 7d2cb9e50..af9049a1e 100644
---- a/setup.py
-+++ b/setup.py
-@@ -27,7 +27,7 @@ import setuptools.command.build_py
- import setuptools.command.develop
- 
- TOP_DIR = os.path.realpath(os.path.dirname(__file__))
--CMAKE_BUILD_DIR = os.path.join(TOP_DIR, ".setuptools-cmake-build")
-+CMAKE_BUILD_DIR = os.path.join(TOP_DIR, os.environ.get("VPATH_BUILDDIR", "redhat-linux-build"))
- 
- WINDOWS = os.name == "nt"
- 
-@@ -151,6 +151,7 @@ class CmakeBuild(setuptools.Command):
-         self.jobs = multiprocessing.cpu_count() if self.jobs is None else int(self.jobs)
- 
-     def run(self):
-+        return
-         os.makedirs(CMAKE_BUILD_DIR, exist_ok=True)
- 
-         with cd(CMAKE_BUILD_DIR):
--- 
-2.52.0
-

diff --git a/0002-Remove-python-parameterized-dependency.patch b/0002-Remove-python-parameterized-dependency.patch
new file mode 100644
index 0000000..b111cab
--- /dev/null
+++ b/0002-Remove-python-parameterized-dependency.patch
@@ -0,0 +1,5739 @@
+From 231b8e5093c24cdc6242d2c8565c1adb526eeba7 Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 29 May 2026 18:47:26 -0400
+Subject: [PATCH 2/2] Remove python-parameterized dependency
+
+
+diff --git a/onnx/test/basic_test.py b/onnx/test/basic_test.py
+index 9713e4d1f..6d6c6c90e 100644
+--- a/onnx/test/basic_test.py
++++ b/onnx/test/basic_test.py
+@@ -11,7 +11,6 @@ import unittest
+ 
+ import google.protobuf.message
+ import google.protobuf.text_format
+-import parameterized
+ 
+ import onnx
+ from onnx import serialization
+@@ -34,97 +33,6 @@ def _simple_tensor() -> onnx.TensorProto:
+     )
+ 
+ 
+-@parameterized.parameterized_class(
+-    [
+-        {"format": "protobuf"},
+-        {"format": "textproto"},
+-        {"format": "json"},
+-        {"format": "onnxtxt"},
+-    ]
+-)
+-class TestIO(unittest.TestCase):
+-    format: str
+-
+-    def test_load_model_when_input_is_bytes(self) -> None:
+-        proto = _simple_model()
+-        proto_string = serialization.registry.get(self.format).serialize_proto(proto)
+-        loaded_proto = onnx.load_model_from_string(proto_string, format=self.format)
+-        self.assertEqual(proto, loaded_proto)
+-
+-    def test_save_and_load_model_when_input_has_read_function(self) -> None:
+-        proto = _simple_model()
+-        # When the proto is a bytes representation provided to `save_model`,
+-        # it should always be a serialized binary protobuf representation. Aka. format="protobuf"
+-        # The saved file format is specified by the `format` argument.
+-        proto_string = serialization.registry.get("protobuf").serialize_proto(proto)
+-        f = io.BytesIO()
+-        onnx.save_model(proto_string, f, format=self.format)
+-        loaded_proto = onnx.load_model(io.BytesIO(f.getvalue()), format=self.format)
+-        self.assertEqual(proto, loaded_proto)
+-
+-    def test_save_and_load_model_when_input_is_file_name(self) -> None:
+-        proto = _simple_model()
+-        with tempfile.TemporaryDirectory() as temp_dir:
+-            model_path = os.path.join(temp_dir, "model.onnx")
+-            onnx.save_model(proto, model_path, format=self.format)
+-            loaded_proto = onnx.load_model(model_path, format=self.format)
+-            self.assertEqual(proto, loaded_proto)
+-
+-    def test_save_and_load_model_when_input_is_pathlike(self) -> None:
+-        proto = _simple_model()
+-        with tempfile.TemporaryDirectory() as temp_dir:
+-            model_path = pathlib.Path(temp_dir, "model.onnx")
+-            onnx.save_model(proto, model_path, format=self.format)
+-            loaded_proto = onnx.load_model(model_path, format=self.format)
+-            self.assertEqual(proto, loaded_proto)
+-
+-
+-@parameterized.parameterized_class(
+-    [
+-        {"format": "protobuf"},
+-        {"format": "textproto"},
+-        {"format": "json"},
+-        # The onnxtxt format does not support saving/loading tensors yet
+-    ]
+-)
+-class TestIOTensor(unittest.TestCase):
+-    """Test loading and saving of TensorProto."""
+-
+-    format: str
+-
+-    def test_load_tensor_when_input_is_bytes(self) -> None:
+-        proto = _simple_tensor()
+-        proto_string = serialization.registry.get(self.format).serialize_proto(proto)
+-        loaded_proto = onnx.load_tensor_from_string(proto_string, format=self.format)
+-        self.assertEqual(proto, loaded_proto)
+-
+-    def test_save_and_load_tensor_when_input_has_read_function(self) -> None:
+-        # Test if input has a read function
+-        proto = _simple_tensor()
+-        f = io.BytesIO()
+-        onnx.save_tensor(proto, f, format=self.format)
+-        loaded_proto = onnx.load_tensor(io.BytesIO(f.getvalue()), format=self.format)
+-        self.assertEqual(proto, loaded_proto)
+-
+-    def test_save_and_load_tensor_when_input_is_file_name(self) -> None:
+-        # Test if input is a file name
+-        proto = _simple_tensor()
+-        with tempfile.TemporaryDirectory() as temp_dir:
+-            model_path = os.path.join(temp_dir, "model.onnx")
+-            onnx.save_tensor(proto, model_path, format=self.format)
+-            loaded_proto = onnx.load_tensor(model_path, format=self.format)
+-            self.assertEqual(proto, loaded_proto)
+-
+-    def test_save_and_load_tensor_when_input_is_pathlike(self) -> None:
+-        # Test if input is a file name
+-        proto = _simple_tensor()
+-        with tempfile.TemporaryDirectory() as temp_dir:
+-            model_path = pathlib.Path(temp_dir, "model.onnx")
+-            onnx.save_tensor(proto, model_path, format=self.format)
+-            loaded_proto = onnx.load_tensor(model_path, format=self.format)
+-            self.assertEqual(proto, loaded_proto)
+-
+-
+ class TestSaveAndLoadFileExtensions(unittest.TestCase):
+     def test_save_model_picks_correct_format_from_extension(self) -> None:
+         proto = _simple_model()
+diff --git a/onnx/test/helper_test.py b/onnx/test/helper_test.py
+index 27793f561..91f7739aa 100644
+--- a/onnx/test/helper_test.py
++++ b/onnx/test/helper_test.py
+@@ -12,7 +12,6 @@ from typing import Any
+ import ml_dtypes
+ import numpy as np
+ import numpy.typing as npt
+-import parameterized
+ import pytest
+ 
+ from onnx import (
+@@ -636,63 +635,6 @@ class TestHelperTensorFunctions(unittest.TestCase):
+             expected.view(np.uint8),
+         )
+ 
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.UINT4, TensorProto.INT4),
+-            ((5, 4, 6), (4, 6, 5), (3, 3), (1,), (2**10,)),
+-        )
+-    )
+-    def test_make_4bit_tensor(self, dtype, dims) -> None:
+-        type_range = {
+-            TensorProto.UINT4: (0, 15),
+-            TensorProto.INT4: (-8, 7),
+-        }
+-        data = np.random.randint(
+-            type_range[dtype][0], high=type_range[dtype][1] + 1, size=dims
+-        )
+-        y = helper.make_tensor("y", dtype, data.shape, data)
+-
+-        # Check the expected size of int32_data in bytes
+-        expected_data_size = math.ceil(np.prod(data.shape) / 2.0)
+-        actual_data_size = len(bytes(y.int32_data))
+-        np.testing.assert_equal(actual_data_size, expected_data_size)
+-
+-        # Check the expected data values.
+-        ynp = numpy_helper.to_array(y)
+-        np.testing.assert_equal(ynp, data)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            ((5, 4, 6), (4, 6, 5), (3, 3), (1,), (2**10,)),
+-        )
+-    )
+-    def test_4bit_tensor_size(self, dims) -> None:
+-        # A bug caused negative int4 values to inflate tensor size.
+-        # So, test negative values here.
+-        num_elems = np.prod(dims)
+-        data = np.array([-4] * num_elems, dtype=np.int8).reshape(dims)
+-        y = helper.make_tensor("y", TensorProto.INT4, data.shape, data)
+-
+-        # Check the expected size of int32_data in bytes
+-        expected_data_size = math.ceil(num_elems / 2.0)
+-        actual_data_size = len(bytes(y.int32_data))
+-        np.testing.assert_equal(actual_data_size, expected_data_size)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.UINT4, TensorProto.INT4), ((5, 4, 6), (4, 6, 5), (3, 3), (1,))
+-        )
+-    )
+-    def test_make_4bit_raw_tensor(self, dtype, dims) -> None:
+-        data = np.random.randint(0, high=16, size=dims, dtype=np.uint8)
+-        packed_data = _pack_4bit(data)
+-
+-        y = helper.make_tensor(
+-            "packed_int4", dtype, dims, packed_data.tobytes(), raw=True
+-        )
+-        ynp = numpy_helper.to_array(y)
+-        np.testing.assert_equal(ynp.view(np.uint8), data)
+-
+     def test_make_float4e2m1_raw_tensor(self) -> None:
+         data = np.array([0, 0.5, 1, 240, 10, -2], dtype=ml_dtypes.float4_e2m1fn)
+         expected = data.view(np.uint8)
+@@ -707,63 +649,6 @@ class TestHelperTensorFunctions(unittest.TestCase):
+         ynp = numpy_helper.to_array(y)
+         np.testing.assert_equal(ynp.view(np.uint8), expected)
+ 
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.UINT2, TensorProto.INT2),
+-            ((5, 4, 6), (4, 6, 5), (3, 3), (1,), (2**10,)),
+-        )
+-    )
+-    def test_make_2bit_tensor(self, dtype, dims) -> None:
+-        type_range = {
+-            TensorProto.UINT2: (0, 3),
+-            TensorProto.INT2: (-2, 1),
+-        }
+-        data = np.random.randint(
+-            type_range[dtype][0], high=type_range[dtype][1] + 1, size=dims
+-        )
+-        y = helper.make_tensor("y", dtype, data.shape, data)
+-
+-        # Check the expected size of int32_data in bytes
+-        expected_data_size = math.ceil(np.prod(data.shape) / 4.0)
+-        actual_data_size = len(bytes(y.int32_data))
+-        np.testing.assert_equal(actual_data_size, expected_data_size)
+-
+-        # Check the expected data values.
+-        ynp = numpy_helper.to_array(y)
+-        np.testing.assert_equal(ynp, data)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            ((5, 4, 6), (4, 6, 5), (3, 3), (1,), (2**10,)),
+-        )
+-    )
+-    def test_2bit_tensor_size(self, dims) -> None:
+-        # A bug caused negative int2 values to inflate tensor size.
+-        # So, test negative values here.
+-        num_elems = np.prod(dims)
+-        data = np.array([-2] * num_elems, dtype=np.int8).reshape(dims)
+-        y = helper.make_tensor("y", TensorProto.INT2, data.shape, data)
+-
+-        # Check the expected size of int32_data in bytes
+-        expected_data_size = math.ceil(num_elems / 4.0)
+-        actual_data_size = len(bytes(y.int32_data))
+-        np.testing.assert_equal(actual_data_size, expected_data_size)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.UINT2, TensorProto.INT2), ((5, 4, 6), (4, 6, 5), (3, 3), (1,))
+-        )
+-    )
+-    def test_make_2bit_raw_tensor(self, dtype, dims) -> None:
+-        data = np.random.randint(0, high=4, size=dims, dtype=np.uint8)
+-        packed_data = _pack_2bit(data)
+-
+-        y = helper.make_tensor(
+-            "packed_int2", dtype, dims, packed_data.tobytes(), raw=True
+-        )
+-        ynp = numpy_helper.to_array(y)
+-        np.testing.assert_equal(ynp.view(np.uint8), data)
+-
+     def test_make_float4e2m1_tensor(self) -> None:
+         y = helper.make_tensor(
+             "zero_point",
+@@ -1105,28 +990,6 @@ class TestHelperMappingFunctions(unittest.TestCase):
+ 
+ 
+ class TestAttrTypeToStr(unittest.TestCase):
+-    @parameterized.parameterized.expand(
+-        [
+-            (AttributeProto.AttributeType.FLOAT, "FLOAT"),
+-            (AttributeProto.AttributeType.INT, "INT"),
+-            (AttributeProto.AttributeType.STRING, "STRING"),
+-            (AttributeProto.AttributeType.TENSOR, "TENSOR"),
+-            (AttributeProto.AttributeType.GRAPH, "GRAPH"),
+-            (AttributeProto.AttributeType.SPARSE_TENSOR, "SPARSE_TENSOR"),
+-            (AttributeProto.AttributeType.TYPE_PROTO, "TYPE_PROTO"),
+-            (AttributeProto.AttributeType.FLOATS, "FLOATS"),
+-            (AttributeProto.AttributeType.INTS, "INTS"),
+-            (AttributeProto.AttributeType.STRINGS, "STRINGS"),
+-            (AttributeProto.AttributeType.TENSORS, "TENSORS"),
+-            (AttributeProto.AttributeType.GRAPHS, "GRAPHS"),
+-            (AttributeProto.AttributeType.SPARSE_TENSORS, "SPARSE_TENSORS"),
+-            (AttributeProto.AttributeType.TYPE_PROTOS, "TYPE_PROTOS"),
+-        ]
+-    )
+-    def test_attr_type_to_str(self, attr_type, expected_str):
+-        result = helper._attr_type_to_str(attr_type)
+-        self.assertEqual(result, expected_str)
+-
+     def test_attr_type_to_str_undefined(self):
+         result = helper._attr_type_to_str(9999)
+         self.assertEqual(result, "UNDEFINED")
+diff --git a/onnx/test/node_shape_inference_test.py b/onnx/test/node_shape_inference_test.py
+index ece776e48..63252b922 100644
+--- a/onnx/test/node_shape_inference_test.py
++++ b/onnx/test/node_shape_inference_test.py
+@@ -5,34 +5,9 @@ from __future__ import annotations
+ 
+ import unittest
+ 
+-import parameterized
+-
+ import onnx.helper
+ import onnx.shape_inference
+ 
+ 
+-class NodeInferenceTest(unittest.TestCase):
+-    @parameterized.parameterized.expand(
+-        [
+-            ("GreaterOrEqual",),
+-            ("LessOrEqual",),
+-        ]
+-    )
+-    def test_comparison_op(self, op_type):
+-        node = onnx.helper.make_node(op_type, ["x", "y"], ["z"])
+-        schema = onnx.defs.get_schema(node.op_type, 23, "")
+-        xtype = onnx.helper.make_tensor_type_proto(onnx.TensorProto.INT32, [1, 10])
+-        ytype = onnx.helper.make_tensor_type_proto(onnx.TensorProto.INT32, [10, 1])
+-        result = onnx.shape_inference.infer_node_outputs(
+-            schema, node, {"x": xtype, "y": ytype}
+-        )
+-        self.assertEqual(list(result.keys()), ["z"])
+-        self.assertEqual(result["z"].tensor_type.elem_type, onnx.TensorProto.BOOL)
+-        self.assertEqual(
+-            [dim.dim_value for dim in result["z"].tensor_type.shape.dim],
+-            [10, 10],
+-        )
+-
+-
+ if __name__ == "__main__":
+     unittest.main()
+diff --git a/onnx/test/numpy_helper_test.py b/onnx/test/numpy_helper_test.py
+index 568000550..2265008d2 100644
+--- a/onnx/test/numpy_helper_test.py
++++ b/onnx/test/numpy_helper_test.py
+@@ -6,7 +6,6 @@ from __future__ import annotations
+ import unittest
+ 
+ import numpy as np
+-import parameterized
+ 
+ import onnx
+ import onnx.reference
+@@ -148,38 +147,6 @@ class TestNumpyHelper(unittest.TestCase):
+         self.assertEqual(tp.SerializeToString(), again.SerializeToString())
+         self.assertEqual(tp.data_type, helper.np_dtype_to_tensor_dtype(back.dtype))
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            ("FLOAT", onnx.TensorProto.FLOAT),
+-            ("UINT8", onnx.TensorProto.UINT8),
+-            ("INT8", onnx.TensorProto.INT8),
+-            ("UINT16", onnx.TensorProto.UINT16),
+-            ("INT16", onnx.TensorProto.INT16),
+-            ("INT32", onnx.TensorProto.INT32),
+-            ("INT64", onnx.TensorProto.INT64),
+-            ("BOOL", onnx.TensorProto.BOOL),
+-            ("FLOAT16", onnx.TensorProto.FLOAT16),
+-            ("DOUBLE", onnx.TensorProto.DOUBLE),
+-            ("UINT32", onnx.TensorProto.UINT32),
+-            ("UINT64", onnx.TensorProto.UINT64),
+-            ("COMPLEX64", onnx.TensorProto.COMPLEX64),
+-            ("COMPLEX128", onnx.TensorProto.COMPLEX128),
+-            ("BFLOAT16", onnx.TensorProto.BFLOAT16),
+-            ("FLOAT8E4M3FN", onnx.TensorProto.FLOAT8E4M3FN),
+-            ("FLOAT8E4M3FNUZ", onnx.TensorProto.FLOAT8E4M3FNUZ),
+-            ("FLOAT8E5M2", onnx.TensorProto.FLOAT8E5M2),
+-            ("FLOAT8E5M2FNUZ", onnx.TensorProto.FLOAT8E5M2FNUZ),
+-            ("FLOAT8E8M0", onnx.TensorProto.FLOAT8E8M0),
+-            ("UINT4", onnx.TensorProto.UINT4),
+-            ("INT4", onnx.TensorProto.INT4),
+-            ("UINT2", onnx.TensorProto.UINT2),
+-            ("INT2", onnx.TensorProto.INT2),
+-            ("FLOAT4E2M1", onnx.TensorProto.FLOAT4E2M1),
+-        ]
+-    )
+-    def test_to_array_from_array(self, _: str, data_type: onnx.TensorProto.DataType):
+-        self._to_array_from_array(data_type)
+-
+     def test_to_array_from_array_string(self):
+         self._to_array_from_array(onnx.TensorProto.STRING, False)
+ 
+diff --git a/onnx/test/parser_test.py b/onnx/test/parser_test.py
+index 19ee40792..9e22f19ae 100644
+--- a/onnx/test/parser_test.py
++++ b/onnx/test/parser_test.py
+@@ -5,8 +5,6 @@ from __future__ import annotations
+ 
+ import unittest
+ 
+-from parameterized import parameterized
+-
+ import onnx
+ from onnx import GraphProto, OperatorSetIdProto, TensorProto, checker
+ 
+@@ -120,94 +118,6 @@ class TestBasicFunctions(unittest.TestCase):
+         model = onnx.parser.parse_model(input)
+         checker.check_model(model)
+ 
+-    @parameterized.expand(
+-        [
+-            (
+-                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu(x) }",
+-                {},
+-            ),
+-            (
+-                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu<alpha=2.0>(x) }",
+-                {"alpha": 2.0},
+-            ),
+-            (
+-                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu<gamma=3.0>(x) }",
+-                {"gamma": 3.0},
+-            ),
+-            (
+-                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu<alpha=2.0, gamma=3.0>(x) }",
+-                {"alpha": 2.0, "gamma": 3.0},
+-            ),
+-        ]
+-    )
+-    def test_composite_parse_function_with_attributes(
+-        self, graph_text: str, expected_attribute: dict
+-    ) -> None:
+-        default_alpha = 1.67326319217681884765625
+-        default_gamma = 1.05070102214813232421875
+-
+-        def expect_custom_node_attribute(node, attributes):
+-            for key in attributes:
+-                match_attr = [attr for attr in node.attribute if attr.name == key]
+-                assert len(match_attr) == 1
+-                assert match_attr[0].f == attributes[key]
+-
+-        def expect_model_function_attribute(model):
+-            assert len(model.functions[0].attribute_proto) == 2
+-            attr_proto_alpha = [
+-                attr_proto
+-                for attr_proto in model.functions[0].attribute_proto
+-                if attr_proto.name == "alpha"
+-            ]
+-            assert len(attr_proto_alpha) == 1 and attr_proto_alpha[0].f == default_alpha
+-            attr_proto_gamma = [
+-                attr_proto
+-                for attr_proto in model.functions[0].attribute_proto
+-                if attr_proto.name == "gamma"
+-            ]
+-            assert len(attr_proto_gamma) == 1 and attr_proto_gamma[0].f == default_gamma
+-
+-        function_text = f"""
+-         <
+-         domain: "custom_domain",
+-         opset_import: [ "" : 15],
+-         doc_string: "Test function proto"
+-         >
+-           Selu
+-           <alpha: float={default_alpha}, gamma: float={default_gamma}>
+-           (X) => (C)
+-           {{
+-               constant_alpha = Constant<value_float: float=@alpha>()
+-               constant_gamma = Constant<value_float: float=@gamma>()
+-               alpha_x = CastLike(constant_alpha, X)
+-               gamma_x = CastLike(constant_gamma, X)
+-               exp_x = Exp(X)
+-               alpha_x_exp_x = Mul(alpha_x, exp_x)
+-               alpha_x_exp_x_ = Sub(alpha_x_exp_x, alpha_x)
+-               neg = Mul(gamma_x, alpha_x_exp_x_)
+-               pos = Mul(gamma_x, X)
+-               _zero = Constant<value_float=0.0>()
+-               zero = CastLike(_zero, X)
+-               less_eq = LessOrEqual(X, zero)
+-               C = Where(less_eq, neg, pos)
+-           }}
+-        """
+-
+-        functions = [onnx.parser.parse_function(function_text)]
+-        graph = onnx.parser.parse_graph(graph_text)
+-        opset_imports = [
+-            OperatorSetIdProto(domain="", version=15),
+-            OperatorSetIdProto(domain="custom_domain", version=1),
+-        ]
+-
+-        model = onnx.helper.make_model(
+-            graph, functions=functions, opset_imports=opset_imports
+-        )
+-        checker.check_model(model)
+-
+-        expect_model_function_attribute(model)
+-        expect_custom_node_attribute(model.graph.node[0], expected_attribute)
+-
+     def test_parse_node(self):
+         node = onnx.parser.parse_node(
+             "out1, out2 = SomeDomain.SomeOp <attr1 = 1> (in1, in2)"
+@@ -242,101 +152,6 @@ class TestBasicFunctions(unittest.TestCase):
+         self.assertEqual(list(node.input), ["", "y"])
+         self.assertEqual(list(node.output), ["", "x"])
+ 
+-    @parameterized.expand(
+-        [
+-            ("not_a_good_float", True),
+-            ("inf1", True),
+-            ("-inf1", True),
+-            ("nan0", True),
+-            ("-nan0", True),
+-            ("naninf", True),
+-            ("inf", False),
+-            ("-inf", False),
+-            ("infinity", False),
+-            ("-infinity", False),
+-            ("nan", False),
+-            ("-NaN", False),
+-        ]
+-    )
+-    def test_parse_various_float_values(self, test_literal, expect_exception):
+-        model_text = f"""
+-        <
+-        ir_version: 8,
+-        opset_import: ["" : 18, "this" : 1],
+-        producer_name: "FunctionProtoTest",
+-        producer_version: "1.0"
+-        >
+-        _func () => ()
+-        {{
+-        tmp = Constant <value_float = {test_literal}>()
+-        }}
+-        """
+-        if expect_exception:
+-            self.assertRaises(
+-                onnx.parser.ParseError, lambda: onnx.parser.parse_model(model_text)
+-            )
+-        else:
+-            model = onnx.parser.parse_model(model_text)
+-            self.assertEqual(model.ir_version, 8)
+-            self.assertEqual(model.producer_name, "FunctionProtoTest")
+-            self.assertEqual(model.producer_version, "1.0")
+-            self.assertEqual(len(model.graph.node), 1)
+-            self.assertEqual(len(model.graph.node[0].attribute), 1)
+-            self.assertEqual(model.graph.node[0].attribute[0].name, "value_float")
+-            self.assertEqual(
+-                model.graph.node[0].attribute[0].type, onnx.AttributeProto.FLOAT
+-            )
+-            self.assertEqual(
+-                str(model.graph.node[0].attribute[0].f), str(float(test_literal))
+-            )
+-
+-    @parameterized.expand(
+-        [
+-            ("bfloat16", TensorProto.BFLOAT16),
+-            ("bool", TensorProto.BOOL),
+-            ("complex64", TensorProto.COMPLEX64),
+-            ("complex128", TensorProto.COMPLEX128),
+-            ("double", TensorProto.DOUBLE),
+-            ("float16", TensorProto.FLOAT16),
+-            ("float", TensorProto.FLOAT),
+-            ("float8e4m3fn", TensorProto.FLOAT8E4M3FN),
+-            ("float8e4m3fnuz", TensorProto.FLOAT8E4M3FNUZ),
+-            ("float8e5m2", TensorProto.FLOAT8E5M2),
+-            ("float8e5m2fnuz", TensorProto.FLOAT8E5M2FNUZ),
+-            ("int2", TensorProto.INT2),
+-            ("int4", TensorProto.INT4),
+-            ("int8", TensorProto.INT8),
+-            ("int16", TensorProto.INT16),
+-            ("int32", TensorProto.INT32),
+-            ("int64", TensorProto.INT64),
+-            ("string", TensorProto.STRING),
+-            ("uint2", TensorProto.UINT2),
+-            ("uint4", TensorProto.UINT4),
+-            ("uint8", TensorProto.UINT8),
+-            ("uint16", TensorProto.UINT16),
+-            ("uint32", TensorProto.UINT32),
+-            ("uint64", TensorProto.UINT64),
+-            ("float4e2m1", TensorProto.FLOAT4E2M1),
+-        ]
+-    )
+-    def test_parse_graph_types(self, name, itype) -> None:
+-        w = '{"0"}' if itype == TensorProto.STRING else "{0}"
+-        text_graph = f"""
+-           <
+-             ir_version: 10,
+-             opset_import: [ "" : 19]
+-           >
+-           agraph (float[N] X) => ({name}[N] C)
+-           <
+-             {name}[1] weight = {w}
+-           >
+-           {{
+-              C = Cast<to={itype}>(X)
+-           }}
+-           """
+-        graph = onnx.parser.parse_model(text_graph)
+-        self.assertEqual(len(graph.graph.node), 1)
+-
+ 
+ if __name__ == "__main__":
+     unittest.main(verbosity=2)
+diff --git a/onnx/test/reference_evaluator_ml_test.py b/onnx/test/reference_evaluator_ml_test.py
+index 7dad96703..1c4276482 100644
+--- a/onnx/test/reference_evaluator_ml_test.py
++++ b/onnx/test/reference_evaluator_ml_test.py
+@@ -11,7 +11,6 @@ import unittest
+ 
+ import numpy as np
+ from numpy.testing import assert_allclose
+-from parameterized import parameterized
+ 
+ import onnx
+ from onnx import ONNX_ML, TensorProto, TypeProto, ValueInfoProto
+@@ -893,118 +892,6 @@ class TestReferenceEvaluatorAiOnnxMl(unittest.TestCase):
+         onnx.checker.check_model(model)
+         return model
+ 
+-    @parameterized.expand(
+-        tuple(
+-            itertools.chain.from_iterable(
+-                (
+-                    (
+-                        AggregationFunction.SUM if opset5 else "SUM",
+-                        np.array(
+-                            [[0.576923], [0.576923], [0.576923]], dtype=np.float32
+-                        ),
+-                        opset5,
+-                    ),
+-                    (
+-                        AggregationFunction.AVERAGE if opset5 else "AVERAGE",
+-                        np.array(
+-                            [[0.288462], [0.288462], [0.288462]], dtype=np.float32
+-                        ),
+-                        opset5,
+-                    ),
+-                    (
+-                        AggregationFunction.MIN if opset5 else "MIN",
+-                        np.array(
+-                            [[0.076923], [0.076923], [0.076923]], dtype=np.float32
+-                        ),
+-                        opset5,
+-                    ),
+-                    (
+-                        AggregationFunction.MAX if opset5 else "MAX",
+-                        np.array([[0.5], [0.5], [0.5]], dtype=np.float32),
+-                        opset5,
+-                    ),
+-                )
+-                for opset5 in [True, False]
+-            )
+-        )
+-    )
+-    @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
+-    def test_tree_ensemble_regressor_aggregation_functions(
+-        self, aggregate_function, expected_result, opset5
+-    ):
+-        x = np.arange(9).reshape((-1, 3)).astype(np.float32) / 10 - 0.5
+-        model_factory = (
+-            self._get_test_tree_ensemble_opset_latest
+-            if opset5
+-            else self._get_test_tree_ensemble_regressor
+-        )
+-        model_proto = model_factory(
+-            aggregate_function,
+-        )
+-        sess = ReferenceEvaluator(model_proto)
+-        (actual,) = sess.run(None, {"X": x})
+-        assert_allclose(actual, expected_result, atol=1e-6)
+-
+-    @parameterized.expand(
+-        tuple(
+-            itertools.chain.from_iterable(
+-                (
+-                    (
+-                        Mode.LEQ if opset5 else "BRANCH_LEQ",
+-                        np.array(
+-                            [[0.576923], [0.576923], [0.576923]], dtype=np.float32
+-                        ),
+-                        opset5,
+-                    ),
+-                    (
+-                        Mode.GT if opset5 else "BRANCH_GT",
+-                        np.array([[0.5], [0.5], [0.5]], dtype=np.float32),
+-                        opset5,
+-                    ),
+-                    (
+-                        Mode.LT if opset5 else "BRANCH_LT",
+-                        np.array(
+-                            [[0.576923], [0.576923], [0.576923]], dtype=np.float32
+-                        ),
+-                        opset5,
+-                    ),
+-                    (
+-                        Mode.GTE if opset5 else "BRANCH_GTE",
+-                        np.array([[0.5], [0.5], [0.5]], dtype=np.float32),
+-                        opset5,
+-                    ),
+-                    (
+-                        Mode.EQ if opset5 else "BRANCH_EQ",
+-                        np.array([[1.0], [1.0], [1.0]], dtype=np.float32),
+-                        opset5,
+-                    ),
+-                    (
+-                        Mode.NEQ if opset5 else "BRANCH_NEQ",
+-                        np.array(
+-                            [[0.076923], [0.076923], [0.076923]], dtype=np.float32
+-                        ),
+-                        opset5,
+-                    ),
+-                )
+-                for opset5 in [True, False]
+-            )
+-        )
+-    )
+-    @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
+-    def test_tree_ensemble_regressor_rule(self, rule, expected, opset5):
+-        x = np.arange(9).reshape((-1, 3)).astype(np.float32) / 10 - 0.5
+-        model_factory = (
+-            self._get_test_tree_ensemble_opset_latest
+-            if opset5
+-            else self._get_test_tree_ensemble_regressor
+-        )
+-        aggregate_function = AggregationFunction.SUM if opset5 else "SUM"
+-
+-        model_proto = model_factory(aggregate_function, rule)
+-        sess = ReferenceEvaluator(model_proto)
+-        (actual,) = sess.run(None, {"X": x})
+-        assert_allclose(actual, expected, atol=1e-6)
+-
+     @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
+     def test_tree_ensemble_regressor_2_targets_opset3(self):
+         X = make_tensor_value_info("X", TensorProto.FLOAT, [None, None])
+@@ -1118,23 +1005,6 @@ class TestReferenceEvaluatorAiOnnxMl(unittest.TestCase):
+         assert_allclose(got[0], expected, atol=1e-6)
+         self.assertIn("op_type=TreeEnsembleRegressor", str(sess.rt_nodes_[0]))
+ 
+-    @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
+-    @parameterized.expand(
+-        [(input_type,) for input_type in [TensorProto.FLOAT, TensorProto.DOUBLE]]
+-    )
+-    def test_tree_ensemble_missing_opset5(self, input_type):
+-        model = self._get_test_tree_ensemble_opset_latest(
+-            AggregationFunction.SUM, Mode.LEQ, True, input_type
+-        )
+-        np_dtype = onnx.helper.tensor_dtype_to_np_dtype(input_type)
+-        x = np.arange(9).reshape((-1, 3)).astype(np_dtype) / 10 - 0.5
+-        x[2, 0] = 5
+-        x[1, :] = np.nan
+-        expected = np.array([[100001.0], [100100.0], [100100.0]], dtype=np_dtype)
+-        session = ReferenceEvaluator(model)
+-        (actual,) = session.run(None, {"X": x})
+-        assert_allclose(actual, expected, atol=1e-6)
+-
+     @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
+     def test_tree_ensemble_regressor_missing_opset5_float16(self):
+         model = self._get_test_tree_ensemble_opset_latest(
+diff --git a/onnx/test/reference_evaluator_test.py b/onnx/test/reference_evaluator_test.py
+index 85cc4cc0e..d0a255fc8 100644
+--- a/onnx/test/reference_evaluator_test.py
++++ b/onnx/test/reference_evaluator_test.py
+@@ -25,7 +25,6 @@ from typing import TYPE_CHECKING
+ 
+ import ml_dtypes
+ import numpy as np
+-import parameterized
+ import version_utils
+ from numpy.testing import assert_allclose
+ 
+@@ -2998,163 +2997,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+         # model
+         return make_model(graph, opset_imports=[make_opsetid("", opset)])
+ 
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            [
+-                (
+-                    "ReduceMin",
+-                    [
+-                        np.array(
+-                            [[np.nan, np.nan], [14.422706, 18.80527]], dtype=np.float32
+-                        ),
+-                        np.array([[2, 15], [10, 4]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceL1",
+-                    [
+-                        np.array(
+-                            [[2.2367053, 2.3516612], [4.076292, 4.2970634]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[18, 6], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceL2",
+-                    [
+-                        np.array(
+-                            [[1.80155, 1.8169948], [2.9928076, 3.1205883]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[11, 18], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceLogSum",
+-                    [
+-                        np.array(
+-                            [[0.9497848, 1.1872643], [1.6764175, 1.70759]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[6, 18], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceLogSumExp",
+-                    [
+-                        np.array(
+-                            [[1.6005973, 1.7445935], [2.5616229, 2.6539795]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[13, 6], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceMax",
+-                    [
+-                        np.array(
+-                            [[1.4217108, 1.5069536], [2.453826, 2.5041783]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[13, 11], [13, 11]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceMean",
+-                    [
+-                        np.array(
+-                            [[0.39247903, 0.78497636], [2.038146, 2.1485317]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[13, 6], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceSumSquare",
+-                    [
+-                        np.array(
+-                            [[3.2455828, 3.3014696], [8.956896, 9.7380705]],
+-                            dtype=np.float32,
+-                        ),
+-                        np.array([[11, 18], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-                (
+-                    "ReduceProd",
+-                    [
+-                        np.array(
+-                            [[np.nan, np.nan], [14.422706, 18.80527]], dtype=np.float32
+-                        ),
+-                        np.array([[2, 15], [13, 6]], dtype=np.int64),
+-                    ],
+-                ),
+-            ],
+-            [17, 18],
+-        )
+-    )
+-    def test_op_reduce(self, reduce_op_expected, opset: int):
+-        reduce_op, expected = reduce_op_expected
+-        X = np.arange(8).reshape((-1, 4)).astype(np.float32)
+-
+-        results = {}
+-
+-        model = self._cdist_model(opset, reduce_op)
+-        sess = ReferenceEvaluator(model)
+-        got = sess.run(None, {"input": X})
+-        results["ref", opset] = got
+-
+-        cl = [
+-            n
+-            for n in sess.rt_nodes_[0].body.rt_nodes_
+-            if n.__class__.__name__.startswith(reduce_op)
+-        ]
+-        schema = cl[0]._schema
+-        new_cl = type(reduce_op, (cl[0].__class__,), {"op_schema": schema})
+-        sess = ReferenceEvaluator(model, new_ops=[new_cl])
+-        got = sess.run(None, {"input": X})
+-        results["ref_cl", opset] = got
+-
+-        baseline = "constant"
+-        for k, v in results.items():
+-            for a, b in zip(reversed(expected), reversed(v), strict=True):
+-                if a.shape != b.shape:
+-                    raise AssertionError(
+-                        f"Shape mismatch for {reduce_op!r}, {baseline}:{a.shape} != {k}:{b.shape}."
+-                    )
+-                diff = np.abs(a - b).max()
+-                if diff > 1e-6:
+-                    raise AssertionError(
+-                        f"Discrepancies (max={diff}) for {reduce_op!r}, {baseline} != {k}\n{a}\n!=\n{b}"
+-                    )
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            (13,),
+-            (17,),
+-            (18,),
+-        ]
+-    )
+-    def test_mvn(self, opset: int, ref_opset: int = 13):
+-        X = make_tensor_value_info("X", TensorProto.FLOAT, [None, None, None, None])
+-        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None, None, None, None])
+-        nodes = [
+-            make_node("MeanVarianceNormalization", ["X"], ["Y"]),
+-        ]
+-        graph = make_graph(nodes, "g", [X], [Y])
+-        x = np.random.rand(3, 3, 3, 1).astype(np.float32)
+-
+-        onnx_model = make_model(graph, opset_imports=[make_opsetid("", opset)])
+-        ref = ReferenceEvaluator(onnx_model)
+-        got = ref.run(None, {"X": x})[0]
+-
+-        ref_onnx_model = make_model(graph, opset_imports=[make_opsetid("", ref_opset)])
+-        ref_expected = ReferenceEvaluator(ref_onnx_model)
+-        expected = ref_expected.run(None, {"X": x})[0]
+-
+-        self.assertEqual(got.shape, expected.shape)
+-        assert_allclose(got, expected)
+-
+     def test_concat_in_a_function(self):
+         def create_model():
+             nodes = []
+@@ -3829,211 +3671,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+         got = ref.run(None, {"X": data})
+         assert_allclose(got[0], expected)
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            (
+-                4 * np.arange(12).reshape(3, 4),
+-                np.arange(1, 7).reshape(3, 2),
+-                np.zeros((3, 2)),
+-                1,
+-                2,
+-                [[0, 4, 4, 6], [5, 7, 6, 7], [6, 7, 7, 7]],
+-            ),
+-            (
+-                4 * np.arange(12).reshape(3, 4),
+-                np.arange(1, 7).reshape(3, 2),
+-                np.ones((3, 2)),
+-                1,
+-                2,
+-                [[1, 5, 5, 7], [6, 8, 7, 8], [7, 8, 8, 8]],
+-            ),
+-            (
+-                np.arange(24).reshape(3, 8),
+-                [[0.25, 0.5, 1], [0.25, 0.5, 1], [0.25, 0.5, 1]],
+-                np.zeros((3, 3)),
+-                1,
+-                3,
+-                [
+-                    [0, 4, 8, 6, 8, 10, 6, 7],
+-                    [32, 36, 40, 22, 24, 26, 14, 15],
+-                    [64, 68, 72, 38, 40, 42, 22, 23],
+-                ],
+-            ),
+-            (
+-                np.arange(6),
+-                [0.25, 0.5],
+-                [-1, -2],
+-                0,
+-                3,
+-                [-1, 3, 7, 4, 6, 8],
+-            ),
+-            (
+-                np.ones((9, 12)),
+-                np.ones((3, 4)),
+-                np.zeros((3, 4)),
+-                0,
+-                3,
+-                None,  # Blocked quantization is defined for 1-D blocks only
+-            ),
+-            (
+-                np.ones((3, 4, 5, 6)),
+-                np.ones((3, 4)),
+-                np.zeros((3, 4)),
+-                2,
+-                2,
+-                None,  # Scale and ZP must have the same rank as the input
+-            ),
+-        ]
+-    )
+-    def test_blocked_quantize_linear(
+-        self, x, scale, zero_point, axis, block_size, expected
+-    ):
+-        X = make_tensor_value_info("X", TensorProto.FLOAT, [None])
+-        Y = make_tensor_value_info("Y", TensorProto.INT8, [None])
+-
+-        scale_data = np.array(scale, dtype=np.float32)
+-        zp_data = np.array(zero_point, dtype=np.int8)
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node(
+-                        "QuantizeLinear",
+-                        ["X", "scale", "zero"],
+-                        ["Y"],
+-                        axis=axis,
+-                        block_size=block_size,
+-                    ),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-                [
+-                    make_tensor(
+-                        "scale", TensorProto.FLOAT, scale_data.shape, scale_data
+-                    ),
+-                    make_tensor("zero", TensorProto.INT8, scale_data.shape, zp_data),
+-                ],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-
+-        data = np.array(x, dtype=np.float32)
+-
+-        if expected is not None:
+-            expected = np.array(expected, dtype=np.int8)
+-            got = ref.run(None, {"X": data})
+-            assert_allclose(got[0], expected)
+-        else:
+-            with self.assertRaises(ValueError):
+-                ref.run(None, {"X": data})
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            (
+-                np.arange(12).reshape(3, 4),
+-                np.arange(1, 7).reshape(3, 2),
+-                np.zeros((3, 2)),
+-                1,
+-                2,
+-                [[0, 1, 4, 6], [12, 15, 24, 28], [40, 45, 60, 66]],
+-            ),
+-            (
+-                np.arange(12).reshape(3, 4),
+-                np.arange(1, 7).reshape(3, 2),
+-                np.ones((3, 2)),
+-                1,
+-                2,
+-                [[-1, 0, 2, 4], [9, 12, 20, 24], [35, 40, 54, 60]],
+-            ),
+-            (
+-                np.dstack([np.arange(4).reshape(2, 2)] * 4),
+-                np.dstack([np.array([[1, 1], [2, 3]]), np.array([[4, 5], [6, 7]])]),
+-                np.zeros((2, 2, 2)),
+-                2,
+-                2,
+-                [[[0, 0, 0, 0], [1, 1, 5, 5]], [[4, 4, 12, 12], [9, 9, 21, 21]]],
+-            ),
+-            (
+-                np.arange(24).reshape(3, 8),
+-                [[2, 1, 3], [2, 1, 3], [2, 1, 3]],
+-                np.zeros((3, 3)),
+-                1,
+-                3,
+-                [
+-                    [0, 2, 4, 3, 4, 5, 18, 21],
+-                    [16, 18, 20, 11, 12, 13, 42, 45],
+-                    [32, 34, 36, 19, 20, 21, 66, 69],
+-                ],
+-            ),
+-            (
+-                np.arange(
+-                    6,
+-                ),
+-                [2, 3],
+-                [1, 2],
+-                0,
+-                3,
+-                [-2, 0, 2, 3, 6, 9],
+-            ),
+-            (
+-                np.ones((9, 12)),
+-                np.ones((3, 4)),
+-                np.zeros((3, 4)),
+-                0,
+-                3,
+-                None,  # Blocked quantization is defined for 1-D blocks only
+-            ),
+-            (
+-                np.ones((3, 4, 5, 6)),
+-                np.ones((3, 4)),
+-                np.zeros((3, 4)),
+-                2,
+-                2,
+-                None,  # Scale and ZP must have the same rank as the input
+-            ),
+-        ]
+-    )
+-    def test_blocked_dequantize_linear(
+-        self, x, scale, zero_point, axis, block_size, expected
+-    ):
+-        X = make_tensor_value_info("X", TensorProto.INT8, [None])
+-        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None])
+-
+-        scale_data = np.array(scale, dtype=np.float32)
+-        zp_data = np.array(zero_point, dtype=np.int8)
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node(
+-                        "DequantizeLinear",
+-                        ["X", "scale", "zero"],
+-                        ["Y"],
+-                        axis=axis,
+-                        block_size=block_size,
+-                    ),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-                [
+-                    make_tensor(
+-                        "scale", TensorProto.FLOAT, scale_data.shape, scale_data
+-                    ),
+-                    make_tensor("zero", TensorProto.INT8, scale_data.shape, zp_data),
+-                ],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        data = np.array(x, dtype=np.int8)
+-
+-        if expected is not None:
+-            expected = np.array(expected, dtype=np.float32)
+-            got = ref.run(None, {"X": data})
+-            assert_allclose(got[0], expected)
+-        else:
+-            with self.assertRaises(ValueError):
+-                ref.run(None, {"X": data})
+-
+     def test_lrn(self):
+         def _expected(x, alpha, beta, bias, size):
+             square_sum = np.zeros((5, 5, 5, 5)).astype(np.float32)
+@@ -4217,52 +3854,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+         got = _conv_implementation_im2col(**feeds, **kwargs)
+         assert_allclose(got, expected)
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            ("ReduceSum",),
+-            ("ReduceL1",),
+-            ("ReduceL2",),
+-            ("ReduceMin",),
+-            ("ReduceMax",),
+-            ("ReduceProd",),
+-            ("ReduceSumSquare",),
+-        ]
+-    )
+-    def test_reduce_op_no_axis(self, op):
+-        X = make_tensor_value_info("X", TensorProto.FLOAT, None)
+-        Y = make_tensor_value_info("Y", TensorProto.FLOAT, None)
+-        data = np.arange(6).reshape((1, 3, 2)).astype(np.float32)
+-        nodes = [make_node(op, ["X"], ["Y"], keepdims=0)]
+-        model = make_model(make_graph(nodes, "g", [X], [Y]))
+-        ref = ReferenceEvaluator(model)
+-        got = ref.run(None, {"X": data})
+-        r = got[0]
+-        self.assertIsInstance(r, np.ndarray)
+-        self.assertEqual(r.shape, ())
+-
+-    @parameterized.parameterized.expand([(1,), (2,), (3,), (4,), (5,), (6,)])
+-    def test_pad(self, dim):
+-        X = make_tensor_value_info("X", TensorProto.FLOAT, None)
+-        P = make_tensor_value_info("P", TensorProto.INT64, None)
+-        V = make_tensor_value_info("V", TensorProto.FLOAT, None)
+-        Y = make_tensor_value_info("Y", TensorProto.FLOAT, None)
+-        value = np.array([-5], dtype=np.float32)
+-
+-        node = make_node("Pad", inputs=["X", "P", "V"], outputs=["Y"], mode="constant")
+-        model = make_model(make_graph([node], "g", [X, P, V], [Y]))
+-        ref = ReferenceEvaluator(model)
+-        x = np.array([1], dtype=np.float32).reshape((1,) * dim)
+-
+-        p = np.array([1, 1] * dim, dtype=np.int64)
+-        got = ref.run(None, {"X": x, "P": p, "V": value})[0]
+-        self.assertEqual(got.shape, (3,) * dim)
+-        self.assertEqual(got.dtype, np.float32)
+-
+-        p = np.repeat([7, 3], dim).astype(np.int64)
+-        got = ref.run(None, {"X": x, "P": p, "V": value})[0]
+-        self.assertEqual(got.shape, (11,) * dim)
+-        self.assertEqual(got.dtype, np.float32)
+-
+     def test_constant_of_shape(self):
+         X = make_tensor_value_info("X", TensorProto.FLOAT, None)
+         Y = make_tensor_value_info("Y", TensorProto.FLOAT, None)
+@@ -5373,124 +4964,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+         for i in range(2, -1, -1):
+             assert_allclose(got[i], expected[i])
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            (["abc", "def"], [".com", ".net"], ["abc.com", "def.net"], (2,)),
+-            (["cat", "dog", "snake"], ["s"], ["cats", "dogs", "snakes"], (3,)),
+-            ("cat", "s", "cats", ()),
+-            (["a", "ß", "y"], ["a", "ß", "y"], ["aa", "ßß", "yy"], (3,)),
+-        ]
+-    )
+-    def test_string_concat(self, a, b, expected, expected_shape):
+-        A = make_tensor_value_info("A", TensorProto.STRING, None)
+-        B = make_tensor_value_info("B", TensorProto.STRING, None)
+-        Y = make_tensor_value_info("Y", TensorProto.STRING, None)
+-        node = make_node("StringConcat", inputs=["A", "B"], outputs=["Y"])
+-        model = make_model(make_graph([node], "g", [A, B], [Y]))
+-        ref = ReferenceEvaluator(model)
+-        result, *_ = ref.run(None, {"A": np.array(a), "B": np.array(b)})
+-        np.testing.assert_array_equal(result, expected)
+-        self.assertIn(result.dtype.kind, {"O", "U"})
+-        self.assertEqual(result.shape, expected_shape)
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            (
+-                ["1,2,3", "4,5,6"],
+-                ",",
+-                None,
+-                [["1", "2", "3"], ["4", "5", "6"]],
+-                [3, 3],
+-            ),
+-            (
+-                ["1,", "4,6", ""],
+-                ",",
+-                None,
+-                [["1", ""], ["4", "6"], ["", ""]],
+-                [2, 2, 1],
+-            ),
+-            (
+-                ["1", "4,6", "4,5,6"],
+-                ",",
+-                1,
+-                [["1", ""], ["4", "6"], ["4", "5,6"]],
+-                [1, 2, 2],
+-            ),
+-            (
+-                [["1,", "4,6", "4,5,6"], ["1,", "4,6", "4,5,6"]],
+-                ",",
+-                None,
+-                [
+-                    [["1", "", ""], ["4", "6", ""], ["4", "5", "6"]],
+-                    [["1", "", ""], ["4", "6", ""], ["4", "5", "6"]],
+-                ],
+-                [[2, 2, 3], [2, 2, 3]],
+-            ),
+-            (
+-                ["hello world !", "  hello   world !", " hello world   ! "],
+-                None,
+-                None,
+-                [
+-                    ["hello", "world", "!"],
+-                    ["hello", "world", "!"],
+-                    ["hello", "world", "!"],
+-                ],
+-                [3, 3, 3],
+-            ),
+-            (
+-                ["hello world !", "  hello   world !", " hello world   ! "],
+-                "",
+-                None,
+-                [
+-                    ["hello", "world", "!"],
+-                    ["hello", "world", "!"],
+-                    ["hello", "world", "!"],
+-                ],
+-                [3, 3, 3],
+-            ),
+-            (
+-                ["o-n-n--x-", "o-n----nx"],
+-                "-",
+-                None,
+-                [["o", "n", "n", "", "x", ""], ["o", "n", "", "", "", "nx"]],
+-                [6, 6],
+-            ),
+-            (
+-                [],
+-                " ",
+-                2,
+-                np.array([]).reshape((0, 0)),
+-                [],
+-            ),
+-        ]
+-    )
+-    def test_string_split(
+-        self,
+-        x,
+-        delimiter,
+-        maxsplit,
+-        expected_split,
+-        expected_num_splits,
+-    ):
+-        X = make_tensor_value_info("X", TensorProto.STRING, (None))
+-        Splits = make_tensor_value_info("Splits", TensorProto.STRING, (None))
+-        MaxSplits = make_tensor_value_info("MaxSplits", TensorProto.INT32, (None))
+-        node = make_node(
+-            "StringSplit",
+-            inputs=["X"],
+-            outputs=["Splits", "MaxSplits"],
+-            delimiter=delimiter,
+-            maxsplit=maxsplit,
+-        )
+-        model = make_model(make_graph([node], "g", [X], [Splits, MaxSplits]))
+-        ref = ReferenceEvaluator(model)
+-        x = np.array(x, dtype=object)
+-        result, num_splits, *_ = ref.run(None, {"X": x})
+-        np.testing.assert_array_equal(result, np.array(expected_split, dtype=object))
+-        np.testing.assert_array_equal(
+-            num_splits, np.array(expected_num_splits, dtype=np.int64)
+-        )
+-
+     def test_qlinearconv_int8(self):
+         node = make_node(
+             "QLinearMatMul",
+@@ -5561,44 +5034,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+             np.array([[41, -12, -9], [1, -75, 20]], dtype=np.int8), got[0]
+         )
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            (
+-                ["www.google.com", "www.facebook.com", "www.bbc.co.uk"],
+-                r"www\.[\w.-]+\.\bcom\b",
+-                [True, True, False],
+-                (3,),
+-            ),
+-            (
+-                [["Onnx", "tensorflow", "Numpy"], ["Pytorch", "Cython", "numba"]],
+-                r"^[A-Z][a-z]*$",
+-                [[True, False, True], [True, True, False]],
+-                (2, 3),
+-            ),
+-            (
+-                [
+-                    "account@gmail.com",
+-                    "account@hotmail.com",
+-                    "not email",
+-                    "account2@yahoo.com",
+-                ],
+-                r"(\W|^)[\w.\-]{0,25}@(yahoo|gmail)\.com(\W|$)",
+-                [True, False, False, True],
+-                (4,),
+-            ),
+-        ]
+-    )
+-    def test_regex_full_match(self, x, pattern, expected, expected_shape):
+-        X = make_tensor_value_info("X", TensorProto.STRING, None)
+-        Y = make_tensor_value_info("Y", TensorProto.BOOL, None)
+-        node = make_node("RegexFullMatch", inputs=["X"], outputs=["Y"], pattern=pattern)
+-        model = make_model(make_graph([node], "g", [X], [Y]))
+-        ref = ReferenceEvaluator(model)
+-        result, *_ = ref.run(None, {"X": np.array(x)})
+-        np.testing.assert_array_equal(result, expected)
+-        self.assertEqual(result.dtype.kind, "b")
+-        self.assertEqual(result.shape, expected_shape)
+-
+     def test_regex_invalid_pattern(self):
+         X = make_tensor_value_info("X", TensorProto.STRING, None)
+         Y = make_tensor_value_info("Y", TensorProto.BOOL, None)
+@@ -5608,220 +5043,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+         with self.assertRaises(ValueError):
+             ref.run(None, {"X": np.array(["x"])})
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            (
+-                TensorProto.UINT2,
+-                [-1, 0, 1.5, 2, 3.3, 10, 20, 40],
+-                [0, 0, 2, 2, 4, 6, 6, 6],
+-            ),
+-            (TensorProto.UINT2, [-1, 0, 1.5, 2, 3.3, 10, 40], [0, 0, 2, 2, 4, 6, 6]),
+-            (TensorProto.UINT2, [0], [0]),
+-            (
+-                TensorProto.INT2,
+-                [-20, -14.5, 0, 1.5, 2, 3.3, 10, 20],
+-                [-4, -4, 0, 2, 2, 2, 2, 2],
+-            ),
+-            (
+-                TensorProto.INT2,
+-                [-20, -14.5, 0, 1.5, 2, 3.3, 10],
+-                [-4, -4, 0, 2, 2, 2, 2],
+-            ),
+-            (TensorProto.INT2, [0], [0]),
+-        ]
+-    )
+-    def test_quantize_linear_int2(self, qtype, data, expected):
+-        X = make_tensor_value_info("X", TensorProto.FLOAT, [None])
+-        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None])
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["scale"],
+-                        value=make_tensor("scale", TensorProto.FLOAT, [1], [2.0]),
+-                    ),
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["zero"],
+-                        value=make_tensor("zero", qtype, [1], [0]),
+-                    ),
+-                    make_node("QuantizeLinear", ["X", "scale", "zero"], ["T"]),
+-                    make_node("DequantizeLinear", ["T", "scale"], ["Y"], axis=0),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        got = ref.run(None, {"X": np.asarray(data)})
+-        assert_allclose(got[0], expected)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.FLOAT, TensorProto.FLOAT16),
+-            (TensorProto.UINT2, TensorProto.INT2),
+-        )
+-    )
+-    def test_cast_int2_output(self, cast_from, cast_to):
+-        X = make_tensor_value_info("X", cast_from, [None])
+-        Y = make_tensor_value_info("Y", cast_to, [None])
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node("Cast", ["X"], ["Y"], to=cast_to),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        data = np.array(
+-            [0, 1, 2.4, 2.6, 4, 10],
+-            dtype=onnx.helper.tensor_dtype_to_np_dtype(cast_from),
+-        )
+-        expected = data.astype(onnx.helper.tensor_dtype_to_np_dtype(cast_to))
+-        got = ref.run(None, {"X": data})
+-        self.assertEqual(got[0].tolist(), expected.tolist())
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.UINT2, TensorProto.INT2),
+-            (TensorProto.FLOAT, TensorProto.FLOAT16),
+-        )
+-    )
+-    def test_cast_int2_input(
+-        self, cast_from: TensorProto.DataType, cast_to: TensorProto.DataType
+-    ):
+-        X = make_tensor_value_info("X", cast_from, [None])
+-        Y = make_tensor_value_info("Y", cast_to, [None])
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node("Cast", ["X"], ["Y"], to=TensorProto.FLOAT),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        data = np.array(range(2), dtype=np.float32)
+-        expected = data.astype(onnx.helper.tensor_dtype_to_np_dtype(cast_from))
+-        got = ref.run(None, {"X": data})
+-        np.testing.assert_array_equal(got[0], expected)
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            (
+-                TensorProto.UINT4,
+-                [-1, 0, 1.5, 2, 3.3, 10, 20, 40],
+-                [0, 0, 2, 2, 4, 10, 20, 30],
+-            ),
+-            (TensorProto.UINT4, [-1, 0, 1.5, 2, 3.3, 10, 40], [0, 0, 2, 2, 4, 10, 30]),
+-            (TensorProto.UINT4, [0], [0]),
+-            (
+-                TensorProto.INT4,
+-                [-20, -14.5, 0, 1.5, 2, 3.3, 10, 20],
+-                [-16, -14, 0, 2, 2, 4, 10, 14],
+-            ),
+-            (
+-                TensorProto.INT4,
+-                [-20, -14.5, 0, 1.5, 2, 3.3, 10],
+-                [-16, -14, 0, 2, 2, 4, 10],
+-            ),
+-            (TensorProto.INT4, [0], [0]),
+-        ]
+-    )
+-    def test_quantize_linear_int4(self, qtype, data, expected):
+-        X = make_tensor_value_info("X", TensorProto.FLOAT, [None])
+-        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None])
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["scale"],
+-                        value=make_tensor("scale", TensorProto.FLOAT, [1], [2.0]),
+-                    ),
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["zero"],
+-                        value=make_tensor("zero", qtype, [1], [0]),
+-                    ),
+-                    make_node("QuantizeLinear", ["X", "scale", "zero"], ["T"]),
+-                    make_node("DequantizeLinear", ["T", "scale"], ["Y"], axis=0),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        got = ref.run(None, {"X": np.asarray(data)})
+-        assert_allclose(got[0], expected)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.FLOAT, TensorProto.FLOAT16),
+-            (TensorProto.UINT4, TensorProto.INT4),
+-        )
+-    )
+-    def test_cast_int4_output(self, cast_from, cast_to):
+-        X = make_tensor_value_info("X", cast_from, [None])
+-        Y = make_tensor_value_info("Y", cast_to, [None])
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node("Cast", ["X"], ["Y"], to=cast_to),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        data = np.array(
+-            [0, 1, 2.4, 2.6, 4, 10],
+-            dtype=onnx.helper.tensor_dtype_to_np_dtype(cast_from),
+-        )
+-        expected = data.astype(onnx.helper.tensor_dtype_to_np_dtype(cast_to))
+-        got = ref.run(None, {"X": data})
+-        self.assertEqual(got[0].tolist(), expected.tolist())
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (TensorProto.UINT4, TensorProto.INT4),
+-            (TensorProto.FLOAT, TensorProto.FLOAT16),
+-        )
+-    )
+-    def test_cast_int4_input(
+-        self, cast_from: TensorProto.DataType, cast_to: TensorProto.DataType
+-    ):
+-        X = make_tensor_value_info("X", cast_from, [None])
+-        Y = make_tensor_value_info("Y", cast_to, [None])
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node("Cast", ["X"], ["Y"], to=TensorProto.FLOAT),
+-                ],
+-                "g",
+-                [X],
+-                [Y],
+-            )
+-        )
+-        ref = ReferenceEvaluator(model)
+-        data = np.array(range(7), dtype=np.float32)
+-        expected = data.astype(onnx.helper.tensor_dtype_to_np_dtype(cast_from))
+-        got = ref.run(None, {"X": data})
+-        np.testing.assert_array_equal(got[0], expected)
+-
+     def test_a_function_calling_a_function_once(self):
+         X = make_tensor_value_info("X", TensorProto.FLOAT, ["N"])
+         output = make_tensor_value_info("output", TensorProto.FLOAT, ["N"])
+@@ -6054,94 +5275,6 @@ class TestReferenceEvaluator(unittest.TestCase):
+         for v in oinf.functions_.values():
+             self.assertIsInstance(v, MyReferenceEvaluator)
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            ("FLOAT8E4M3FN", 0.23),
+-            ("FLOAT8E4M3FNUZ", 0.23),
+-            ("FLOAT8E5M2", 0.85),
+-            ("FLOAT8E5M2FNUZ", 0.85),
+-            ("DOUBLE", 0),
+-            ("FLOAT", 0),
+-            ("FLOAT16", 2e-3),
+-            ("BFLOAT16", 2e-2),
+-        ]
+-    )
+-    def test_add_custom_dtype(self, stype: str, atol: float):
+-        itype = getattr(TensorProto, stype)
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node("Cast", ["X"], ["Xc"], to=itype),
+-                    make_node("Cast", ["Y"], ["Yc"], to=itype),
+-                    make_node("Add", ["Xc", "Yc"], ["Zc"]),
+-                    make_node("Cast", ["Zc"], ["Z"], to=TensorProto.FLOAT),
+-                ],
+-                "nd",
+-                [
+-                    make_tensor_value_info("X", TensorProto.FLOAT, [None, None, None]),
+-                    make_tensor_value_info("Y", TensorProto.FLOAT, [None, None, None]),
+-                ],
+-                [make_tensor_value_info("Z", TensorProto.FLOAT, [None, None, None])],
+-            ),
+-            opset_imports=[make_opsetid("", 18)],
+-            ir_version=9,
+-        )
+-
+-        ref = ReferenceEvaluator(model, verbose=0)
+-
+-        x = (np.arange(18) / 6).reshape((2, 3, 3)).astype(np.float32)
+-        y = (np.arange(18) / 9).reshape((2, 3, 3)).astype(np.float32)
+-        feeds = dict(X=x, Y=y)
+-        expected = x + y
+-        got = ref.run(None, feeds)[0]
+-        assert_allclose(got, expected, atol=atol)
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            ("DOUBLE",),
+-            ("FLOAT",),
+-            ("FLOAT16",),
+-            ("BFLOAT16",),
+-            ("FLOAT8E4M3FN",),
+-            ("FLOAT8E4M3FNUZ",),
+-            ("FLOAT8E5M2",),
+-            ("FLOAT8E5M2FNUZ",),
+-            ("INT4",),
+-            ("UINT4",),
+-            ("INT2",),
+-            ("UINT2",),
+-        ]
+-    )
+-    def test_cmp_custom_dtype(self, stype):
+-        itype = getattr(TensorProto, stype)
+-        model = make_model(
+-            make_graph(
+-                [
+-                    make_node("Cast", ["X"], ["Xc"], to=itype),
+-                    make_node("Cast", ["Y"], ["Yc"], to=itype),
+-                    make_node("GreaterOrEqual", ["Xc", "Yc"], ["Zc"]),
+-                    make_node("Cast", ["Zc"], ["Z"], to=TensorProto.BOOL),
+-                ],
+-                "nd",
+-                [
+-                    make_tensor_value_info("X", TensorProto.FLOAT, [None, None, None]),
+-                    make_tensor_value_info("Y", TensorProto.FLOAT, [None, None, None]),
+-                ],
+-                [make_tensor_value_info("Z", TensorProto.FLOAT, [None, None, None])],
+-            ),
+-            opset_imports=[make_opsetid("", 18)],
+-            ir_version=9,
+-        )
+-
+-        ref = ReferenceEvaluator(model)
+-
+-        x = (np.arange(18) / 18).reshape((2, 3, 3)).astype(np.float32)
+-        y = ((np.arange(18) - 9) / 18).reshape((2, 3, 3)).astype(np.float32)
+-        feeds = dict(X=x, Y=y)
+-        expected = x >= y
+-        got = ref.run(None, feeds)[0]
+-        np.testing.assert_equal(got, expected)
+-
+     def test_scatter_elements_4d(self):
+         model = make_model(
+             make_graph(
+diff --git a/onnx/test/schema_test.py b/onnx/test/schema_test.py
+index f8b3f8a65..710b602a3 100644
+--- a/onnx/test/schema_test.py
++++ b/onnx/test/schema_test.py
+@@ -7,8 +7,6 @@ import contextlib
+ import unittest
+ from typing import TYPE_CHECKING
+ 
+-import parameterized
+-
+ import onnx
+ from onnx import defs
+ 
+@@ -247,34 +245,6 @@ class TestFormalParameter(unittest.TestCase):
+         )
+ 
+ 
+-class TestTypeConstraintParam(unittest.TestCase):
+-    @parameterized.parameterized.expand(
+-        [
+-            ("single_type", "T", ["tensor(float)"], "Test description"),
+-            (
+-                "double_types",
+-                "T",
+-                ["tensor(float)", "tensor(int64)"],
+-                "Test description",
+-            ),
+-            ("tuple", "T", ("tensor(float)", "tensor(int64)"), "Test description"),
+-        ]
+-    )
+-    def test_init(
+-        self,
+-        _: str,
+-        type_param_str: str,
+-        allowed_types: Sequence[str],
+-        description: str,
+-    ) -> None:
+-        type_constraint = defs.OpSchema.TypeConstraintParam(
+-            type_param_str, allowed_types, description
+-        )
+-        self.assertEqual(type_constraint.description, description)
+-        self.assertEqual(type_constraint.allowed_type_strs, list(allowed_types))
+-        self.assertEqual(type_constraint.type_param_str, type_param_str)
+-
+-
+ class TestAttribute(unittest.TestCase):
+     def test_init(self):
+         name = "test_attr"
+@@ -297,169 +267,5 @@ class TestAttribute(unittest.TestCase):
+         self.assertEqual("attr1 description", attribute.description)
+ 
+ 
+-@parameterized.parameterized_class(
+-    [
+-        # register to exist domain
+-        {
+-            "op_type": "CustomOp",
+-            "op_version": 5,
+-            "op_domain": "",
+-            "trap_op_version": [1, 2, 6, 7],
+-        },
+-        # register to new domain
+-        {
+-            "op_type": "CustomOp",
+-            "op_version": 5,
+-            "op_domain": "test",
+-            "trap_op_version": [1, 2, 6, 7],
+-        },
+-    ]
+-)
+-class TestOpSchemaRegister(unittest.TestCase):
+-    op_type: str
+-    op_version: int
+-    op_domain: str
+-    # register some fake schema to check behavior
+-    trap_op_version: list[int]
+-
+-    def setUp(self) -> None:
+-        # Ensure the schema is unregistered
+-        self.assertFalse(onnx.defs.has(self.op_type, self.op_domain))
+-
+-    def tearDown(self) -> None:
+-        # Clean up the registered schema
+-        for version in [*self.trap_op_version, self.op_version]:
+-            with contextlib.suppress(onnx.defs.SchemaError):
+-                onnx.defs.deregister_schema(self.op_type, version, self.op_domain)
+-
+-    def test_register_multi_schema(self):
+-        for version in [*self.trap_op_version, self.op_version]:
+-            op_schema = defs.OpSchema(
+-                self.op_type,
+-                self.op_domain,
+-                version,
+-            )
+-            onnx.defs.register_schema(op_schema)
+-            self.assertTrue(onnx.defs.has(self.op_type, version, self.op_domain))
+-        for version in [*self.trap_op_version, self.op_version]:
+-            # Also make sure the `op_schema` is accessible after register
+-            registered_op = onnx.defs.get_schema(
+-                op_schema.name, version, op_schema.domain
+-            )
+-            op_schema = defs.OpSchema(
+-                self.op_type,
+-                self.op_domain,
+-                version,
+-            )
+-            self.assertEqual(str(registered_op), str(op_schema))
+-
+-    def test_using_the_specified_version_in_onnx_check(self):
+-        input = f"""
+-            <
+-                ir_version: 7,
+-                opset_import: [
+-                    "{self.op_domain}" : {self.op_version}
+-                ]
+-            >
+-            agraph (float[N, 128] X, int32 Y) => (float[N] Z)
+-            {{
+-                Z = {self.op_domain}.{self.op_type}<attr1=[1,2]>(X, Y)
+-            }}
+-           """
+-        model = onnx.parser.parse_model(input)
+-        op_schema = defs.OpSchema(
+-            self.op_type,
+-            self.op_domain,
+-            self.op_version,
+-            inputs=[
+-                defs.OpSchema.FormalParameter("input1", "T"),
+-                defs.OpSchema.FormalParameter("input2", "int32"),
+-            ],
+-            outputs=[
+-                defs.OpSchema.FormalParameter("output1", "T"),
+-            ],
+-            type_constraints=[("T", ["tensor(float)"], "")],
+-            attributes=[
+-                defs.OpSchema.Attribute(
+-                    "attr1", defs.OpSchema.AttrType.INTS, "attr1 description"
+-                )
+-            ],
+-        )
+-        with self.assertRaises(onnx.checker.ValidationError):
+-            onnx.checker.check_model(model, check_custom_domain=True)
+-        onnx.defs.register_schema(op_schema)
+-        # The fake schema will raise check exception if selected in checker
+-        for version in self.trap_op_version:
+-            onnx.defs.register_schema(
+-                defs.OpSchema(
+-                    self.op_type,
+-                    self.op_domain,
+-                    version,
+-                    outputs=[
+-                        defs.OpSchema.FormalParameter("output1", "int32"),
+-                    ],
+-                )
+-            )
+-        onnx.checker.check_model(model, check_custom_domain=True)
+-
+-    def test_register_schema_raises_error_when_registering_a_schema_twice(self):
+-        op_schema = defs.OpSchema(
+-            self.op_type,
+-            self.op_domain,
+-            self.op_version,
+-        )
+-        onnx.defs.register_schema(op_schema)
+-        with self.assertRaises(onnx.defs.SchemaError):
+-            onnx.defs.register_schema(op_schema)
+-
+-    def test_deregister_the_specified_schema(self):
+-        for version in [*self.trap_op_version, self.op_version]:
+-            op_schema = defs.OpSchema(
+-                self.op_type,
+-                self.op_domain,
+-                version,
+-            )
+-            onnx.defs.register_schema(op_schema)
+-            self.assertTrue(onnx.defs.has(op_schema.name, version, op_schema.domain))
+-        onnx.defs.deregister_schema(op_schema.name, self.op_version, op_schema.domain)
+-        for version in self.trap_op_version:
+-            self.assertTrue(onnx.defs.has(op_schema.name, version, op_schema.domain))
+-        # Maybe has lesser op version in trap list
+-        if onnx.defs.has(op_schema.name, self.op_version, op_schema.domain):
+-            schema = onnx.defs.get_schema(
+-                op_schema.name, self.op_version, op_schema.domain
+-            )
+-            self.assertLess(schema.since_version, self.op_version)
+-
+-    def test_deregister_schema_raises_error_when_opschema_does_not_exist(self):
+-        with self.assertRaises(onnx.defs.SchemaError):
+-            onnx.defs.deregister_schema(self.op_type, self.op_version, self.op_domain)
+-
+-    def test_legacy_schema_accessible_after_deregister(self):
+-        op_schema = defs.OpSchema(
+-            self.op_type,
+-            self.op_domain,
+-            self.op_version,
+-        )
+-        onnx.defs.register_schema(op_schema)
+-        schema_a = onnx.defs.get_schema(
+-            op_schema.name, op_schema.since_version, op_schema.domain
+-        )
+-        schema_b = onnx.defs.get_schema(op_schema.name, op_schema.domain)
+-
+-        def filter_schema(schemas):
+-            return [op for op in schemas if op.name == op_schema.name]
+-
+-        schema_c = filter_schema(onnx.defs.get_all_schemas())
+-        schema_d = filter_schema(onnx.defs.get_all_schemas_with_history())
+-        self.assertEqual(len(schema_c), 1)
+-        self.assertEqual(len(schema_d), 1)
+-        # Avoid memory residue and access storage as much as possible
+-        self.assertEqual(str(schema_a), str(op_schema))
+-        self.assertEqual(str(schema_b), str(op_schema))
+-        self.assertEqual(str(schema_c[0]), str(op_schema))
+-        self.assertEqual(str(schema_d[0]), str(op_schema))
+-
+-
+ if __name__ == "__main__":
+     unittest.main()
+diff --git a/onnx/test/shape_inference_test.py b/onnx/test/shape_inference_test.py
+index ee22c8ffb..849ae042a 100644
+--- a/onnx/test/shape_inference_test.py
++++ b/onnx/test/shape_inference_test.py
+@@ -12,7 +12,6 @@ from typing import TYPE_CHECKING, Any
+ import numpy as np
+ import pytest
+ from google.protobuf import text_format
+-from parameterized import parameterized
+ 
+ import onnx.shape_inference
+ from onnx import (
+@@ -244,86 +243,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             graph, [make_tensor_value_info("y", TensorProto.FLOAT, (30, 4, 5))]
+         )
+ 
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, (2, 3, 4))],
+-            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("Y", TensorProto.FLOAT, (3, 2, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose_preexisting(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, (2, 3, 4))],
+-            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
+-            [make_tensor_value_info("Y", TensorProto.FLOAT, None)],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("Y", TensorProto.FLOAT, (3, 2, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose_scalar(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, ())],
+-            [make_node("Transpose", ["X"], ["Y"])],
+-            [],
+-        )
+-
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("Y", TensorProto.FLOAT, ())],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose_partial(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, (2, 3, 4))],
+-            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
+-            [make_tensor_value_info("Y", TensorProto.UNDEFINED, (3, "a", "b"))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("Y", TensorProto.FLOAT, (3, 2, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose_preexisting_incorrect_shape(self, *_) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, (2, 3, 4))],
+-            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
+-            [make_tensor_value_info("Y", TensorProto.FLOAT, (5, 5, 5))],
+-        )
+-        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
+-
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose_preexisting_incorrect_type(self, *_) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, (2, 3, 4))],
+-            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
+-            [make_tensor_value_info("Y", TensorProto.STRING, (3, 2, 4))],
+-        )
+-        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
+-
+-    @parameterized.expand(all_versions_for("Transpose"))
+-    def test_transpose_incorrect_repeated_perm(self, *_) -> None:
+-        graph = self._make_graph(
+-            [("X", TensorProto.FLOAT, (2, 3, 4))],
+-            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 1])],
+-            [],
+-        )
+-        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
+-
+     def _make_matmul_test_all_dims_known(
+         self, version, shape1: Sequence[int], shape2: Sequence[int]
+     ) -> None:
+@@ -342,21 +261,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+         )
+ 
+-    @parameterized.expand(all_versions_for("MatMul"))
+-    def test_matmul_all_dims_known(self, _, version) -> None:
+-        self._make_matmul_test_all_dims_known(version, (2,), (2,))
+-
+-        self._make_matmul_test_all_dims_known(version, (4, 2), (2, 4))
+-        self._make_matmul_test_all_dims_known(version, (5, 2), (2, 4))
+-        self._make_matmul_test_all_dims_known(version, (5, 2), (2, 1))
+-        self._make_matmul_test_all_dims_known(version, (1, 2), (2, 3))
+-        self._make_matmul_test_all_dims_known(version, (2,), (2, 3))
+-        self._make_matmul_test_all_dims_known(version, (4, 2), (2,))
+-        self._make_matmul_test_all_dims_known(version, (1, 4, 2), (3, 2, 3))
+-        self._make_matmul_test_all_dims_known(version, (3, 4, 2), (3, 2, 3))
+-        self._make_matmul_test_all_dims_known(version, (5, 1, 4, 2), (1, 3, 2, 3))
+-        self._make_matmul_test_all_dims_known(version, (4, 2), (3, 2, 3))
+-
+     def _make_matmul_test_allow_unknown(
+         self, version, shape1: Any, shape2: Any, expected_out_shape: Any
+     ) -> None:
+@@ -367,1318 +271,39 @@ class TestShapeInference(TestShapeInferenceHelper):
+         )
+         self._assert_inferred(
+             graph,
+-            [make_tensor_value_info("z", TensorProto.FLOAT, expected_out_shape)],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("MatMul"))
+-    def test_matmul_allow_unknown(self, _, version) -> None:
+-        self._make_matmul_test_allow_unknown(version, (None,), (None,), ())
+-        self._make_matmul_test_allow_unknown(version, (3,), (None,), ())
+-        self._make_matmul_test_allow_unknown(version, (2,), (2, "a"), ("a",))
+-        self._make_matmul_test_allow_unknown(version, (4, 2), (2, "a"), (4, "a"))
+-        self._make_matmul_test_allow_unknown(version, (4, None), (2, "a"), (4, "a"))
+-        self._make_matmul_test_allow_unknown(version, (4, None), (None, "a"), (4, "a"))
+-        self._make_matmul_test_allow_unknown(
+-            version, (1, 4, 2), ("a", 2, 5), ("a", 4, 5)
+-        )
+-        self._make_matmul_test_allow_unknown(
+-            version, (1, 3, 4, 2), ("a", 2, 5), (1, 3, 4, 5)
+-        )
+-        self._make_matmul_test_allow_unknown(version, (3,), None, None)
+-        self._make_matmul_test_allow_unknown(version, None, None, None)
+-
+-    @parameterized.expand(all_versions_for("Cast"))
+-    def test_cast(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Cast", ["x"], ["y"], to=TensorProto.UINT8)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (2, 4, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Cast"))
+-    @unittest.skip(
+-        "Issue #5960"
+-    )  # FIXME(#5960) propagateElemTypeFromAttributeToOutput does not validate against output type constraints
+-    def test_cast_to_complex(self, _, version) -> None:  # noqa: ARG002
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Cast", ["x"], ["y"], to=TensorProto.COMPLEX128)],
+-            [],
+-        )
+-
+-        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
+-
+-    @parameterized.expand(all_versions_for("CastLike"))
+-    def test_cast_like(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3)), ("t", TensorProto.FLOAT16, ("N",))],
+-            [make_node("CastLike", ["x", "t"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT16, (2, 4, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("BitCast"))
+-    def test_bitcast_same_size(self, _, version) -> None:
+-        # Test bitcast between types of same size (float32 -> int32)
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("BitCast", ["x"], ["y"], to=TensorProto.INT32)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("BitCast"))
+-    def test_bitcast_scalar(self, _, version) -> None:
+-        # Test bitcast with scalar input (same size)
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, ())],
+-            [make_node("BitCast", ["x"], ["y"], to=TensorProto.INT32)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, ())],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("BitCast"))
+-    def test_bitcast_1d(self, _, version) -> None:
+-        # Test bitcast with 1D tensor (float32 -> uint32, same size)
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (8,))],
+-            [make_node("BitCast", ["x"], ["y"], to=TensorProto.UINT32)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT32, (8,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("BitCast"))
+-    def test_bitcast_double_to_int64(self, _, version) -> None:
+-        # Test bitcast between 64-bit types (double -> int64)
+-        graph = self._make_graph(
+-            [("x", TensorProto.DOUBLE, (3, 5))],
+-            [make_node("BitCast", ["x"], ["y"], to=TensorProto.INT64)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (3, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("BitCast"))
+-    def test_bitcast_int8_to_uint8(self, _, version) -> None:
+-        # Test bitcast between 8-bit types (int8 -> uint8)
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT8, (4, 6))],
+-            [make_node("BitCast", ["x"], ["y"], to=TensorProto.UINT8)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (4, 6))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("BitCast"))
+-    def test_bitcast_float16_to_int16(self, _, version) -> None:
+-        # Test bitcast between 16-bit types (float16 -> int16)
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT16, (2, 3))],
+-            [make_node("BitCast", ["x"], ["y"], to=TensorProto.INT16)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT16, (2, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Col2Im"))
+-    def test_col2im(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("input", TensorProto.FLOAT, (1, 5, 5)),
+-                ("output_shape", TensorProto.INT64, (2,)),
+-                ("kernel_shape", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Col2Im", ["input", "output_shape", "kernel_shape"], ["output"]
+-                )
+-            ],
+-            [],
+-            initializer=[
+-                make_tensor("output_shape", TensorProto.INT64, (2,), (5, 5)),
+-                make_tensor("kernel_shape", TensorProto.INT64, (2,), (1, 5)),
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 5, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Col2Im"))
+-    def test_col2im_strides(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("input", TensorProto.FLOAT, (1, 9, 4)),
+-                ("output_shape", TensorProto.INT64, (2,)),
+-                ("kernel_shape", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Col2Im",
+-                    ["input", "output_shape", "kernel_shape"],
+-                    ["output"],
+-                    strides=[2, 2],
+-                )
+-            ],
+-            [],
+-            initializer=[
+-                make_tensor("output_shape", TensorProto.INT64, (2,), (5, 5)),
+-                make_tensor("kernel_shape", TensorProto.INT64, (2,), (3, 3)),
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 5, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Col2Im"))
+-    def test_col2im_pads(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("input", TensorProto.FLOAT, (1, 5, 15)),
+-                ("output_shape", TensorProto.INT64, (2,)),
+-                ("kernel_shape", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Col2Im",
+-                    ["input", "output_shape", "kernel_shape"],
+-                    ["output"],
+-                    pads=[0, 1, 0, 1],
+-                )
+-            ],
+-            [],
+-            initializer=[
+-                make_tensor("output_shape", TensorProto.INT64, (2,), (5, 5)),
+-                make_tensor("kernel_shape", TensorProto.INT64, (2,), (1, 5)),
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 5, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Col2Im"))
+-    def test_col2im_dilations(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("input", TensorProto.FLOAT, (1, 4, 5)),
+-                ("output_shape", TensorProto.INT64, (2,)),
+-                ("kernel_shape", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Col2Im",
+-                    ["input", "output_shape", "kernel_shape"],
+-                    ["output"],
+-                    dilations=[1, 5],
+-                )
+-            ],
+-            [],
+-            initializer=[
+-                make_tensor("output_shape", TensorProto.INT64, (2,), (6, 6)),
+-                make_tensor("kernel_shape", TensorProto.INT64, (2,), (2, 2)),
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 6, 6))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Col2Im"))
+-    def test_col2im_5d(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("input", TensorProto.FLOAT, (1, 10, 12)),
+-                ("output_shape", TensorProto.INT64, (3,)),
+-                ("kernel_shape", TensorProto.INT64, (3,)),
+-            ],
+-            [
+-                make_node(
+-                    "Col2Im", ["input", "output_shape", "kernel_shape"], ["output"]
+-                )
+-            ],
+-            [],
+-            initializer=[
+-                make_tensor("output_shape", TensorProto.INT64, (3,), (3, 4, 5)),
+-                make_tensor("kernel_shape", TensorProto.INT64, (3,), (1, 1, 5)),
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 2, 3, 4, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Concat"))
+-    def test_concat(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3)), ("y", TensorProto.FLOAT, (7, 4, 3))],
+-            [make_node("Concat", ["x", "y"], ["z"], axis=0)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("z", TensorProto.FLOAT, (9, 4, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Concat"))
+-    def test_concat_missing_shape(self, *_) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.FLOAT, (2, 4, 3)),
+-                "y",
+-                ("z", TensorProto.FLOAT, (None, None, None)),
+-            ],
+-            [make_node("Concat", ["x", "y", "z"], ["out"], axis=0)],
+-            [],
+-        )
+-        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
+-
+-    @parameterized.expand(all_versions_for("Concat"))
+-    def test_concat_3d_axis_2(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 2, 2)), ("y", TensorProto.FLOAT, (2, 2, 2))],
+-            [make_node("Concat", ["x", "y"], ["z"], axis=2)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("z", TensorProto.FLOAT, (2, 2, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Concat"))
+-    def test_concat_param(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, ("a", 2)), ("y", TensorProto.FLOAT, ("a", 3))],
+-            [make_node("Concat", ["x", "y"], ["z"], axis=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("z", TensorProto.FLOAT, ("a", 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Concat"))
+-    def test_concat_param_single_input(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, ("a", 2))],
+-            [make_node("Concat", ["x"], ["z"], axis=0)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("z", TensorProto.FLOAT, ("a", 2))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_dynamic_shape_known_rank(self, _, version) -> None:
+-        self.skipIf(version < 14, "Rank inference is added from Version 14")
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, (2,))],
+-            [make_node("Reshape", ["x", "shape"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (None, None))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_dynamic_shape_symbolic(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, ("M",))],
+-            [make_node("Reshape", ["x", "shape"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, None)],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_dynamic_unknown_shape(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, None)],
+-            [make_node("Reshape", ["x", "shape"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, None)],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_static_shape(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, (2,))],
+-            [make_node("Reshape", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[make_tensor("shape", TensorProto.INT64, (2,), (3, 8))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (3, 8))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_static_shape_inferred(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, (3,))],
+-            [make_node("Reshape", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (0, 3, -1))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (2, 3, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_static_shape_zero(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (1, 1, 1)), ("shape", TensorProto.INT64, (3,))],
+-            [make_node("Reshape", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (0, 1, 1))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (1, 1, 1))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_static_shape_allowzero(self, _, version) -> None:
+-        self.skipIf(version < 14, "allowzero is added from Version 14")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.UINT8, (1, 0, 0)),
+-                ("shape", TensorProto.INT64, (3,)),
+-            ],
+-            [make_node("Reshape", ["x", "shape"], ["y"], allowzero=1)],
+-            [],
+-            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (0, 1, 1))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.UINT8, (0, 1, 1))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Reshape"))
+-    def test_reshape_static_shape_constant(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.UINT8, (2, 4, 3))],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["shape"],
+-                    value=make_tensor("shape", TensorProto.INT64, (2,), (3, 8)),
+-                ),
+-                make_node("Reshape", ["x", "shape"], ["y"]),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("shape", TensorProto.INT64, (2,)),
+-                make_tensor_value_info("y", TensorProto.UINT8, (3, 8)),
+-            ],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Upsample"))
+-    def test_upsample(self, _, version) -> None:
+-        if version == 7:
+-            graph = self._make_graph(
+-                [("x", TensorProto.INT32, (2, 4, 3, 5))],
+-                [make_node("Upsample", ["x"], ["y"], scales=[1.0, 1.1, 1.3, 1.9])],
+-                [],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-        else:
+-            graph = self._make_graph(
+-                [
+-                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                    ("scales", TensorProto.FLOAT, (4,)),
+-                ],
+-                [make_node("Upsample", ["x", "scales"], ["y"])],
+-                [],
+-                initializer=[
+-                    make_tensor("scales", TensorProto.FLOAT, (4,), (1.0, 1.1, 1.3, 1.9))
+-                ],
+-            )
+-
+-            def call_inference():
+-                self._assert_inferred(
+-                    graph,
+-                    [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-                    opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-                )
+-
+-            if version == 9:
+-                call_inference()
+-            else:
+-                # Upsample is deprecated since Version 10.
+-                with self.assertRaises(onnx.checker.ValidationError) as cm:
+-                    call_inference()
+-                exception = cm.exception
+-                assert "Upsample is deprecated" in str(exception)
+-
+-    @parameterized.expand(all_versions_for("Upsample"))
+-    def test_upsample_raw_data(self, _, version) -> None:
+-        if version == 7:
+-            graph = self._make_graph(
+-                [("x", TensorProto.INT32, (1, 3, 4, 5))],
+-                [make_node("Upsample", ["x"], ["y"], scales=[2.0, 1.1, 2.3, 1.9])],
+-                [],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 9, 9))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-        else:
+-            graph = self._make_graph(
+-                [
+-                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                    ("scales", TensorProto.FLOAT, (4,)),
+-                ],
+-                [make_node("Upsample", ["x", "scales"], ["y"])],
+-                [],
+-                initializer=[
+-                    make_tensor(
+-                        "scales",
+-                        TensorProto.FLOAT,
+-                        (4,),
+-                        vals=np.array([1.0, 1.1, 1.3, 1.9], dtype="<f4").tobytes(),
+-                        raw=True,
+-                    )
+-                ],
+-            )  # Feed raw bytes (force little endian ordering like onnx standard) for test purpose
+-
+-            def call_inference():
+-                self._assert_inferred(
+-                    graph,
+-                    [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-                    opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-                )
+-
+-            if version == 9:
+-                call_inference()
+-            else:
+-                # Upsample is deprecated since Version 10.
+-                with self.assertRaises(onnx.checker.ValidationError) as cm:
+-                    call_inference()
+-                exception = cm.exception
+-                assert "Upsample is deprecated" in str(exception)
+-
+-    @parameterized.expand(all_versions_for("Expand"))
+-    def test_expand(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT32, (3, 1)), ("shape", TensorProto.INT64, (3,))],
+-            [make_node("Expand", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (2, 1, 6))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 6))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Expand"))
+-    def test_expand_scalar_input(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT32, ()), ("shape", TensorProto.INT64, (2,))],
+-            [make_node("Expand", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[make_tensor("shape", TensorProto.INT64, (2,), (4, 8))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (4, 8))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Expand"))
+-    def test_expand_raw_data(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT32, (3, 1)), ("shape", TensorProto.INT64, (2,))],
+-            [make_node("Expand", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[
+-                make_tensor(
+-                    "shape",
+-                    TensorProto.INT64,
+-                    (2,),
+-                    vals=np.array([3, 4], dtype="<i8").tobytes(),
+-                    raw=True,
+-                )
+-            ],
+-        )  # Feed raw bytes (force little endian ordering like onnx standard) for test purpose
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (3, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Expand"))
+-    def test_expand_dynamic_shape(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (1, 2, None)),
+-                ("shape", TensorProto.INT64, (3,)),
+-            ],
+-            [make_node("Expand", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (None, 2, None))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Expand"))
+-    def test_expand_symbolic_shape(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (1, 2, None)),
+-                ("shape", TensorProto.INT64, ("unk__0",)),
+-            ],
+-            [make_node("Expand", ["x", "shape"], ["y"])],
+-            [],
+-            initializer=[],
+-        )
+-        # if giving a symbolic shape, Expand should not infer any shape or rank inference
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, None)],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size(self, _, version) -> None:
+-        if version == 10:
+-            graph = self._make_graph(
+-                [
+-                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                    ("scales", TensorProto.FLOAT, (4,)),
+-                ],
+-                [make_node("Resize", ["x", "scales"], ["y"])],
+-                [],
+-                initializer=[
+-                    make_tensor("scales", TensorProto.FLOAT, (4,), (1.0, 1.1, 1.3, 1.9))
+-                ],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-        elif version == 11:
+-            graph = self._make_graph(
+-                [
+-                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                    ("roi", TensorProto.FLOAT, (8,)),
+-                    ("scales", TensorProto.FLOAT, (4,)),
+-                    ("sizes", TensorProto.INT64, (4,)),
+-                ],
+-                [make_node("Resize", ["x", "roi", "scales", "sizes"], ["y"])],
+-                [],
+-                initializer=[
+-                    make_tensor("sizes", TensorProto.INT64, (4,), (3, 5, 6, 7))
+-                ],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.INT32, (3, 5, 6, 7))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-        else:
+-            graph = self._make_graph(
+-                [
+-                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                    ("roi", TensorProto.FLOAT, (8,)),
+-                    ("sizes", TensorProto.INT64, (4,)),
+-                ],
+-                [make_node("Resize", ["x", "roi", "", "sizes"], ["y"])],
+-                [],
+-                initializer=[
+-                    make_tensor("sizes", TensorProto.INT64, (4,), (3, 5, 6, 7))
+-                ],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.INT32, (3, 5, 6, 7))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-
+-    @parameterized.expand(all_versions_for("RMSNormalization"))
+-    def test_rms_normalization(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("X", TensorProto.FLOAT, ("N", "C", "H", "W")),
+-                ("scale", TensorProto.FLOAT, ("H", "W")),
+-            ],
+-            [make_node("RMSNormalization", ["X", "scale"], ["y"], axis=2)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, ("N", "C", "H", "W"))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size_axes_2_3(self, _, version) -> None:
+-        self.skipIf(version < 18, "axes is from Version 18")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (2,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "", "sizes"], ["y"], axes=(2, 3))],
+-            [],
+-            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 7))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 6, 7))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size_axes_3_2(self, _, version) -> None:
+-        self.skipIf(version < 18, "axes is from Version 18")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (2,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "", "sizes"], ["y"], axes=(3, 2))],
+-            [],
+-            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 7))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 7, 6))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size_not_larger(self, _, version) -> None:
+-        self.skipIf(
+-            version < 18,
+-            "keep_aspect_ratio_policy is from Version 18",
+-        )
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (3, 5)),
+-                ("roi", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Resize",
+-                    ["x", "roi", "", "sizes"],
+-                    ["y"],
+-                    keep_aspect_ratio_policy="not_larger",
+-                )
+-            ],
+-            [],
+-            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (4, 6))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size_axes_2_3_not_larger(self, _, version) -> None:
+-        self.skipIf(
+-            version < 18,
+-            "axes & keep_aspect_ratio_policy are from Version 18",
+-        )
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Resize",
+-                    ["x", "roi", "", "sizes"],
+-                    ["y"],
+-                    axes=(2, 3),
+-                    keep_aspect_ratio_policy="not_larger",
+-                )
+-            ],
+-            [],
+-            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 4, 6))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size_not_smaller(self, _, version) -> None:
+-        self.skipIf(
+-            version < 18,
+-            "keep_aspect_ratio_policy is from Version 18",
+-        )
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (3, 5)),
+-                ("roi", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Resize",
+-                    ["x", "roi", "", "sizes"],
+-                    ["y"],
+-                    keep_aspect_ratio_policy="not_smaller",
+-                )
+-            ],
+-            [],
+-            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (6, 10))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_size_axes_2_3_not_smaller(self, _, version) -> None:
+-        self.skipIf(
+-            version < 18,
+-            "axes & keep_aspect_ratio_policy are from Version 18",
+-        )
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (2,)),
+-            ],
+-            [
+-                make_node(
+-                    "Resize",
+-                    ["x", "roi", "", "sizes"],
+-                    ["y"],
+-                    axes=(2, 3),
+-                    keep_aspect_ratio_policy="not_smaller",
+-                )
+-            ],
+-            [],
+-            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 6, 10))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_scale(self, _, version) -> None:
+-        self.skipIf(version < 11, "roi input is from Version 11")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (8,)),
+-                ("scales", TensorProto.FLOAT, (4,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "scales"], ["y"])],
+-            [],
+-            initializer=[
+-                make_tensor("scales", TensorProto.FLOAT, (4,), (1.0, 1.1, 1.3, 1.9))
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_scale_axes_2_3(self, _, version) -> None:
+-        self.skipIf(version < 18, "axes is from Version 18")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (8,)),
+-                ("scales", TensorProto.FLOAT, (2,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "scales"], ["y"], axes=(2, 3))],
+-            [],
+-            initializer=[make_tensor("scales", TensorProto.FLOAT, (2,), (1.3, 1.9))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_scale_axes_3_2(self, _, version) -> None:
+-        self.skipIf(version < 18, "axes is from Version 18")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (2, 4, 3, 5)),
+-                ("roi", TensorProto.FLOAT, (8,)),
+-                ("scales", TensorProto.FLOAT, (2,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "scales"], ["y"], axes=(3, 2))],
+-            [],
+-            initializer=[make_tensor("scales", TensorProto.FLOAT, (2,), (1.9, 1.3))],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_scale_raw_data(self, _, version) -> None:
+-        self.skipIf(version < 11, "roi input is from Version 11")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (1, 3, 4, 5)),
+-                ("roi", TensorProto.FLOAT, (8,)),
+-                ("scales", TensorProto.FLOAT, (4,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "scales"], ["y"])],
+-            [],
+-            initializer=[
+-                make_tensor(
+-                    "scales",
+-                    TensorProto.FLOAT,
+-                    (4,),
+-                    vals=np.array([2.0, 1.1, 2.3, 1.9], dtype="<f4").tobytes(),
+-                    raw=True,
+-                )
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 9, 9))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_scale_and_size_but_one_is_empty(self, _, version) -> None:
+-        self.skipIf(version < 11, "roi input is from Version 11")
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (1, 3, 4, 5)),
+-                ("roi", TensorProto.FLOAT, (8,)),
+-                ("scales", TensorProto.FLOAT, (4,)),
+-                ("sizes", TensorProto.INT64, (0,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "scales", "sizes"], ["y"])],
+-            [],
+-            initializer=[
+-                make_tensor(
+-                    "scales",
+-                    TensorProto.FLOAT,
+-                    (4,),
+-                    vals=np.array([2.0, 1.1, 2.3, 1.9], dtype="<f4").tobytes(),
+-                    raw=True,
+-                ),
+-                make_tensor(
+-                    "sizes",
+-                    TensorProto.INT64,
+-                    (0,),
+-                    vals=np.array([], dtype="<i8").tobytes(),
+-                    raw=True,
+-                ),
+-            ],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 9, 9))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Resize"))
+-    def test_resize_opset11_scales_is_empty(self, _, version) -> None:
+-        self.skipIf(version != 11, "This test only works for Version 11")
+-        # "scales" input in Resize in opset11 is not optional. It must be an empty tensor
+-        # if sizes is needed. Shape inference for Resize shall handle this case.
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.INT32, (1, 3, 4, 5)),
+-                ("roi", TensorProto.FLOAT, (8,)),
+-                ("scales", TensorProto.FLOAT, (0,)),
+-                ("sizes", TensorProto.INT64, (4,)),
+-            ],
+-            [make_node("Resize", ["x", "roi", "scales", "sizes"], ["y"])],
+-            [],
+-            initializer=[
+-                make_tensor(
+-                    "sizes",
+-                    TensorProto.INT64,
+-                    (4,),
+-                    vals=np.array(
+-                        [2, 6, 8, 10], dtype="<i8"
+-                    ).tobytes(),  # double in all dimensions
+-                    raw=True,
+-                ),
+-            ],
+-        )
+-
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT32, (2, 6, 8, 10))],
+-            opset_imports=[helper.make_opsetid("", version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Shape"))
+-    def test_shape(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Shape", ["x"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (3,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Shape"))
+-    def test_shape_start_1(self, _, version) -> None:
+-        self.skipIf(version < 15, "start and end are from Version 15")
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Shape", ["x"], ["y"], start=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (2,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Shape"))
+-    def test_shape_end_1(self, _, version) -> None:
+-        self.skipIf(version < 15, "start and end are from Version 15")
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Shape", ["x"], ["y"], end=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (1,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Shape"))
+-    def test_shape_negative_start(self, _, version) -> None:
+-        self.skipIf(version < 15, "start and end are from Version 15")
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Shape", ["x"], ["y"], start=-1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (1,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Shape"))
+-    def test_shape_clip1(self, _, version) -> None:
+-        self.skipIf(version < 15, "start and end are from Version 15")
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Shape", ["x"], ["y"], start=-5)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (3,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Shape"))
+-    def test_shape_clip2(self, _, version) -> None:
+-        self.skipIf(version < 15, "start and end are from Version 15")
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))],
+-            [make_node("Shape", ["x"], ["y"], end=10)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (3,))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Size"))
+-    def test_size(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 4, 3))], [make_node("Size", ["x"], ["y"])], []
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, ())],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Gather"))
+-    def test_gather(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (4, 3)), ("i", TensorProto.INT64, (2,))],
+-            [make_node("Gather", ["x", "i"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (2, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Gather"))
+-    def test_gather_axis1(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (4, 3, 5)), ("i", TensorProto.INT64, (1, 2))],
+-            [make_node("Gather", ["x", "i"], ["y"], axis=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (4, 1, 2, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Gather"))
+-    def test_gather_into_scalar(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (3,)), ("i", TensorProto.INT64, ())],
+-            [make_node("Gather", ["x", "i"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, ())],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("GatherElements"))
+-    def test_gather_elements(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2, 2)), ("i", TensorProto.INT64, (2, 2))],
+-            [make_node("GatherElements", ["x", "i"], ["y"], axis=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (2, 2))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("GatherElements"))
+-    def test_gather_elements_axis0(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (3, 3)), ("i", TensorProto.INT64, (2, 3))],
+-            [make_node("GatherElements", ["x", "i"], ["y"], axis=0)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (2, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Scatter"))
+-    def test_scatter(self, _, version) -> None:
+-        if version >= 11:
+-            # Scatter is deprecated in domain_version of 11.
+-            with self.assertRaises(onnx.checker.ValidationError) as cm:
+-                self._test_scatter(version)
+-            exception = cm.exception
+-            assert "Scatter is deprecated" in str(exception)
+-        else:
+-            self._test_scatter(version)
+-
+-    def _test_scatter(self, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.FLOAT, (3, 3)),
+-                ("i", TensorProto.INT64, (2, 3)),
+-                ("u", TensorProto.FLOAT, (2, 3)),
+-            ],
+-            [make_node("Scatter", ["x", "i", "u"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (3, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("Scatter"))
+-    def test_scatter_axis1(self, _, version) -> None:
+-        if version >= 11:
+-            # Scatter is deprecated in domain_version of 11.
+-            with self.assertRaises(onnx.checker.ValidationError) as cm:
+-                self._test_scatter_axis1(version)
+-            exception = cm.exception
+-            assert "Scatter is deprecated" in str(exception)
+-        else:
+-            self._test_scatter_axis1(version)
+-
+-    def _test_scatter_axis1(self, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.FLOAT, (1, 5)),
+-                ("i", TensorProto.INT64, (1, 2)),
+-                ("u", TensorProto.FLOAT, (1, 2)),
+-            ],
+-            [make_node("Scatter", ["x", "i", "u"], ["y"], axis=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 5))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("ScatterElements"))
+-    def test_scatter_elements(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.FLOAT, (3, 3)),
+-                ("i", TensorProto.INT64, (2, 3)),
+-                ("u", TensorProto.FLOAT, (2, 3)),
+-            ],
+-            [make_node("ScatterElements", ["x", "i", "u"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (3, 3))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("ScatterElements"))
+-    def test_scatter_elements_axis1(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.FLOAT, (1, 5)),
+-                ("i", TensorProto.INT64, (1, 2)),
+-                ("u", TensorProto.FLOAT, (1, 2)),
+-            ],
+-            [make_node("ScatterElements", ["x", "i", "u"], ["y"], axis=1)],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 5))],
++            [make_tensor_value_info("z", TensorProto.FLOAT, expected_out_shape)],
+             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+         )
+ 
+-    @parameterized.expand(all_versions_for("ScatterND"))
+-    def test_scatternd(self, _, version) -> None:
++    def _test_scatter(self, version) -> None:
+         graph = self._make_graph(
+             [
+-                ("x", TensorProto.FLOAT, (4, 5, 6)),
+-                ("indices", TensorProto.INT64, (3, 3, 2)),
+-                ("updates", TensorProto.FLOAT, (3, 3, 6)),
++                ("x", TensorProto.FLOAT, (3, 3)),
++                ("i", TensorProto.INT64, (2, 3)),
++                ("u", TensorProto.FLOAT, (2, 3)),
+             ],
+-            [make_node("ScatterND", ["x", "indices", "updates"], ["y"])],
++            [make_node("Scatter", ["x", "i", "u"], ["y"])],
+             [],
+         )
+         self._assert_inferred(
+             graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (4, 5, 6))],
++            [make_tensor_value_info("y", TensorProto.FLOAT, (3, 3))],
+             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+         )
+ 
+-    @parameterized.expand(all_versions_for("ScatterND"))
+-    def test_scatternd_noshape(self, _, version) -> None:
+-        # The shape of 'x_reshaped' cannot be inferred, since it is the output of a dynamic reshape.
+-        # Thus the shape of 'y' is also None.
++    def _test_scatter_axis1(self, version) -> None:
+         graph = self._make_graph(
+             [
+-                ("x", TensorProto.FLOAT, (4, 5, 6)),
+-                ("indices", TensorProto.INT64, (3, 3, 2)),
+-                ("updates", TensorProto.FLOAT, (3, 3, 6)),
+-                ("shape", TensorProto.INT64, ("M",)),
+-            ],
+-            [
+-                make_node("Reshape", ["x", "shape"], ["x_reshaped"]),
+-                make_node("ScatterND", ["x_reshaped", "indices", "updates"], ["y"]),
++                ("x", TensorProto.FLOAT, (1, 5)),
++                ("i", TensorProto.INT64, (1, 2)),
++                ("u", TensorProto.FLOAT, (1, 2)),
+             ],
++            [make_node("Scatter", ["x", "i", "u"], ["y"], axis=1)],
+             [],
+         )
+         self._assert_inferred(
+             graph,
+-            [
+-                make_tensor_value_info("x_reshaped", TensorProto.FLOAT, None),
+-                make_tensor_value_info("y", TensorProto.FLOAT, None),
+-            ],
++            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 5))],
+             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+         )
+ 
+@@ -1709,95 +334,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 24)],
+         )
+ 
+-    @parameterized.expand(all_versions_for("Squeeze"))
+-    def test_squeeze(self, _, version) -> None:
+-        if version == 11:
+-            graph = self._make_graph(
+-                [("x", TensorProto.FLOAT, (1, 3, 1, 1, 2, 1))],
+-                [make_node("Squeeze", "x", "y", axes=[0, 2, 3, 5])],
+-                [],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.FLOAT, (3, 2))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-        else:
+-            graph = self._make_graph(
+-                [
+-                    ("x", TensorProto.FLOAT, (1, 3, 1, 1, 2, 1)),
+-                    ("axes", TensorProto.INT64, (4,)),
+-                ],
+-                [make_node("Squeeze", ["x", "axes"], "y")],
+-                [],
+-                initializer=[
+-                    make_tensor("axes", TensorProto.INT64, (4,), (0, 2, 3, 5))
+-                ],
+-            )
+-            self._assert_inferred(
+-                graph,
+-                [make_tensor_value_info("y", TensorProto.FLOAT, (3, 2))],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-            )
+-
+-    @parameterized.expand(all_versions_for("StringConcat"))
+-    def test_stringconcat(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, (2, 3, 4)),
+-                ("y", TensorProto.STRING, (2, 3, 4)),
+-            ],
+-            [make_node("StringConcat", ["x", "y"], "z")],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("z", TensorProto.STRING, (2, 3, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("StringConcat"))
+-    def test_stringconcat_broadcasting(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, (2, 3, 4)),
+-                ("y", TensorProto.STRING, (1, 3, 1)),
+-            ],
+-            [make_node("StringConcat", ["x", "y"], "z")],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("z", TensorProto.STRING, (2, 3, 4))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("RegexFullMatch"))
+-    def test_regex_full_match(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.STRING, (2, 4, 3, 9))],
+-            [make_node("RegexFullMatch", ["x"], ["y"], pattern=r"^[A-Z][a-z]*$")],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.BOOL, (2, 4, 3, 9))],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("RegexFullMatch"))
+-    def test_regex_full_match_empty_shape(self, _, version) -> None:
+-        graph = self._make_graph(
+-            [("x", TensorProto.STRING, ())],
+-            [make_node("RegexFullMatch", ["x"], ["y"], pattern=r"^[A-Z][a-z]*$")],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.BOOL, ())],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+     def test_squeeze_no_axes_opset11(self) -> None:
+         graph = self._make_graph(
+             [
+@@ -5632,23 +4168,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+         self._make_matmulinteger_test((5, 1, 4, 2), (1, 3, 2, 3))
+         self._make_matmulinteger_test((4, 2), (3, 2, 3))
+ 
+-    @parameterized.expand(
+-        [onnx.TensorProto.FLOAT, onnx.TensorProto.FLOAT16, onnx.TensorProto.BFLOAT16]
+-    )
+-    def test_quantizelinear(self, elem_type) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", elem_type, (30, 4, 5)),
+-                ("y_scale", elem_type, ()),
+-                ("y_zero_point", TensorProto.UINT8, ()),
+-            ],
+-            [make_node("QuantizeLinear", ["x", "y_scale", "y_zero_point"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph, [make_tensor_value_info("y", TensorProto.UINT8, (30, 4, 5))]
+-        )
+-
+     def test_quantizelinear_default_zp(self) -> None:
+         graph = self._make_graph(
+             [("x", TensorProto.FLOAT, (30, 4, 5)), ("y_scale", TensorProto.FLOAT, ())],
+@@ -5754,23 +4273,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             graph,
+         )
+ 
+-    @parameterized.expand(
+-        [onnx.TensorProto.FLOAT, onnx.TensorProto.FLOAT16, onnx.TensorProto.BFLOAT16]
+-    )
+-    def test_dequantizelinear(self, elem_type) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.UINT8, (30, 4, 5)),
+-                ("x_scale", elem_type, ()),
+-                ("x_zero_point", TensorProto.UINT8, ()),
+-            ],
+-            [make_node("DequantizeLinear", ["x", "x_scale", "x_zero_point"], ["y"])],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph, [make_tensor_value_info("y", elem_type, (30, 4, 5))]
+-        )
+-
+     def test_dynamicquantizelinear(self) -> None:
+         graph = self._make_graph(
+             [("x", TensorProto.FLOAT, (30, 4, 5))],
+@@ -6005,319 +4507,61 @@ class TestShapeInference(TestShapeInferenceHelper):
+             [make_node("RoiAlign", ["x", "rois", "batch_indices"], ["y"])],
+             [],
+         )
+-        self._assert_inferred(
+-            graph, [make_tensor_value_info("y", TensorProto.FLOAT, (15, "C", 1, 1))]
+-        )
+-
+-    def test_rotaryembedding_4d(self) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("X", TensorProto.FLOAT, ("B", "num_heads", "seq_len", "head_size")),
+-                ("cos_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
+-                ("sin_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
+-                ("position_ids", TensorProto.INT64, ("B", "seq_len")),
+-            ],
+-            [
+-                make_node(
+-                    "RotaryEmbedding",
+-                    ["X", "cos_cache", "sin_cache", "position_ids"],
+-                    ["Y"],
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info(
+-                    "Y", TensorProto.FLOAT, ("B", "num_heads", "seq_len", "head_size")
+-                )
+-            ],
+-        )
+-
+-    def test_rotaryembedding_3d(self) -> None:
+-        graph = self._make_graph(
+-            [
+-                ("X", TensorProto.FLOAT, ("B", "seq_len", "hidden_size")),
+-                ("cos_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
+-                ("sin_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
+-                ("position_ids", TensorProto.INT64, ("B", "seq_len")),
+-            ],
+-            [
+-                make_node(
+-                    "RotaryEmbedding",
+-                    ["X", "cos_cache", "sin_cache", "position_ids"],
+-                    ["Y"],
+-                    num_heads=4,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info(
+-                    "Y", TensorProto.FLOAT, ("B", "seq_len", "hidden_size")
+-                )
+-            ],
+-        )
+-
+-    @parameterized.expand(
+-        all_versions_for("LabelEncoder") if ONNX_ML else [], skip_on_empty=True
+-    )
+-    def test_label_encoder_string_int64(self, _, version) -> None:
+-        self.skipIf(
+-            version < 2, "keys_* attributes were introduced in ai.onnx.ml opset 2"
+-        )
+-        string_list = ["A", "m", "y"]
+-        float_list = [94.17, 36.00, -99.0]
+-        int64_list = [12, 28, 86]
+-        graph = self._make_graph(
+-            [("x", TensorProto.STRING, (6, 1))],
+-            [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_strings=string_list,
+-                    values_int64s=int64_list,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (6, 1))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT64, (2, 3))],
+-            [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_int64s=int64_list,
+-                    values_strings=string_list,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.STRING, (2, 3))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, (2,))],
+-            [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_floats=float_list,
+-                    values_int64s=int64_list,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, (2,))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT64, (8,))],
+-            [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_int64s=int64_list,
+-                    values_floats=float_list,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (8,))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", TensorProto.FLOAT, ())],
+-            [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_floats=float_list,
+-                    values_strings=string_list,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.STRING, ())],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", TensorProto.STRING, (1, 2))],
+-            [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_strings=string_list,
+-                    values_floats=float_list,
+-                )
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 2))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-    @parameterized.expand(
+-        all_versions_for("LabelEncoder") if ONNX_ML else [], skip_on_empty=True
+-    )
+-    def test_label_encoder_tensor_attributes(self, _, version) -> None:
+-        self.skipIf(
+-            version < 4, "tensor attributes were introduced in ai.onnx.ml opset 4"
+-        )
+-        key_tensor = make_tensor(
+-            "keys_tensor", TensorProto.STRING, [4], ["a", "b", "cc", "ddd"]
+-        )
+-        values_tensor = make_tensor(
+-            "values_tensor", TensorProto.INT64, [4], [1, 2, 3, 4]
++        self._assert_inferred(
++            graph, [make_tensor_value_info("y", TensorProto.FLOAT, (15, "C", 1, 1))]
+         )
++
++    def test_rotaryembedding_4d(self) -> None:
+         graph = self._make_graph(
+-            [("x", TensorProto.STRING, ("M", None, 3, 12))],
++            [
++                ("X", TensorProto.FLOAT, ("B", "num_heads", "seq_len", "head_size")),
++                ("cos_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
++                ("sin_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
++                ("position_ids", TensorProto.INT64, ("B", "seq_len")),
++            ],
+             [
+                 make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_tensor=key_tensor,
+-                    values_tensor=values_tensor,
+-                    default_tensor=make_tensor(
+-                        "default_tensor", TensorProto.INT64, [1], [0]
+-                    ),
++                    "RotaryEmbedding",
++                    ["X", "cos_cache", "sin_cache", "position_ids"],
++                    ["Y"],
+                 )
+             ],
+             [],
+         )
+         self._assert_inferred(
+             graph,
+-            [make_tensor_value_info("y", TensorProto.INT64, ("M", None, 3, 12))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, version),
+-                make_opsetid(ONNX_DOMAIN, 11),
++            [
++                make_tensor_value_info(
++                    "Y", TensorProto.FLOAT, ("B", "num_heads", "seq_len", "head_size")
++                )
+             ],
+         )
+ 
+-    @parameterized.expand(
+-        all_versions_for("LabelEncoder") if ONNX_ML else [], skip_on_empty=True
+-    )
+-    def test_label_encoder_tensor_attributes_invalid_configurations(
+-        self, _, version
+-    ) -> None:
+-        self.skipIf(version < 4, "tensor attributes introduced in ai.onnx.ml opset 4")
+-        key_tensor = make_tensor(
+-            "keys_tensor", TensorProto.STRING, [4], ["a", "b", "cc", "ddd"]
+-        )
+-        values_tensor = make_tensor(
+-            "values_tensor", TensorProto.INT64, [4], [1, 2, 3, 4]
+-        )
+-
+-        opset_imports = [
+-            make_opsetid(ONNX_ML_DOMAIN, version),
+-            make_opsetid(ONNX_DOMAIN, 11),
+-        ]
+-
+-        # default_tensor should be INT64, same type as values_tensor
++    def test_rotaryembedding_3d(self) -> None:
+         graph = self._make_graph(
+-            [("x", TensorProto.STRING, ("M", None, 3, 12))],
++            [
++                ("X", TensorProto.FLOAT, ("B", "seq_len", "hidden_size")),
++                ("cos_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
++                ("sin_cache", TensorProto.FLOAT, ("max_seq_len", "head_size_div_2")),
++                ("position_ids", TensorProto.INT64, ("B", "seq_len")),
++            ],
+             [
+                 make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_tensor=key_tensor,
+-                    values_tensor=values_tensor,
+-                    default_tensor=make_tensor(
+-                        "default_tensor", TensorProto.INT32, [1], [0]
+-                    ),
++                    "RotaryEmbedding",
++                    ["X", "cos_cache", "sin_cache", "position_ids"],
++                    ["Y"],
++                    num_heads=4,
+                 )
+             ],
+             [],
+         )
+-
+-        self.assertRaises(
+-            onnx.shape_inference.InferenceError,
+-            self._inferred,
++        self._assert_inferred(
+             graph,
+-            opset_imports=opset_imports,
+-        )
+-
+-        # default_tensor should be a singleton of shape (1,)
+-        graph = self._make_graph(
+-            [("x", TensorProto.STRING, ("M", None, 3, 12))],
+             [
+-                make_node(
+-                    "LabelEncoder",
+-                    ["x"],
+-                    ["y"],
+-                    domain=ONNX_ML_DOMAIN,
+-                    keys_tensor=key_tensor,
+-                    values_strings=["a", "b", "cc", "ddd"],
+-                    default_tensor=make_tensor(
+-                        "default_tensor", TensorProto.STRING, [1, 2], ["a", "b"]
+-                    ),
++                make_tensor_value_info(
++                    "Y", TensorProto.FLOAT, ("B", "seq_len", "hidden_size")
+                 )
+             ],
+-            [],
+-        )
+-
+-        self.assertRaises(
+-            onnx.shape_inference.InferenceError,
+-            self._inferred,
+-            graph,
+-            opset_imports=opset_imports,
+         )
+ 
+     def make_sparse(
+@@ -8746,105 +6990,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+         )
+         self._assert_inferred(graph, [output_tensor_val_info])
+ 
+-    @parameterized.expand(all_versions_for("StringSplit"))
+-    def test_string_split_basic(self, _, version) -> None:
+-        substrings = make_tensor_value_info(
+-            "substrings",
+-            TensorProto.STRING,
+-            (2, None),
+-        )
+-        length = make_tensor_value_info("length", TensorProto.INT64, (2,))
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, (2,)),
+-            ],
+-            [make_node("StringSplit", ["x"], ["substrings", "length"])],
+-            [substrings, length],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [substrings, length],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("StringSplit"))
+-    def test_string_split_symbolic(self, _, version) -> None:
+-        substrings = make_tensor_value_info(
+-            "substrings",
+-            TensorProto.STRING,
+-            ("A", None),
+-        )
+-        length = make_tensor_value_info("length", TensorProto.INT64, ("A",))
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, ("A",)),
+-            ],
+-            [make_node("StringSplit", ["x"], ["substrings", "length"])],
+-            [substrings, length],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [substrings, length],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("StringSplit"))
+-    def test_string_split_nested(self, _, version) -> None:
+-        substrings = make_tensor_value_info(
+-            "substrings", TensorProto.STRING, (2, 4, 3, None)
+-        )
+-        length = make_tensor_value_info("length", TensorProto.INT64, (2, 4, 3))
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, (2, 4, 3)),
+-            ],
+-            [make_node("StringSplit", ["x"], ["substrings", "length"], maxsplit=2)],
+-            [substrings, length],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [substrings, length],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("StringSplit"))
+-    def test_string_split_zero_dimensional_input(self, _, version) -> None:
+-        substrings = make_tensor_value_info("substrings", TensorProto.STRING, (None,))
+-        length = make_tensor_value_info("length", TensorProto.INT64, ())
+-
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, ()),
+-            ],
+-            [make_node("StringSplit", ["x"], ["substrings", "length"], maxsplit=2)],
+-            [substrings, length],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [substrings, length],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(all_versions_for("StringSplit"))
+-    def test_string_split_empty_input(self, _, version) -> None:
+-        substrings = make_tensor_value_info(
+-            "substrings", TensorProto.STRING, ("M", 3, 0, None)
+-        )
+-        length = make_tensor_value_info("length", TensorProto.INT64, ("M", 3, 0))
+-
+-        graph = self._make_graph(
+-            [
+-                ("x", TensorProto.STRING, ("M", 3, 0)),
+-            ],
+-            [make_node("StringSplit", ["x"], ["substrings", "length"], maxsplit=2)],
+-            [substrings, length],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [substrings, length],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+     def test_optional_tensor_get_element(self) -> None:
+         tensor_type_proto = helper.make_tensor_type_proto(
+             elem_type=TensorProto.DOUBLE, shape=[2, 1, 4]
+@@ -9452,426 +7597,76 @@ class TestShapeInference(TestShapeInferenceHelper):
+             [],
+         )
+         self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("shape", TensorProto.INT64, ()),
+-                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["shape"],
+-                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
+-                ),
+-                make_node("HannWindow", ["shape"], ["y"], periodic=0),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("shape", TensorProto.INT64, ()),
+-                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
+-            ],
+-        )
+-
+-    def test_blackmanwindow(self):
+-        graph = self._make_graph(
+-            [],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["shape"],
+-                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
+-                ),
+-                make_node("BlackmanWindow", ["shape"], ["y"]),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("shape", TensorProto.INT64, ()),
+-                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
+-            ],
+-        )
+-
+-        graph = self._make_graph(
+-            [],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["shape"],
+-                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
+-                ),
+-                make_node("BlackmanWindow", ["shape"], ["y"], periodic=0),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("shape", TensorProto.INT64, ()),
+-                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
+-            ],
+-        )
+-
+-    @parameterized.expand(
+-        [
+-            (
+-                name,
+-                version,
+-                test_aspect,
+-                input_shape,
+-                axis,
+-                onesided,
+-                inverse,
+-                expected_shape,
+-            )
+-            for (name, version), (
+-                test_aspect,
+-                input_shape,
+-                axis,
+-                onesided,
+-                inverse,
+-                expected_shape,
+-            ) in itertools.product(
+-                all_versions_for("DFT"),
+-                (
+-                    ("reals_default_axis", (2, 5, 1), None, None, None, (2, 5, 2)),
+-                    ("reals_axis_0", (3, 5, 10, 1), 0, 0, 0, (3, 5, 10, 2)),
+-                    ("reals_axis_1", (3, 5, 10, 1), 1, 0, 0, (3, 5, 10, 2)),
+-                    ("reals_axis_2", (3, 5, 10, 1), 2, 0, 0, (3, 5, 10, 2)),
+-                    ("reals_axis_neg", (3, 5, 10, 1), -2, 0, 0, (3, 5, 10, 2)),
+-                    ("reals_axis_0_onesided", (3, 5, 10, 1), 0, 1, 0, (2, 5, 10, 2)),
+-                    ("reals_axis_1_onesided", (3, 5, 10, 1), 1, 1, 0, (3, 3, 10, 2)),
+-                    ("reals_axis_2_onesided", (3, 5, 10, 1), 2, 1, 0, (3, 5, 6, 2)),
+-                    ("reals_axis_neg_onesided", (3, 5, 10, 1), -2, 1, 0, (3, 5, 6, 2)),
+-                    ("complex_default_axis", (2, 5, 2), None, None, None, (2, 5, 2)),
+-                    ("real_inverse", (2, 5, 1), 1, None, 1, (2, 5, 2)),
+-                    ("complex_inverse", (2, 5, 2), 1, None, 1, (2, 5, 2)),
+-                    ("irfft_axis_0", (2, 5, 10, 2), 0, 1, 1, (2, 5, 10, 1)),
+-                    ("irfft_axis_1", (3, 3, 10, 2), 1, 1, 1, (3, 4, 10, 1)),
+-                    ("irfft_axis_2", (3, 5, 6, 2), 2, 1, 1, (3, 5, 10, 1)),
+-                    ("irfft_axis_neg", (3, 5, 6, 2), -2, 1, 1, (3, 5, 10, 1)),
+-                ),
+-            )
+-        ]
+-    )
+-    def test_dft(
+-        self,
+-        _: str,
+-        version: int,
+-        _test_aspect: str,
+-        input_shape: tuple[int],
+-        axis: int | None,
+-        onesided: int | None,
+-        inverse: int | None,
+-        expected_shape: tuple[int],
+-    ) -> None:
+-        # Build the attributes for different opset versions
+-        attributes = {}
+-        if onesided is not None:
+-            attributes["onesided"] = onesided
+-        if inverse is not None:
+-            attributes["inverse"] = inverse
+-
+-        if version < 20:
+-            if axis is not None:
+-                attributes["axis"] = axis
+-            nodes = [make_node("DFT", ["input", ""], ["output"], **attributes)]
+-            value_infos = []
+-        else:
+-            assert version >= 20
+-            if axis is not None:
+-                nodes = [
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["axis"],
+-                        value=make_tensor("axis", TensorProto.INT64, (), (axis,)),
+-                    ),
+-                    make_node("DFT", ["input", "", "axis"], ["output"], **attributes),
+-                ]
+-                value_infos = [make_tensor_value_info("axis", TensorProto.INT64, ())]
+-            else:
+-                nodes = [
+-                    make_node("DFT", ["input", "", ""], ["output"], **attributes),
+-                ]
+-                value_infos = []
+-
+-        # Construct the graph
+-        graph = self._make_graph(
+-            [],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        input_shape,
+-                        np.ones(input_shape, dtype=np.float32).flatten(),
+-                    ),
+-                ),
+-                *nodes,
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("input", TensorProto.FLOAT, input_shape),
+-                *value_infos,
+-                make_tensor_value_info("output", TensorProto.FLOAT, expected_shape),
+-            ],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+-    @parameterized.expand(
+-        [
+-            (
+-                name,
+-                version,
+-                test_aspect,
+-                input_shape,
+-                axis,
+-                onesided,
+-                inverse,
+-                expected_shape,
+-            )
+-            for (name, version), (
+-                test_aspect,
+-                input_shape,
+-                axis,
+-                onesided,
+-                inverse,
+-                expected_shape,
+-            ) in itertools.product(
+-                all_versions_for("DFT"),
+-                (
+-                    ("reals_default_axis", (2, 5, 1), None, None, None, (2, 42, 2)),
+-                    ("reals_axis_0", (3, 5, 10, 1), 0, 0, 0, (42, 5, 10, 2)),
+-                    ("reals_axis_1", (3, 5, 10, 1), 1, 0, 0, (3, 42, 10, 2)),
+-                    ("reals_axis_2", (3, 5, 10, 1), 2, 0, 0, (3, 5, 42, 2)),
+-                    ("reals_axis_neg", (3, 5, 10, 1), -2, 0, 0, (3, 5, 42, 2)),
+-                    ("reals_axis_0_onesided", (3, 5, 10, 1), 0, 1, 0, (22, 5, 10, 2)),
+-                    ("reals_axis_1_onesided", (3, 5, 10, 1), 1, 1, 0, (3, 22, 10, 2)),
+-                    ("reals_axis_2_onesided", (3, 5, 10, 1), 2, 1, 0, (3, 5, 22, 2)),
+-                    ("reals_axis_neg_onesided", (3, 5, 10, 1), -2, 1, 0, (3, 5, 22, 2)),
+-                    ("complex_default_axis", (2, 5, 2), None, None, None, (2, 42, 2)),
+-                    ("real_inverse", (2, 5, 1), 1, None, 1, (2, 42, 2)),
+-                    ("complex_inverse", (2, 5, 2), 1, None, 1, (2, 42, 2)),
+-                    ("irfft_axis_0", (2, 5, 10, 2), 0, 1, 1, (42, 5, 10, 1)),
+-                    ("irfft_axis_1", (3, 3, 10, 2), 1, 1, 1, (3, 42, 10, 1)),
+-                    ("irfft_axis_2", (3, 5, 6, 2), 2, 1, 1, (3, 5, 42, 1)),
+-                    ("irfft_axis_neg", (3, 5, 6, 2), -2, 1, 1, (3, 5, 42, 1)),
+-                ),
+-            )
+-        ]
+-    )
+-    def test_dft_dft_length(
+-        self,
+-        _: str,
+-        version: int,
+-        _test_aspect: str,
+-        input_shape: tuple[int],
+-        axis: int | None,
+-        onesided: int | None,
+-        inverse: int | None,
+-        expected_shape: tuple[int],
+-    ) -> None:
+-        # Build the attributes for different opset versions
+-        attributes = {}
+-        if onesided is not None:
+-            attributes["onesided"] = onesided
+-        if inverse is not None:
+-            attributes["inverse"] = inverse
+-
+-        dft_length = 42
+-
+-        if version < 20:
+-            if axis is not None:
+-                attributes["axis"] = axis
+-            nodes = [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["dft_length"],
+-                    value=make_tensor(
+-                        "dft_length", TensorProto.INT64, (), (dft_length,)
+-                    ),
+-                ),
+-                make_node("DFT", ["input", "dft_length"], ["output"], **attributes),
+-            ]
+-            value_infos = [make_tensor_value_info("dft_length", TensorProto.INT64, ())]
+-        else:
+-            assert version >= 20
+-            if axis is not None:
+-                nodes = [
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["axis"],
+-                        value=make_tensor("axis", TensorProto.INT64, (), (axis,)),
+-                    ),
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["dft_length"],
+-                        value=make_tensor(
+-                            "dft_length", TensorProto.INT64, (), (dft_length,)
+-                        ),
+-                    ),
+-                    make_node(
+-                        "DFT",
+-                        ["input", "dft_length", "axis"],
+-                        ["output"],
+-                        **attributes,
+-                    ),
+-                ]
+-                value_infos = [
+-                    make_tensor_value_info("dft_length", TensorProto.INT64, ()),
+-                    make_tensor_value_info("axis", TensorProto.INT64, ()),
+-                ]
+-            else:
+-                nodes = [
+-                    make_node(
+-                        "Constant",
+-                        [],
+-                        ["dft_length"],
+-                        value=make_tensor(
+-                            "dft_length", TensorProto.INT64, (), (dft_length,)
+-                        ),
+-                    ),
+-                    make_node(
+-                        "DFT",
+-                        ["input", "dft_length", ""],
+-                        ["output"],
+-                        **attributes,
+-                    ),
+-                ]
+-                value_infos = [
+-                    make_tensor_value_info("dft_length", TensorProto.INT64, ())
+-                ]
++            graph,
++            [
++                make_tensor_value_info("shape", TensorProto.INT64, ()),
++                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
++            ],
++        )
+ 
+-        # Construct the graph
+         graph = self._make_graph(
+             [],
+             [
+                 make_node(
+                     "Constant",
+                     [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        input_shape,
+-                        np.ones(input_shape, dtype=np.float32).flatten(),
+-                    ),
++                    ["shape"],
++                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
+                 ),
+-                *nodes,
++                make_node("HannWindow", ["shape"], ["y"], periodic=0),
+             ],
+             [],
+         )
+         self._assert_inferred(
+             graph,
+             [
+-                make_tensor_value_info("input", TensorProto.FLOAT, input_shape),
+-                *value_infos,
+-                make_tensor_value_info("output", TensorProto.FLOAT, expected_shape),
++                make_tensor_value_info("shape", TensorProto.INT64, ()),
++                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
+             ],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+         )
+ 
+-    @parameterized.expand(
+-        [
+-            ("last", 3),
+-            ("last_negative", -1),
+-            ("out_of_range", 4),
+-            ("out_of_range_negative", -5),
+-        ]
+-    )
+-    def test_dft_invalid_axis_opset17(self, _: str, axis: int) -> None:
++    def test_blackmanwindow(self):
+         graph = self._make_graph(
+             [],
+             [
+                 make_node(
+                     "Constant",
+                     [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        (2, 5, 5, 2),
+-                        np.ones((2, 5, 5, 2), dtype=np.float32).flatten(),
+-                    ),
++                    ["shape"],
++                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
+                 ),
+-                make_node("DFT", ["input", ""], ["output"], onesided=1, axis=axis),
++                make_node("HammingWindow", ["shape"], ["y"]),
+             ],
+             [],
+         )
+-        with self.assertRaises(onnx.shape_inference.InferenceError):
+-            self._assert_inferred(
+-                graph,
+-                [
+-                    make_tensor_value_info("input", TensorProto.FLOAT, (2, 5, 5, 2)),
+-                    make_tensor_value_info("output", TensorProto.FLOAT, (2, 3, 5, 2)),
+-                ],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 17)],
+-            )
++        self._assert_inferred(
++            graph,
++            [
++                make_tensor_value_info("shape", TensorProto.INT64, ()),
++                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
++            ],
++        )
+ 
+-    @parameterized.expand(
+-        [
+-            ("last", 3),
+-            ("last_negative", -1),
+-            ("out_of_range", 4),
+-            ("out_of_range_negative", -5),
+-        ]
+-    )
+-    def test_dft_invalid_axis_opset20(self, _: str, axis: int) -> None:
+         graph = self._make_graph(
+             [],
+             [
+                 make_node(
+                     "Constant",
+                     [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        (2, 5, 5, 2),
+-                        np.ones((2, 5, 5, 2), dtype=np.float32).flatten(),
+-                    ),
+-                ),
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["axis"],
+-                    value=make_tensor("axis", TensorProto.INT64, (), (axis,)),
++                    ["shape"],
++                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
+                 ),
+-                make_node("DFT", ["input", "", "axis"], ["output"]),
++                make_node("HammingWindow", ["shape"], ["y"], periodic=0),
+             ],
+             [],
+         )
+-        with self.assertRaises(onnx.shape_inference.InferenceError):
+-            self._assert_inferred(
+-                graph,
+-                [
+-                    make_tensor_value_info("input", TensorProto.FLOAT, (2, 5, 5, 2)),
+-                    make_tensor_value_info("axis", TensorProto.INT64, ()),
+-                    make_tensor_value_info("output", TensorProto.FLOAT, (2, 3, 5, 2)),
+-                ],
+-                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
+-            )
++        self._assert_inferred(
++            graph,
++            [
++                make_tensor_value_info("shape", TensorProto.INT64, ()),
++                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
++            ],
++        )
+ 
+     def test_dft_rfft_invalid_complex_input_opset17(self) -> None:
+         """Test that RFFT (onesided=1, inverse=0) rejects complex input"""
+@@ -10011,128 +7806,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+                 opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
+             )
+ 
+-    @parameterized.expand(
+-        [
+-            ("real", (2, 5, 5, 1)),
+-            ("complex", (2, 5, 5, 2)),
+-        ]
+-    )
+-    def test_dft_dynamic_axis_opset20(self, _: str, shape: tuple[int, ...]) -> None:
+-        graph = self._make_graph(
+-            [("axis", TensorProto.INT64, ())],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        shape,
+-                        np.ones(shape, dtype=np.float32).flatten(),
+-                    ),
+-                ),
+-                make_node("DFT", ["input", "", "axis"], ["output"]),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("input", TensorProto.FLOAT, shape),
+-                make_tensor_value_info("output", TensorProto.FLOAT, (2, 5, 5, 2)),
+-            ],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
+-        )
+-
+-    @parameterized.expand(
+-        [
+-            ("real", (2, 5, 5, 1)),
+-        ]
+-    )
+-    def test_dft_dynamic_axis_onesided_dft_length_opset20(
+-        self, _: str, shape: tuple[int, ...]
+-    ) -> None:
+-        graph = self._make_graph(
+-            [("axis", TensorProto.INT64, ())],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        shape,
+-                        np.ones(shape, dtype=np.float32).flatten(),
+-                    ),
+-                ),
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["dft_length"],
+-                    value=make_tensor(
+-                        "dft_length",
+-                        TensorProto.INT64,
+-                        (),
+-                        np.array([42], dtype=np.int64),
+-                    ),
+-                ),
+-                make_node(
+-                    "DFT", ["input", "dft_length", "axis"], ["output"], onesided=1
+-                ),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("input", TensorProto.FLOAT, shape),
+-                make_tensor_value_info("dft_length", TensorProto.INT64, ()),
+-                make_tensor_value_info(
+-                    "output", TensorProto.FLOAT, (None, None, None, 2)
+-                ),
+-            ],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
+-        )
+-
+-    @parameterized.expand(
+-        [
+-            ("real", (2, 5, 5, 1)),
+-        ]
+-    )
+-    def test_dft_dynamic_axis_onesided_opset20(
+-        self, _: str, shape: tuple[int, ...]
+-    ) -> None:
+-        graph = self._make_graph(
+-            [("axis", TensorProto.INT64, ())],
+-            [
+-                make_node(
+-                    "Constant",
+-                    [],
+-                    ["input"],
+-                    value=make_tensor(
+-                        "input",
+-                        TensorProto.FLOAT,
+-                        shape,
+-                        np.ones(shape, dtype=np.float32).flatten(),
+-                    ),
+-                ),
+-                make_node("DFT", ["input", "", "axis"], ["output"], onesided=1),
+-            ],
+-            [],
+-        )
+-        self._assert_inferred(
+-            graph,
+-            [
+-                make_tensor_value_info("input", TensorProto.FLOAT, shape),
+-                make_tensor_value_info(
+-                    "output", TensorProto.FLOAT, (None, None, None, 2)
+-                ),
+-            ],
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
+-        )
+-
+     def test_dft_onesided_default_axis_opset17(self) -> None:
+         # Opset 17 sets default axis to be 1.
+         graph = self._make_graph(
+@@ -10591,41 +8264,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             ],
+         )
+ 
+-    @parameterized.expand(
+-        [
+-            ([1, 2, 3], ["1", "2"]),
+-            ([1, 2, 3], None),
+-            (None, ["1", "2", "3"]),
+-            (None, None),
+-        ]
+-    )
+-    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+-    def test_category_mapper_fails_if_invalid_attributes(
+-        self, cats_int64s, cats_strings
+-    ) -> None:
+-        cat = make_node(
+-            "CategoryMapper",
+-            ["x"],
+-            ["y"],
+-            domain=ONNX_ML_DOMAIN,
+-            cats_int64s=cats_int64s,
+-            cats_strings=cats_strings,
+-        )
+-        graph = self._make_graph(
+-            [("x", TensorProto.INT64, (30, 4, 5))],
+-            [cat],
+-            [],
+-        )
+-        self.assertRaises(
+-            onnx.shape_inference.InferenceError,
+-            self._inferred,
+-            graph,
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, 1),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+     @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+     def test_tree_ensemble_regressor(self) -> None:
+         tree = make_node(
+@@ -10649,131 +8287,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             ],
+         )
+ 
+-    @parameterized.expand([TensorProto.FLOAT, TensorProto.DOUBLE, TensorProto.FLOAT16])
+-    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+-    def test_tree_ensemble(self, dtype) -> None:
+-        interior_nodes = 5
+-        leaves = 9
+-        tree = make_node(
+-            "TreeEnsemble",
+-            ["x"],
+-            ["y"],
+-            domain=ONNX_ML_DOMAIN,
+-            n_targets=5,
+-            nodes_featureids=[0] * interior_nodes,
+-            nodes_splits=make_tensor(
+-                "nodes_splits",
+-                dtype,
+-                (interior_nodes,),
+-                list(range(interior_nodes)),
+-            ),
+-            nodes_modes=make_tensor(
+-                "nodes_modes",
+-                TensorProto.UINT8,
+-                (interior_nodes,),
+-                [0] * interior_nodes,
+-            ),
+-            nodes_truenodeids=[0] * interior_nodes,
+-            nodes_falsenodeids=[0] * interior_nodes,
+-            nodes_trueleafs=[0] * interior_nodes,
+-            nodes_falseleafs=[0] * interior_nodes,
+-            membership_values=make_tensor(
+-                "membership_values",
+-                dtype,
+-                (7,),
+-                [0.0, 0.1, 0.2, np.nan, 0.4, 0.5, 1.0],
+-            ),
+-            leaf_targetids=[0] * leaves,
+-            leaf_weights=make_tensor("leaf_weights", dtype, (leaves,), [1] * leaves),
+-            tree_roots=[0],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", dtype, ("Batch Size", "Features"))],
+-            [tree],
+-            [],
+-        )
+-
+-        self._assert_inferred(
+-            graph,
+-            [make_tensor_value_info("y", dtype, ("Batch Size", 5))],
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, 5),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+-    @parameterized.expand(
+-        [
+-            (
+-                [0] * 6,
+-                make_tensor("leaf_weights", TensorProto.DOUBLE, (9,), [1] * 9),
+-                make_tensor("nodes_splits", TensorProto.DOUBLE, (5,), [1] * 5),
+-            ),
+-            (
+-                [0] * 5,
+-                make_tensor("leaf_weights", TensorProto.FLOAT, (9,), [1] * 9),
+-                make_tensor("nodes_splits", TensorProto.DOUBLE, (5,), [1] * 5),
+-            ),
+-            (
+-                [0] * 5,
+-                make_tensor("leaf_weights", TensorProto.DOUBLE, (18,), [1] * 18),
+-                make_tensor("nodes_splits", TensorProto.DOUBLE, (5,), [1] * 5),
+-            ),
+-            (
+-                [0] * 5,
+-                make_tensor("leaf_weights", TensorProto.DOUBLE, (9,), [1] * 9),
+-                make_tensor("nodes_splits", TensorProto.FLOAT, (5,), [1] * 5),
+-            ),
+-        ]
+-    )
+-    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+-    def test_tree_ensemble_fails_if_invalid_attributes(
+-        self,
+-        nodes_truenodeids,
+-        leaf_weights,
+-        nodes_splits,
+-    ) -> None:
+-        interior_nodes = 5
+-        leaves = 9
+-        tree = make_node(
+-            "TreeEnsemble",
+-            ["x"],
+-            ["y"],
+-            domain=ONNX_ML_DOMAIN,
+-            n_targets=5,
+-            nodes_featureids=[0] * interior_nodes,
+-            nodes_splits=nodes_splits,
+-            nodes_modes=make_tensor(
+-                "nodes_modes",
+-                TensorProto.UINT8,
+-                (interior_nodes,),
+-                [0] * interior_nodes,
+-            ),
+-            nodes_truenodeids=nodes_truenodeids,
+-            nodes_falsenodeids=[0] * interior_nodes,
+-            nodes_trueleafs=[0] * interior_nodes,
+-            nodes_falseleafs=[0] * interior_nodes,
+-            leaf_targetids=[0] * leaves,
+-            leaf_weights=leaf_weights,
+-            tree_roots=[0],
+-        )
+-
+-        graph = self._make_graph(
+-            [("x", TensorProto.DOUBLE, ("Batch Size", "Features"))],
+-            [tree],
+-            [],
+-        )
+-        self.assertRaises(
+-            onnx.shape_inference.InferenceError,
+-            self._inferred,
+-            graph,
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, 5),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+     @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+     def test_tree_ensemble_classifier(self) -> None:
+         tree = make_node(
+@@ -10878,40 +8391,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             ],
+         )
+ 
+-    @parameterized.expand(
+-        [
+-            ([1, 2, 3], ["1", "2", "3"]),
+-            (None, None),
+-        ]
+-    )
+-    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+-    def test_one_hot_encoder_fails_if_invalid_attributes(
+-        self, cats_int64s, cats_strings
+-    ) -> None:
+-        graph = self._make_graph(
+-            [("input", TensorProto.INT64, (2, "N", 3))],
+-            [
+-                make_node(
+-                    "OneHotEncoder",
+-                    ["input"],
+-                    ["output"],
+-                    cats_int64s=cats_int64s,
+-                    cats_strings=cats_strings,
+-                    domain="ai.onnx.ml",
+-                )
+-            ],
+-            [],
+-        )
+-        self.assertRaises(
+-            onnx.shape_inference.InferenceError,
+-            self._inferred,
+-            graph,
+-            opset_imports=[
+-                make_opsetid(ONNX_ML_DOMAIN, 1),
+-                make_opsetid(ONNX_DOMAIN, 11),
+-            ],
+-        )
+-
+     @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
+     def test_zip_map(self) -> None:
+         params = (
+@@ -11066,28 +8545,6 @@ class TestShapeInference(TestShapeInferenceHelper):
+             onnx.checker.check_model(model, full_check=True)
+             onnx.shape_inference.infer_shapes(model)
+ 
+-    @parameterized.expand(all_versions_for("ConstantOfShape"))
+-    def test_issue_constantofshape_6135(self, _, version):
+-        graph = self._make_graph(
+-            [("std.constant", TensorProto.INT64, (1,)), "output"],
+-            [
+-                make_node(
+-                    "ConstantOfShape",
+-                    inputs=["std.constant"],
+-                    outputs=["output"],
+-                    name="invalid_node",
+-                )
+-            ],
+-            [],
+-            initializer=[make_tensor("std.constant", TensorProto.FLOAT, (1,), (-10,))],
+-        )
+-        self.assertRaises(
+-            onnx.shape_inference.InferenceError,
+-            self._inferred,
+-            graph,
+-            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
+-        )
+-
+     def test_protobuf_default(self) -> None:
+         model_text = """
+             ir_version: 8
+diff --git a/onnx/test/test_external_data.py b/onnx/test/test_external_data.py
+index c0845f96a..eb07f09e8 100644
+--- a/onnx/test/test_external_data.py
++++ b/onnx/test/test_external_data.py
+@@ -14,7 +14,6 @@ import warnings
+ from typing import TYPE_CHECKING, Any
+ 
+ import numpy as np
+-import parameterized
+ 
+ import onnx
+ from onnx import (
+@@ -123,616 +122,6 @@ class TestLoadExternalDataBase(unittest.TestCase):
+         checker.check_model(self.model_filename)
+ 
+ 
+-@parameterized.parameterized_class(
+-    [
+-        {"serialization_format": "protobuf"},
+-        {"serialization_format": "textproto"},
+-    ]
+-)
+-class TestLoadExternalData(TestLoadExternalDataBase):
+-    def test_load_external_data(self) -> None:
+-        model = onnx.load_model(self.model_filename, self.serialization_format)
+-        initializer_tensor = model.graph.initializer[0]
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    def test_load_external_data_for_model(self) -> None:
+-        model = onnx.load_model(
+-            self.model_filename, self.serialization_format, load_external_data=False
+-        )
+-        load_external_data_for_model(model, self.temp_dir)
+-        initializer_tensor = model.graph.initializer[0]
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    def test_save_external_data(self) -> None:
+-        model = onnx.load_model(self.model_filename, self.serialization_format)
+-
+-        temp_dir = os.path.join(self.temp_dir, "save_copy")
+-        os.mkdir(temp_dir)
+-        new_model_filename = os.path.join(temp_dir, "model.onnx")
+-        onnx.save_model(model, new_model_filename, self.serialization_format)
+-
+-        new_model = onnx.load_model(new_model_filename, self.serialization_format)
+-        initializer_tensor = new_model.graph.initializer[0]
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = new_model.graph.node[0].attribute[0].t
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-
+-@parameterized.parameterized_class(
+-    [
+-        {"serialization_format": "protobuf"},
+-        {"serialization_format": "textproto"},
+-    ]
+-)
+-class TestLoadExternalDataSingleFile(TestLoadExternalDataBase):
+-    def create_external_data_tensors(
+-        self, tensors_data: list[tuple[list[Any], Any]]
+-    ) -> list[TensorProto]:
+-        tensor_filename = "tensors.bin"
+-        tensors = []
+-
+-        with open(os.path.join(self.temp_dir, tensor_filename), "ab") as data_file:
+-            for value, tensor_name in tensors_data:
+-                tensor = from_array(np.array(value))
+-                offset = data_file.tell()
+-                if offset % 4096 != 0:
+-                    data_file.write(b"\0" * (4096 - offset % 4096))
+-                    offset = offset + 4096 - offset % 4096
+-
+-                data_file.write(tensor.raw_data)
+-                set_external_data(
+-                    tensor,
+-                    location=tensor_filename,
+-                    offset=offset,
+-                    length=data_file.tell() - offset,
+-                )
+-                tensor.name = tensor_name
+-                tensor.ClearField("raw_data")
+-                tensor.data_location = onnx.TensorProto.EXTERNAL
+-                tensors.append(tensor)
+-
+-        return tensors
+-
+-    def test_load_external_single_file_data(self) -> None:
+-        model = onnx.load_model(self.model_filename, self.serialization_format)
+-
+-        initializer_tensor = model.graph.initializer[0]
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    def test_save_external_single_file_data(self) -> None:
+-        model = onnx.load_model(self.model_filename, self.serialization_format)
+-
+-        temp_dir = os.path.join(self.temp_dir, "save_copy")
+-        os.mkdir(temp_dir)
+-        new_model_filename = os.path.join(temp_dir, "model.onnx")
+-        onnx.save_model(model, new_model_filename, self.serialization_format)
+-
+-        new_model = onnx.load_model(new_model_filename, self.serialization_format)
+-        initializer_tensor = new_model.graph.initializer[0]
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = new_model.graph.node[0].attribute[0].t
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    @parameterized.parameterized.expand(
+-        itertools.product(
+-            (True, False),
+-        )
+-    )
+-    def test_save_external_invalid_single_file_data_and_check(
+-        self, use_absolute_path: bool
+-    ) -> None:
+-        model = onnx.load_model(self.model_filename, self.serialization_format)
+-
+-        model_dir = os.path.join(self.temp_dir, "save_copy")
+-        os.mkdir(model_dir)
+-
+-        traversal_external_data_dir = os.path.join(
+-            self.temp_dir, "invalid_external_data"
+-        )
+-        os.mkdir(traversal_external_data_dir)
+-
+-        if use_absolute_path:
+-            traversal_external_data_location = os.path.join(
+-                traversal_external_data_dir, "tensors.bin"
+-            )
+-        else:
+-            traversal_external_data_location = "../invalid_external_data/tensors.bin"
+-
+-        external_data_dir = os.path.join(self.temp_dir, "external_data")
+-        os.mkdir(external_data_dir)
+-        new_model_filepath = os.path.join(model_dir, "model.onnx")
+-
+-        def convert_model_to_external_data_no_check(model: ModelProto, location: str):
+-            for tensor in model.graph.initializer:
+-                if tensor.HasField("raw_data"):
+-                    set_external_data(tensor, location)
+-
+-        convert_model_to_external_data_no_check(
+-            model,
+-            location=traversal_external_data_location,
+-        )
+-
+-        with self.assertRaises(onnx.checker.ValidationError):
+-            onnx.save_model(model, new_model_filepath, self.serialization_format)
+-
+-
+-@parameterized.parameterized_class(
+-    [
+-        {"serialization_format": "protobuf"},
+-        {"serialization_format": "textproto"},
+-    ]
+-)
+-class TestSaveAllTensorsAsExternalData(unittest.TestCase):
+-    serialization_format: str = "protobuf"
+-
+-    def setUp(self) -> None:
+-        self._temp_dir_obj = tempfile.TemporaryDirectory()
+-        self.temp_dir: str = self._temp_dir_obj.name
+-        self.initializer_value = np.arange(6).reshape(3, 2).astype(np.float32) + 512
+-        self.attribute_value = np.arange(6).reshape(2, 3).astype(np.float32) + 256
+-        self.model = self.create_test_model_proto()
+-
+-    def get_temp_model_filename(self):
+-        return os.path.join(self.temp_dir, str(uuid.uuid4()) + ".onnx")
+-
+-    def create_data_tensors(
+-        self, tensors_data: list[tuple[list[Any], Any]]
+-    ) -> list[TensorProto]:
+-        tensors = []
+-        for value, tensor_name in tensors_data:
+-            tensor = from_array(np.array(value))
+-            tensor.name = tensor_name
+-            tensors.append(tensor)
+-
+-        return tensors
+-
+-    def create_test_model_proto(self) -> ModelProto:
+-        tensors = self.create_data_tensors(
+-            [
+-                (self.attribute_value, "attribute_value"),
+-                (self.initializer_value, "input_value"),
+-            ]
+-        )
+-
+-        constant_node = onnx.helper.make_node(
+-            "Constant", inputs=[], outputs=["values"], value=tensors[0]
+-        )
+-
+-        inputs = [
+-            helper.make_tensor_value_info(
+-                "input_value", onnx.TensorProto.FLOAT, self.initializer_value.shape
+-            )
+-        ]
+-
+-        graph = helper.make_graph(
+-            [constant_node],
+-            "test_graph",
+-            inputs=inputs,
+-            outputs=[],
+-            initializer=[tensors[1]],
+-        )
+-        return helper.make_model(graph)
+-
+-    @unittest.skipIf(
+-        serialization_format != "protobuf",
+-        "check_model supports protobuf only when provided as a path",
+-    )
+-    def test_check_model(self) -> None:
+-        checker.check_model(self.model)
+-
+-    def test_convert_model_to_external_data_with_size_threshold(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-
+-        convert_model_to_external_data(self.model, size_threshold=1024)
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertFalse(initializer_tensor.HasField("data_location"))
+-
+-    def test_convert_model_to_external_data_without_size_threshold(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-        convert_model_to_external_data(self.model, size_threshold=0)
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertTrue(initializer_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-    def test_convert_model_to_external_data_from_one_file_with_location(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-        external_data_file = str(uuid.uuid4())
+-
+-        convert_model_to_external_data(
+-            self.model,
+-            size_threshold=0,
+-            all_tensors_to_one_file=True,
+-            location=external_data_file,
+-        )
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, external_data_file)))
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-
+-        # test convert model from external data
+-        convert_model_from_external_data(model)
+-        model_file_path = self.get_temp_model_filename()
+-        onnx.save_model(model, model_file_path, self.serialization_format)
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertFalse(len(initializer_tensor.external_data))
+-        self.assertEqual(initializer_tensor.data_location, TensorProto.DEFAULT)
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        self.assertFalse(len(attribute_tensor.external_data))
+-        self.assertEqual(attribute_tensor.data_location, TensorProto.DEFAULT)
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    def test_convert_model_to_external_data_from_one_file_without_location_uses_model_name(
+-        self,
+-    ) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-
+-        convert_model_to_external_data(
+-            self.model, size_threshold=0, all_tensors_to_one_file=True
+-        )
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        self.assertTrue(os.path.isfile(model_file_path))
+-        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, model_file_path)))
+-
+-    def test_convert_model_to_external_data_one_file_per_tensor_without_attribute(
+-        self,
+-    ) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-
+-        convert_model_to_external_data(
+-            self.model,
+-            size_threshold=0,
+-            all_tensors_to_one_file=False,
+-            convert_attribute=False,
+-        )
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        self.assertTrue(os.path.isfile(model_file_path))
+-        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "input_value")))
+-        self.assertFalse(os.path.isfile(os.path.join(self.temp_dir, "attribute_value")))
+-
+-    def test_convert_model_to_external_data_one_file_per_tensor_with_attribute(
+-        self,
+-    ) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-
+-        convert_model_to_external_data(
+-            self.model,
+-            size_threshold=0,
+-            all_tensors_to_one_file=False,
+-            convert_attribute=True,
+-        )
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        self.assertTrue(os.path.isfile(model_file_path))
+-        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "input_value")))
+-        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "attribute_value")))
+-
+-    def test_convert_model_to_external_data_does_not_convert_attribute_values(
+-        self,
+-    ) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-
+-        convert_model_to_external_data(
+-            self.model,
+-            size_threshold=0,
+-            convert_attribute=False,
+-            all_tensors_to_one_file=False,
+-        )
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "input_value")))
+-        self.assertFalse(os.path.isfile(os.path.join(self.temp_dir, "attribute_value")))
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertTrue(initializer_tensor.HasField("data_location"))
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        self.assertFalse(attribute_tensor.HasField("data_location"))
+-
+-    def test_convert_model_to_external_data_converts_attribute_values(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-
+-        convert_model_to_external_data(
+-            self.model, size_threshold=0, convert_attribute=True
+-        )
+-        onnx.save_model(self.model, model_file_path, self.serialization_format)
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-
+-        initializer_tensor = model.graph.initializer[0]
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-        self.assertTrue(initializer_tensor.HasField("data_location"))
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-        self.assertTrue(attribute_tensor.HasField("data_location"))
+-
+-    def test_save_model_does_not_convert_to_external_data_and_saves_the_model(
+-        self,
+-    ) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-        onnx.save_model(
+-            self.model,
+-            model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=False,
+-        )
+-        self.assertTrue(os.path.isfile(model_file_path))
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertFalse(initializer_tensor.HasField("data_location"))
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        self.assertFalse(attribute_tensor.HasField("data_location"))
+-
+-    def test_save_model_does_convert_and_saves_the_model(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-        onnx.save_model(
+-            self.model,
+-            model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            all_tensors_to_one_file=True,
+-            location=None,
+-            size_threshold=0,
+-            convert_attribute=False,
+-        )
+-
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertTrue(initializer_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        self.assertFalse(attribute_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    def test_save_model_without_loading_external_data(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-        onnx.save_model(
+-            self.model,
+-            model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            location=None,
+-            size_threshold=0,
+-            convert_attribute=False,
+-        )
+-        # Save without load_external_data
+-        model = onnx.load_model(
+-            model_file_path, self.serialization_format, load_external_data=False
+-        )
+-        onnx.save_model(
+-            model,
+-            model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            location=None,
+-            size_threshold=0,
+-            convert_attribute=False,
+-        )
+-        # Load the saved model again; Only works if the saved path is under the same directory
+-        model = onnx.load_model(model_file_path, self.serialization_format)
+-
+-        initializer_tensor = model.graph.initializer[0]
+-        self.assertTrue(initializer_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
+-
+-        attribute_tensor = model.graph.node[0].attribute[0].t
+-        self.assertFalse(attribute_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
+-
+-    def test_save_model_with_existing_raw_data_should_override(self) -> None:
+-        model_file_path = self.get_temp_model_filename()
+-        original_raw_data = self.model.graph.initializer[0].raw_data
+-        onnx.save_model(
+-            self.model,
+-            model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            size_threshold=0,
+-        )
+-        self.assertTrue(os.path.isfile(model_file_path))
+-
+-        model = onnx.load_model(
+-            model_file_path, self.serialization_format, load_external_data=False
+-        )
+-        initializer_tensor = model.graph.initializer[0]
+-        initializer_tensor.raw_data = b"dummpy_raw_data"
+-        # If raw_data and external tensor exist at the same time, override existing raw_data
+-        load_external_data_for_tensor(initializer_tensor, self.temp_dir)
+-        self.assertEqual(initializer_tensor.raw_data, original_raw_data)
+-
+-
+-@parameterized.parameterized_class(
+-    [
+-        {"serialization_format": "protobuf"},
+-        {"serialization_format": "textproto"},
+-    ]
+-)
+-class TestExternalDataToArray(unittest.TestCase):
+-    serialization_format: str = "protobuf"
+-
+-    def setUp(self) -> None:
+-        self._temp_dir_obj = tempfile.TemporaryDirectory()
+-        self.temp_dir: str = self._temp_dir_obj.name
+-        self._model_file_path: str = os.path.join(self.temp_dir, "model.onnx")
+-        self.large_data = np.random.rand(10, 60, 100).astype(np.float32)
+-        self.small_data = (200, 300)
+-        self.model = self.create_test_model()
+-
+-    @property
+-    def model_file_path(self):
+-        return self._model_file_path
+-
+-    def tearDown(self) -> None:
+-        self._temp_dir_obj.cleanup()
+-
+-    def create_test_model(self) -> ModelProto:
+-        X = helper.make_tensor_value_info("X", TensorProto.FLOAT, self.large_data.shape)
+-        input_init = helper.make_tensor(
+-            name="X",
+-            data_type=TensorProto.FLOAT,
+-            dims=self.large_data.shape,
+-            vals=onnx.numpy_helper.tobytes_little_endian(self.large_data),
+-            raw=True,
+-        )
+-
+-        shape_data = np.array(self.small_data, np.int64)
+-        shape_init = helper.make_tensor(
+-            name="Shape",
+-            data_type=TensorProto.INT64,
+-            dims=shape_data.shape,
+-            vals=onnx.numpy_helper.tobytes_little_endian(shape_data),
+-            raw=True,
+-        )
+-        C = helper.make_tensor_value_info("C", TensorProto.INT64, self.small_data)
+-
+-        reshape = onnx.helper.make_node(
+-            "Reshape",
+-            inputs=["X", "Shape"],
+-            outputs=["Y"],
+-        )
+-        cast = onnx.helper.make_node(
+-            "Cast", inputs=["Y"], outputs=["C"], to=TensorProto.INT64
+-        )
+-
+-        graph_def = helper.make_graph(
+-            [reshape, cast],
+-            "test-model",
+-            [X],
+-            [C],
+-            initializer=[input_init, shape_init],
+-        )
+-        return helper.make_model(graph_def, producer_name="onnx-example")
+-
+-    @unittest.skipIf(
+-        serialization_format != "protobuf",
+-        "check_model supports protobuf only when provided as a path",
+-    )
+-    def test_check_model(self) -> None:
+-        checker.check_model(self.model)
+-
+-    def test_reshape_inference_with_external_data_fail(self) -> None:
+-        onnx.save_model(
+-            self.model,
+-            self.model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            all_tensors_to_one_file=False,
+-            size_threshold=0,
+-        )
+-        model_without_external_data = onnx.load(
+-            self.model_file_path, self.serialization_format, load_external_data=False
+-        )
+-        # Shape inference of Reshape uses ParseData
+-        # ParseData cannot handle external data and should throw the error as follows:
+-        # Cannot parse data from external tensors. Please load external data into raw data for tensor: Shape
+-        self.assertRaises(
+-            shape_inference.InferenceError,
+-            shape_inference.infer_shapes,
+-            model_without_external_data,
+-            strict_mode=True,
+-        )
+-
+-    def test_to_array_with_external_data(self) -> None:
+-        onnx.save_model(
+-            self.model,
+-            self.model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            all_tensors_to_one_file=False,
+-            size_threshold=0,
+-        )
+-        # raw_data of external tensor is not loaded
+-        model = onnx.load(
+-            self.model_file_path, self.serialization_format, load_external_data=False
+-        )
+-        # Specify self.temp_dir to load external tensor
+-        loaded_large_data = to_array(model.graph.initializer[0], self.temp_dir)
+-        np.testing.assert_allclose(loaded_large_data, self.large_data)
+-
+-    def test_save_model_with_external_data_multiple_times(self) -> None:
+-        # Test onnx.save should respectively handle typical tensor and external tensor properly
+-        # 1st save: save two tensors which have raw_data
+-        # Only w_large will be stored as external tensors since it's larger than 1024
+-        onnx.save_model(
+-            self.model,
+-            self.model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            all_tensors_to_one_file=False,
+-            location=None,
+-            size_threshold=1024,
+-            convert_attribute=True,
+-        )
+-        model_without_loading_external = onnx.load(
+-            self.model_file_path, self.serialization_format, load_external_data=False
+-        )
+-        large_input_tensor = model_without_loading_external.graph.initializer[0]
+-        self.assertTrue(large_input_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(
+-            to_array(large_input_tensor, self.temp_dir), self.large_data
+-        )
+-
+-        small_shape_tensor = model_without_loading_external.graph.initializer[1]
+-        self.assertTrue(not small_shape_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(to_array(small_shape_tensor), self.small_data)
+-
+-        # 2nd save: one tensor has raw_data (small); one external tensor (large)
+-        # Save them both as external tensors this time
+-        onnx.save_model(
+-            model_without_loading_external,
+-            self.model_file_path,
+-            self.serialization_format,
+-            save_as_external_data=True,
+-            all_tensors_to_one_file=False,
+-            location=None,
+-            size_threshold=0,
+-            convert_attribute=True,
+-        )
+-
+-        model_without_loading_external = onnx.load(
+-            self.model_file_path, self.serialization_format, load_external_data=False
+-        )
+-        large_input_tensor = model_without_loading_external.graph.initializer[0]
+-        self.assertTrue(large_input_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(
+-            to_array(large_input_tensor, self.temp_dir), self.large_data
+-        )
+-
+-        small_shape_tensor = model_without_loading_external.graph.initializer[1]
+-        self.assertTrue(small_shape_tensor.HasField("data_location"))
+-        np.testing.assert_allclose(
+-            to_array(small_shape_tensor, self.temp_dir), self.small_data
+-        )
+-
+-
+ class TestNotAllowToLoadExternalDataOutsideModelDirectory(TestLoadExternalDataBase):
+     """Essential test to check that onnx (validate) C++ code will not allow to load external_data outside the model
+     directory.
+@@ -797,17 +186,6 @@ class TestNotAllowToLoadExternalDataOutsideModelDirectoryOnWindows(
+             checker.check_model(self.model_filename)
+ 
+ 
+-class TestSaveAllTensorsAsExternalDataWithPath(TestSaveAllTensorsAsExternalData):
+-    def get_temp_model_filename(self) -> pathlib.Path:
+-        return pathlib.Path(super().get_temp_model_filename())
+-
+-
+-class TestExternalDataToArrayWithPath(TestExternalDataToArray):
+-    @property
+-    def model_file_path(self) -> pathlib.Path:
+-        return pathlib.Path(self._model_file_path)
+-
+-
+ class TestFunctionsAndSubGraphs(unittest.TestCase):
+     def setUp(self) -> None:
+         self._temp_dir_obj = tempfile.TemporaryDirectory()
+diff --git a/onnx/test/version_converter/automatic_downgrade_test.py b/onnx/test/version_converter/automatic_downgrade_test.py
+index a94aea1a9..f639d44f8 100644
+--- a/onnx/test/version_converter/automatic_downgrade_test.py
++++ b/onnx/test/version_converter/automatic_downgrade_test.py
+@@ -7,7 +7,6 @@ import unittest
+ 
+ import automatic_conversion_test_base
+ import numpy as np
+-import parameterized
+ 
+ import onnx
+ from onnx import helper
+@@ -22,35 +21,6 @@ class TestAutomaticDowngrade(automatic_conversion_test_base.TestAutomaticConvers
+     def _test_op_downgrade(self, op: str, *args, **kwargs):
+         self._test_op_conversion(op, *args, **kwargs, is_upgrade=False)
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            "ReduceL1",
+-            "ReduceL2",
+-            "ReduceLogSum",
+-            "ReduceLogSumExp",
+-            "ReduceMean",
+-            "ReduceMax",
+-            "ReduceMin",
+-            "ReduceProd",
+-            "ReduceSum",
+-            "ReduceSumSquare",
+-        ]
+-    )
+-    def test_reduce_ops(self, op) -> None:
+-        # TODO: need to add test cases for missing axes input which depends on this pr:
+-        # https://github.com/onnx/onnx/pull/5613
+-        axes = helper.make_tensor(
+-            "b", onnx.TensorProto.INT64, dims=[3], vals=np.array([0, 1, 2])
+-        )
+-        self._test_op_downgrade(
+-            op,
+-            from_opset=13,
+-            input_shapes=[[3, 4, 5], [3]],
+-            output_shapes=[[1, 1, 1]],
+-            input_types=[onnx.TensorProto.FLOAT, onnx.TensorProto.INT64],
+-            initializer=[axes],
+-        )
+-
+     def test_dft20_no_axis(self) -> None:
+         self._test_model_conversion(
+             to_opset=19,
+diff --git a/onnx/test/version_converter_test.py b/onnx/test/version_converter_test.py
+index a75edcde7..fd057518f 100644
+--- a/onnx/test/version_converter_test.py
++++ b/onnx/test/version_converter_test.py
+@@ -10,7 +10,6 @@ import tempfile
+ import unittest
+ 
+ import numpy as np
+-import parameterized
+ 
+ import onnx.version_converter
+ from onnx import (
+@@ -2115,169 +2114,6 @@ class TestVersionConverter(unittest.TestCase):
+         assert converted_model.graph.node[0].attribute[0].i == 2
+         assert converted_model.opset_import[0].version == 12
+ 
+-    @parameterized.parameterized.expand(
+-        [
+-            ("per_tensor", (16, 3), (1,), None, None, None, TensorProto.INT8, True),
+-            (
+-                "per_axis_none_block_shape",
+-                (16, 3),
+-                (16,),
+-                1,
+-                None,
+-                None,
+-                TensorProto.INT8,
+-                True,
+-            ),
+-            (
+-                "per_axis_zero_block_shape",
+-                (16, 3),
+-                (16,),
+-                1,
+-                0,
+-                None,
+-                TensorProto.INT8,
+-                True,
+-            ),
+-            (
+-                "per_tensor_positive_block_shape",
+-                (16, 3),
+-                (1,),
+-                1,
+-                2,
+-                None,
+-                TensorProto.INT8,
+-                False,
+-            ),
+-            (
+-                "per_axis_positive_block_shape",
+-                (16, 3),
+-                (16,),
+-                1,
+-                2,
+-                None,
+-                TensorProto.INT8,
+-                False,
+-            ),
+-            ("blocked_2d", (16, 3), (4, 3), 0, 4, None, TensorProto.INT8, False),
+-            ("blocked_3d", (4, 3, 32), (4, 3, 8), 2, 4, None, TensorProto.INT8, False),
+-            (
+-                "per_axis_output_dtype",
+-                (16, 3),
+-                (16,),
+-                1,
+-                None,
+-                TensorProto.FLOAT8E4M3FN,
+-                None,
+-                False,
+-            ),
+-            (
+-                "per_axis_unsupported_type",
+-                (16, 3),
+-                (16,),
+-                1,
+-                None,
+-                None,
+-                TensorProto.UINT16,
+-                False,
+-            ),
+-        ]
+-    )
+-    def test_quantize_21_20(
+-        self,
+-        _: str,
+-        x_shape: tuple[int, ...],
+-        scale_shape: tuple[int, ...],
+-        axis: int,
+-        block_size: int,
+-        output_dtype: int | None,
+-        zero_point_dtype: int | None,
+-        compatible: bool,
+-    ) -> None:
+-        def test(
+-            input_shape, scale_shape, axis, block_size, output_dtype, zero_point_dtype
+-        ) -> None:
+-            nodes = [
+-                helper.make_node(
+-                    "QuantizeLinear",
+-                    ["X", "S"],
+-                    ["Y"],
+-                    axis=axis,
+-                    block_size=block_size,
+-                    output_dtype=output_dtype,
+-                )
+-            ]
+-            inputs = [
+-                helper.make_tensor_value_info("X", TensorProto.FLOAT, input_shape),
+-                helper.make_tensor_value_info("S", TensorProto.FLOAT, scale_shape),
+-            ]
+-            if zero_point_dtype:
+-                inputs.append(
+-                    helper.make_tensor_value_info("ZP", zero_point_dtype, scale_shape)
+-                )
+-                nodes[0].input.append("ZP")
+-            output_type_ = output_dtype or zero_point_dtype
+-            graph = helper.make_graph(
+-                nodes,
+-                "test",
+-                inputs,
+-                [helper.make_tensor_value_info("Y", output_type_, input_shape)],
+-            )
+-            _ = self._converted(graph, helper.make_operatorsetid("", 21), 20)
+-
+-        context_manager = (
+-            contextlib.nullcontext() if compatible else self.assertRaises(RuntimeError)
+-        )
+-        with context_manager:
+-            test(x_shape, scale_shape, axis, block_size, output_dtype, zero_point_dtype)
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            ("per_tensor", (16, 3), (1,), None, None, True),
+-            ("per_axis_none_block_shape", (16, 3), (16,), 1, None, True),
+-            ("per_axis_zero_block_shape", (16, 3), (16,), 1, 0, True),
+-            ("per_tensor_positive_block_shape", (16, 3), (1,), 1, 2, False),
+-            ("per_axis_positive_block_shape", (16, 3), (16,), 1, 2, False),
+-            ("blocked_2d", (16, 3), (4, 3), 0, 4, False),
+-            ("blocked_3d", (4, 3, 32), (4, 3, 8), 2, 4, False),
+-        ]
+-    )
+-    def test_dequantize_21_20(
+-        self,
+-        _: str,
+-        y_shape: tuple[int, ...],
+-        scale_shape: tuple[int, ...],
+-        axis: int,
+-        block_size: int,
+-        compatible: bool,
+-    ) -> None:
+-        def test(input_shape, scale_shape, axis, block_size) -> None:
+-            nodes = [
+-                helper.make_node(
+-                    "DequantizeLinear",
+-                    ["X", "S", "ZP"],
+-                    ["Y"],
+-                    axis=axis,
+-                    block_size=block_size,
+-                )
+-            ]
+-            graph = helper.make_graph(
+-                nodes,
+-                "test",
+-                [
+-                    helper.make_tensor_value_info("X", TensorProto.INT8, input_shape),
+-                    helper.make_tensor_value_info("S", TensorProto.FLOAT, scale_shape),
+-                    helper.make_tensor_value_info("ZP", TensorProto.INT8, scale_shape),
+-                ],
+-                [helper.make_tensor_value_info("Y", TensorProto.FLOAT, input_shape)],
+-            )
+-            _ = self._converted(graph, helper.make_operatorsetid("", 21), 20)
+-
+-        context_manager = (
+-            contextlib.nullcontext() if compatible else self.assertRaises(RuntimeError)
+-        )
+-        with context_manager:
+-            test(y_shape, scale_shape, axis, block_size)
+-
+     def test_external_data_version_conversion(self) -> None:
+         with tempfile.TemporaryDirectory() as temp_dir:
+             # Create a model with external data
+@@ -2413,76 +2249,6 @@ class TestVersionConverter(unittest.TestCase):
+             [helper.make_tensor_value_info("out", dtype, data_s)],
+         )
+ 
+-    # Scatter 16 -> 15: TypeRestriction (bfloat16) + RemoveAttribute (reduction)
+-    @parameterized.parameterized.expand([("ScatterElements",), ("ScatterND",)])
+-    def test_scatter_16_15_success(self, op_name: str) -> None:
+-        graph = self._make_scatter_graph(op_name, TensorProto.FLOAT, "none")
+-        converted = self._converted(graph, helper.make_operatorsetid("", 16), 15)
+-        assert converted.opset_import[0].version == 15
+-
+-    @parameterized.parameterized.expand([("ScatterElements",), ("ScatterND",)])
+-    def test_scatter_16_15_bfloat16_fails(self, op_name: str) -> None:
+-        def test() -> None:
+-            graph = self._make_scatter_graph(op_name, TensorProto.BFLOAT16)
+-            self._converted(graph, helper.make_operatorsetid("", 16), 15)
+-
+-        self.assertRaises(RuntimeError, test)
+-
+-    # Opset 16 added reduction 'add' and 'mul'; 16 -> 15 only allows 'none'
+-    @parameterized.parameterized.expand(
+-        [
+-            ("ScatterElements", "add"),
+-            ("ScatterElements", "mul"),
+-            ("ScatterND", "add"),
+-            ("ScatterND", "mul"),
+-        ]
+-    )
+-    def test_scatter_16_15_reduction_add_mul_fails(
+-        self, op_name: str, reduction: str
+-    ) -> None:
+-        def test() -> None:
+-            graph = self._make_scatter_graph(op_name, TensorProto.FLOAT, reduction)
+-            self._converted(graph, helper.make_operatorsetid("", 16), 15)
+-
+-        self.assertRaises(RuntimeError, test)
+-
+-    # Scatter 18 -> 17: reject reduction "max" / "min"
+-    @parameterized.parameterized.expand(
+-        [
+-            ("ScatterElements", "max"),
+-            ("ScatterElements", "min"),
+-            ("ScatterND", "max"),
+-            ("ScatterND", "min"),
+-        ]
+-    )
+-    def test_scatter_18_17_reduction_max_min_fails(
+-        self, op_name: str, reduction: str
+-    ) -> None:
+-        def test() -> None:
+-            graph = self._make_scatter_graph(op_name, TensorProto.FLOAT, reduction)
+-            self._converted(graph, helper.make_operatorsetid("", 18), 17)
+-
+-        self.assertRaises(RuntimeError, test)
+-
+-    @parameterized.parameterized.expand(
+-        [
+-            ("ScatterElements", None),
+-            ("ScatterElements", "none"),
+-            ("ScatterElements", "add"),
+-            ("ScatterElements", "mul"),
+-            ("ScatterND", None),
+-            ("ScatterND", "none"),
+-            ("ScatterND", "add"),
+-            ("ScatterND", "mul"),
+-        ]
+-    )
+-    def test_scatter_18_17_allowed_reductions_success(
+-        self, op_name: str, reduction: str | None
+-    ) -> None:
+-        graph = self._make_scatter_graph(op_name, TensorProto.FLOAT, reduction)
+-        converted = self._converted(graph, helper.make_operatorsetid("", 18), 17)
+-        checker.check_model(converted)
+-
+ 
+ if __name__ == "__main__":
+     unittest.main()
+diff --git a/requirements-dev.txt b/requirements-dev.txt
+index e36ecd6d9..7e4a0ccd4 100644
+--- a/requirements-dev.txt
++++ b/requirements-dev.txt
+@@ -1,6 +1,5 @@
+ build
+ numpy
+-parameterized
+ protobuf
+ pytest
+ pytest-cov
+-- 
+2.54.0
+

diff --git a/0003-Add-fixes-for-use-with-onnxruntime.patch b/0003-Add-fixes-for-use-with-onnxruntime.patch
deleted file mode 100644
index 41bc68e..0000000
--- a/0003-Add-fixes-for-use-with-onnxruntime.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 9809f77792517d0ace2874a84a181e8fe3766d8d Mon Sep 17 00:00:00 2001
-From: Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com>
-Date: Sat, 24 Feb 2024 14:53:33 +0100
-Subject: [PATCH 4/4] Add fixes for use with onnxruntime
-
----
- onnx/defs/schema.cc    | 14 ++++++++++++++
- onnx/onnxruntime_fix.h | 14 ++++++++++++++
- 2 files changed, 28 insertions(+)
- create mode 100644 onnx/onnxruntime_fix.h
-
-diff --git a/onnx/defs/schema.cc b/onnx/defs/schema.cc
-index 74bd0a630..573d09018 100644
---- a/onnx/defs/schema.cc
-+++ b/onnx/defs/schema.cc
-@@ -21,8 +21,19 @@
- 
- #include "onnx/common/assertions.h"
- #include "onnx/defs/parser.h"
-+#include "onnx/onnxruntime_fix.h"
- 
- namespace ONNX_NAMESPACE {
-+
-+bool ONNXRuntimeFix::_static_registration_disabled = false;
-+bool ONNXRuntimeFix::isStaticRegistrationDisabled() {
-+  return _static_registration_disabled;
-+}
-+
-+void ONNXRuntimeFix::disableStaticRegistration() {
-+  _static_registration_disabled = true;
-+}
-+
- // -1 means ONNX schema hasn't been loaded yet
- // 0 means all versions of ONNX schema have been loaded
- // Other positive integer means the ONNX schemas for the specified version have been loaded
-@@ -1091,6 +1102,9 @@ OpName_Domain_Version_Schema_Map& OpSchemaRegistry::map() {
-   class SchemasRegisterer {
-    public:
-     SchemasRegisterer() {
-+      // Check if static registration is actually disabled
-+      if(ONNXRuntimeFix::isStaticRegistrationDisabled()) return;
-+
-       // In debug builds, the number of schema registered in this constructor
-       // is compared against the number of calls to schema registration macros.
- #ifndef NDEBUG
-diff --git a/onnx/onnxruntime_fix.h b/onnx/onnxruntime_fix.h
-new file mode 100644
-index 000000000..2495b9310
---- /dev/null
-+++ b/onnx/onnxruntime_fix.h
-@@ -0,0 +1,14 @@
-+#pragma once
-+
-+namespace ONNX_NAMESPACE {
-+
-+class ONNXRuntimeFix {
-+public:
-+  static bool isStaticRegistrationDisabled();
-+  static void disableStaticRegistration();
-+
-+private:
-+  static bool _static_registration_disabled;
-+};
-+
-+} // namespace ONNX_NAMESPACE
--- 
-2.52.0
-

diff --git a/0004-Remove-python-parameterized-dependency.patch b/0004-Remove-python-parameterized-dependency.patch
deleted file mode 100644
index 40e2c85..0000000
--- a/0004-Remove-python-parameterized-dependency.patch
+++ /dev/null
@@ -1,5681 +0,0 @@
-From 31560ea9f50d6ccb816e5fef537ba3e477201aa1 Mon Sep 17 00:00:00 2001
-From: Diego Herrera <dherrera@fedoraproject.org>
-Date: Thu, 15 Jan 2026 17:32:58 -0300
-Subject: [PATCH 4/4] Remove python-parameterized dependency
-
----
- onnx/test/basic_test.py                       |   92 -
- onnx/test/helper_test.py                      |  100 -
- onnx/test/numpy_helper_test.py                |   63 -
- onnx/test/parser_test.py                      |  182 --
- onnx/test/reference_evaluator_ml_test.py      |  130 -
- onnx/test/reference_evaluator_test.py         |  771 -----
- onnx/test/schema_test.py                      |  194 --
- onnx/test/shape_inference_test.py             | 2589 +----------------
- onnx/test/test_backend_reference.py           |    9 +
- onnx/test/test_external_data.py               |  627 ----
- onnx/test/tools_test.py                       |  117 -
- .../automatic_downgrade_test.py               |   30 -
- onnx/test/version_converter_test.py           |  164 --
- requirements-dev.txt                          |    1 -
- requirements-release.txt                      |    1 -
- requirements.txt                              |    1 -
- 16 files changed, 130 insertions(+), 4941 deletions(-)
-
-diff --git a/onnx/test/basic_test.py b/onnx/test/basic_test.py
-index 3de8a91d6..ca5719ba6 100644
---- a/onnx/test/basic_test.py
-+++ b/onnx/test/basic_test.py
-@@ -11,7 +11,6 @@ import unittest
- 
- import google.protobuf.message
- import google.protobuf.text_format
--import parameterized
- 
- import onnx
- from onnx import serialization
-@@ -35,97 +34,6 @@ def _simple_tensor() -> onnx.TensorProto:
-     return tensor
- 
- 
--@parameterized.parameterized_class(
--    [
--        {"format": "protobuf"},
--        {"format": "textproto"},
--        {"format": "json"},
--        {"format": "onnxtxt"},
--    ]
--)
--class TestIO(unittest.TestCase):
--    format: str
--
--    def test_load_model_when_input_is_bytes(self) -> None:
--        proto = _simple_model()
--        proto_string = serialization.registry.get(self.format).serialize_proto(proto)
--        loaded_proto = onnx.load_model_from_string(proto_string, format=self.format)
--        self.assertEqual(proto, loaded_proto)
--
--    def test_save_and_load_model_when_input_has_read_function(self) -> None:
--        proto = _simple_model()
--        # When the proto is a bytes representation provided to `save_model`,
--        # it should always be a serialized binary protobuf representation. Aka. format="protobuf"
--        # The saved file format is specified by the `format` argument.
--        proto_string = serialization.registry.get("protobuf").serialize_proto(proto)
--        f = io.BytesIO()
--        onnx.save_model(proto_string, f, format=self.format)
--        loaded_proto = onnx.load_model(io.BytesIO(f.getvalue()), format=self.format)
--        self.assertEqual(proto, loaded_proto)
--
--    def test_save_and_load_model_when_input_is_file_name(self) -> None:
--        proto = _simple_model()
--        with tempfile.TemporaryDirectory() as temp_dir:
--            model_path = os.path.join(temp_dir, "model.onnx")
--            onnx.save_model(proto, model_path, format=self.format)
--            loaded_proto = onnx.load_model(model_path, format=self.format)
--            self.assertEqual(proto, loaded_proto)
--
--    def test_save_and_load_model_when_input_is_pathlike(self) -> None:
--        proto = _simple_model()
--        with tempfile.TemporaryDirectory() as temp_dir:
--            model_path = pathlib.Path(temp_dir, "model.onnx")
--            onnx.save_model(proto, model_path, format=self.format)
--            loaded_proto = onnx.load_model(model_path, format=self.format)
--            self.assertEqual(proto, loaded_proto)
--
--
--@parameterized.parameterized_class(
--    [
--        {"format": "protobuf"},
--        {"format": "textproto"},
--        {"format": "json"},
--        # The onnxtxt format does not support saving/loading tensors yet
--    ]
--)
--class TestIOTensor(unittest.TestCase):
--    """Test loading and saving of TensorProto."""
--
--    format: str
--
--    def test_load_tensor_when_input_is_bytes(self) -> None:
--        proto = _simple_tensor()
--        proto_string = serialization.registry.get(self.format).serialize_proto(proto)
--        loaded_proto = onnx.load_tensor_from_string(proto_string, format=self.format)
--        self.assertEqual(proto, loaded_proto)
--
--    def test_save_and_load_tensor_when_input_has_read_function(self) -> None:
--        # Test if input has a read function
--        proto = _simple_tensor()
--        f = io.BytesIO()
--        onnx.save_tensor(proto, f, format=self.format)
--        loaded_proto = onnx.load_tensor(io.BytesIO(f.getvalue()), format=self.format)
--        self.assertEqual(proto, loaded_proto)
--
--    def test_save_and_load_tensor_when_input_is_file_name(self) -> None:
--        # Test if input is a file name
--        proto = _simple_tensor()
--        with tempfile.TemporaryDirectory() as temp_dir:
--            model_path = os.path.join(temp_dir, "model.onnx")
--            onnx.save_tensor(proto, model_path, format=self.format)
--            loaded_proto = onnx.load_tensor(model_path, format=self.format)
--            self.assertEqual(proto, loaded_proto)
--
--    def test_save_and_load_tensor_when_input_is_pathlike(self) -> None:
--        # Test if input is a file name
--        proto = _simple_tensor()
--        with tempfile.TemporaryDirectory() as temp_dir:
--            model_path = pathlib.Path(temp_dir, "model.onnx")
--            onnx.save_tensor(proto, model_path, format=self.format)
--            loaded_proto = onnx.load_tensor(model_path, format=self.format)
--            self.assertEqual(proto, loaded_proto)
--
--
- class TestSaveAndLoadFileExtensions(unittest.TestCase):
-     def test_save_model_picks_correct_format_from_extension(self) -> None:
-         proto = _simple_model()
-diff --git a/onnx/test/helper_test.py b/onnx/test/helper_test.py
-index 2b38e52c7..ecb3d34e7 100644
---- a/onnx/test/helper_test.py
-+++ b/onnx/test/helper_test.py
-@@ -11,7 +11,6 @@ import unittest
- from typing import Any
- 
- import numpy as np
--import parameterized
- import pytest
- import version_utils
- 
-@@ -656,83 +655,6 @@ class TestHelperTensorFunctions(unittest.TestCase):
-         ynp = numpy_helper.to_array(y)
-         np.testing.assert_equal(Cast.eval(expected, to=TensorProto.FLOAT8E5M2FNUZ), ynp)  # type: ignore[arg-type]
- 
--    @parameterized.parameterized.expand(
--        itertools.product(
--            (TensorProto.UINT4, TensorProto.INT4),
--            ((5, 4, 6), (4, 6, 5), (3, 3), (1,), (2**10,)),
--        )
--    )
--    @unittest.skipIf(
--        version_utils.numpy_older_than("1.22.0"),
--        "The test requires numpy 1.22.0 or later",
--    )
--    def test_make_4bit_tensor(self, dtype, dims) -> None:
--        type_range = {
--            TensorProto.UINT4: (0, 15),
--            TensorProto.INT4: (-8, 7),
--        }
--        data = np.random.randint(
--            type_range[dtype][0], high=type_range[dtype][1] + 1, size=dims
--        )
--        y = helper.make_tensor("y", dtype, data.shape, data)
--
--        # Check the expected size of int32_data in bytes
--        expected_data_size = math.ceil(np.prod(data.shape) / 2.0)
--        actual_data_size = len(bytes(y.int32_data))
--        np.testing.assert_equal(actual_data_size, expected_data_size)
--
--        # Check the expected data values.
--        ynp = to_array_extended(y)
--        np.testing.assert_equal(data, ynp)
--
--    @parameterized.parameterized.expand(
--        itertools.product(
--            ((5, 4, 6), (4, 6, 5), (3, 3), (1,), (2**10,)),
--        )
--    )
--    @unittest.skipIf(
--        version_utils.numpy_older_than("1.22.0"),
--        "The test requires numpy 1.22.0 or later",
--    )
--    def test_4bit_tensor_size(self, dims) -> None:
--        # A bug caused negative int4 values to inflate tensor size.
--        # So, test negative values here.
--        num_elems = np.prod(dims)
--        data = np.array([-4] * num_elems, dtype=np.int8).reshape(dims)
--        y = helper.make_tensor("y", TensorProto.INT4, data.shape, data)
--
--        # Check the expected size of int32_data in bytes
--        expected_data_size = math.ceil(num_elems / 2.0)
--        actual_data_size = len(bytes(y.int32_data))
--        np.testing.assert_equal(actual_data_size, expected_data_size)
--
--    @parameterized.parameterized.expand(
--        itertools.product(
--            (TensorProto.UINT4, TensorProto.INT4), ((5, 4, 6), (4, 6, 5), (3, 3), (1,))
--        )
--    )
--    @unittest.skipIf(
--        version_utils.numpy_older_than("1.26.0"),
--        "The test requires numpy 1.26.0 or later",
--    )
--    def test_make_4bit_raw_tensor(self, dtype, dims) -> None:
--        type_range = {
--            TensorProto.UINT4: (0, 15),
--            TensorProto.INT4: (-8, 7),
--        }
--        data = np.random.randint(
--            type_range[dtype][0], high=type_range[dtype][1] + 1, size=dims
--        ).astype(np.float32)
--        packed_data = helper.pack_float32_to_4bit(
--            data, signed=(dtype == TensorProto.INT4)
--        )
--
--        y = helper.make_tensor(
--            "packed_int4", dtype, dims, packed_data.tobytes(), raw=True
--        )
--        ynp = numpy_helper.to_array(y)
--        np.testing.assert_equal(data, ynp)
--
-     def test_make_sparse_tensor(self) -> None:
-         values = [1.1, 2.2, 3.3, 4.4, 5.5]
-         values_tensor = helper.make_tensor(
-@@ -1018,28 +940,6 @@ class TestHelperMappingFunctions(unittest.TestCase):
- 
- 
- class TestAttrTypeToStr(unittest.TestCase):
--    @parameterized.parameterized.expand(
--        [
--            (AttributeProto.AttributeType.FLOAT, "FLOAT"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.INT, "INT"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.STRING, "STRING"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.TENSOR, "TENSOR"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.GRAPH, "GRAPH"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.SPARSE_TENSOR, "SPARSE_TENSOR"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.TYPE_PROTO, "TYPE_PROTO"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.FLOATS, "FLOATS"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.INTS, "INTS"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.STRINGS, "STRINGS"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.TENSORS, "TENSORS"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.GRAPHS, "GRAPHS"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.SPARSE_TENSORS, "SPARSE_TENSORS"),  # type: ignore[attr-defined]
--            (AttributeProto.AttributeType.TYPE_PROTOS, "TYPE_PROTOS"),  # type: ignore[attr-defined]
--        ]
--    )
--    def test_attr_type_to_str(self, attr_type, expected_str):
--        result = helper._attr_type_to_str(attr_type)
--        self.assertEqual(result, expected_str)
--
-     def test_attr_type_to_str_undefined(self):
-         result = helper._attr_type_to_str(9999)
-         self.assertEqual(result, "UNDEFINED")
-diff --git a/onnx/test/numpy_helper_test.py b/onnx/test/numpy_helper_test.py
-index f642cc87f..621a8b8a2 100644
---- a/onnx/test/numpy_helper_test.py
-+++ b/onnx/test/numpy_helper_test.py
-@@ -7,7 +7,6 @@ import unittest
- from typing import Any
- 
- import numpy as np
--import parameterized
- 
- import onnx
- import onnx.reference
-@@ -147,29 +146,6 @@ class TestNumpyHelper(unittest.TestCase):
-     def test_complex128(self) -> None:
-         self._test_numpy_helper_float_type(np.complex128)
- 
--    @parameterized.parameterized.expand(
--        [
--            (1,),
--            (0.100097656,),
--            (130048,),
--            (1.2993813e-5,),
--            (np.nan,),
--            (np.inf,),
--        ]
--    )
--    def test_bfloat16_to_float32(self, f):
--        f32 = np.float32(f)
--        bf16 = helper.float32_to_bfloat16(f32)
--        assert isinstance(bf16, int)
--        f32_1 = numpy_helper.bfloat16_to_float32(np.array([bf16]))[0]
--        f32_2 = bfloat16_to_float32(bf16)
--        if np.isnan(f32):
--            assert np.isnan(f32_1)
--            assert np.isnan(f32_2)
--        else:
--            self.assertEqual(f32, f32_1)
--            self.assertEqual(f32, f32_2)
--
-     def test_float8e4m3_to_float32(self):
-         self.assertEqual(numpy_helper.float8e4m3_to_float32(int("1111110", 2)), 448)
-         self.assertEqual(numpy_helper.float8e4m3_to_float32(int("1000", 2)), 2 ** (-6))
-@@ -208,26 +184,6 @@ class TestNumpyHelper(unittest.TestCase):
-                     self.assertEqual(f32, f32_1)
-                     self.assertEqual(f32, f32_2)
- 
--    @parameterized.parameterized.expand(
--        [
--            (0.00439453125, 0.00390625),
--            (0.005859375, 0.005859375),
--            (0.005759375, 0.005859375),
--            (0.0046875, 0.00390625),
--            (0.001953125, 0.001953125),
--            (0.0029296875, 0.00390625),
--            (0.002053125, 0.001953125),
--            (0.00234375, 0.001953125),
--            (0.0087890625, 0.0078125),
--            (0.001171875, 0.001953125),
--            (1.8131605, 1.875),
--        ]
--    )
--    def test_float8e4m3_to_float32_round(self, val, expected):
--        f8 = helper.float32_to_float8e4m3(val)
--        f32 = numpy_helper.float8e4m3_to_float32(f8)
--        self.assertEqual(f32, expected)
--
-     def test_float8e5m2_to_float32(self):
-         self.assertEqual(numpy_helper.float8e5m2_to_float32(int("1111011", 2)), 57344)
-         self.assertEqual(numpy_helper.float8e5m2_to_float32(int("100", 2)), 2 ** (-14))
-@@ -625,25 +581,6 @@ class TestNumpyHelper(unittest.TestCase):
-         self.assertEqual(tp.SerializeToString(), again.SerializeToString())
-         self.assertEqual(tp.data_type, helper.np_dtype_to_tensor_dtype(back.dtype))
- 
--    @parameterized.parameterized.expand([(att,) for att in dir(onnx.TensorProto)])
--    def test_to_array_from_array(self, att):
--        if att in {
--            "INT4",
--            "UINT4",
--            "STRING",
--            "UNDEFINED",
--            "DEFAULT",
--            "NAME_FIELD_NUMBER",
--        }:
--            return
--        if att[0] < "A" or att[0] > "Z":
--            return
--        value = getattr(onnx.TensorProto, att)
--        if not isinstance(value, int):
--            return
--
--        self._to_array_from_array(value)
--
-     def test_to_array_from_array_subtype(self):
-         self._to_array_from_array(onnx.TensorProto.INT4)
-         self._to_array_from_array(onnx.TensorProto.UINT4)
-diff --git a/onnx/test/parser_test.py b/onnx/test/parser_test.py
-index c117d379b..967d29390 100644
---- a/onnx/test/parser_test.py
-+++ b/onnx/test/parser_test.py
-@@ -5,8 +5,6 @@ from __future__ import annotations
- 
- import unittest
- 
--from parameterized import parameterized
--
- import onnx
- from onnx import GraphProto, OperatorSetIdProto, TensorProto, checker
- 
-@@ -120,94 +118,6 @@ class TestBasicFunctions(unittest.TestCase):
-         model = onnx.parser.parse_model(input)
-         checker.check_model(model)
- 
--    @parameterized.expand(
--        [
--            (
--                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu(x) }",
--                {},
--            ),
--            (
--                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu<alpha=2.0>(x) }",
--                {"alpha": 2.0},
--            ),
--            (
--                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu<gamma=3.0>(x) }",
--                {"gamma": 3.0},
--            ),
--            (
--                "agraph (float[N] x) => (float[N] out) { out = custom_domain.Selu<alpha=2.0, gamma=3.0>(x) }",
--                {"alpha": 2.0, "gamma": 3.0},
--            ),
--        ]
--    )
--    def test_composite_parse_function_with_attributes(
--        self, graph_text: str, expected_attribute: dict
--    ) -> None:
--        default_alpha = 1.67326319217681884765625
--        default_gamma = 1.05070102214813232421875
--
--        def expect_custom_node_attribute(node, attributes):
--            for key in attributes:
--                match_attr = [attr for attr in node.attribute if attr.name == key]
--                assert len(match_attr) == 1
--                assert match_attr[0].f == attributes[key]
--
--        def expect_model_function_attribute(model):
--            assert len(model.functions[0].attribute_proto) == 2
--            attr_proto_alpha = [
--                attr_proto
--                for attr_proto in model.functions[0].attribute_proto
--                if attr_proto.name == "alpha"
--            ]
--            assert len(attr_proto_alpha) == 1 and attr_proto_alpha[0].f == default_alpha
--            attr_proto_gamma = [
--                attr_proto
--                for attr_proto in model.functions[0].attribute_proto
--                if attr_proto.name == "gamma"
--            ]
--            assert len(attr_proto_gamma) == 1 and attr_proto_gamma[0].f == default_gamma
--
--        function_text = f"""
--         <
--         domain: "custom_domain",
--         opset_import: [ "" : 15],
--         doc_string: "Test function proto"
--         >
--           Selu
--           <alpha: float={default_alpha}, gamma: float={default_gamma}>
--           (X) => (C)
--           {{
--               constant_alpha = Constant<value_float: float=@alpha>()
--               constant_gamma = Constant<value_float: float=@gamma>()
--               alpha_x = CastLike(constant_alpha, X)
--               gamma_x = CastLike(constant_gamma, X)
--               exp_x = Exp(X)
--               alpha_x_exp_x = Mul(alpha_x, exp_x)
--               alpha_x_exp_x_ = Sub(alpha_x_exp_x, alpha_x)
--               neg = Mul(gamma_x, alpha_x_exp_x_)
--               pos = Mul(gamma_x, X)
--               _zero = Constant<value_float=0.0>()
--               zero = CastLike(_zero, X)
--               less_eq = LessOrEqual(X, zero)
--               C = Where(less_eq, neg, pos)
--           }}
--        """
--
--        functions = [onnx.parser.parse_function(function_text)]
--        graph = onnx.parser.parse_graph(graph_text)
--        opset_imports = [
--            OperatorSetIdProto(domain="", version=15),
--            OperatorSetIdProto(domain="custom_domain", version=1),
--        ]
--
--        model = onnx.helper.make_model(
--            graph, functions=functions, opset_imports=opset_imports
--        )
--        checker.check_model(model)
--
--        expect_model_function_attribute(model)
--        expect_custom_node_attribute(model.graph.node[0], expected_attribute)
--
-     def test_parse_node(self):
-         node = onnx.parser.parse_node(
-             "out1, out2 = SomeDomain.SomeOp <attr1 = 1> (in1, in2)"
-@@ -220,98 +130,6 @@ class TestBasicFunctions(unittest.TestCase):
-         self.assertEqual(node.domain, "SomeDomain")
-         self.assertEqual(node.op_type, "SomeOp")
- 
--    @parameterized.expand(
--        [
--            ("not_a_good_float", True),
--            ("inf1", True),
--            ("-inf1", True),
--            ("nan0", True),
--            ("-nan0", True),
--            ("naninf", True),
--            ("inf", False),
--            ("-inf", False),
--            ("infinity", False),
--            ("-infinity", False),
--            ("nan", False),
--            ("-NaN", False),
--        ]
--    )
--    def test_parse_various_float_values(self, test_literal, expect_exception):
--        model_text = f"""
--        <
--        ir_version: 8,
--        opset_import: ["" : 18, "this" : 1],
--        producer_name: "FunctionProtoTest",
--        producer_version: "1.0"
--        >
--        _func () => ()
--        {{
--        tmp = Constant <value_float = {test_literal}>()
--        }}
--        """
--        if expect_exception:
--            self.assertRaises(
--                onnx.parser.ParseError, lambda: onnx.parser.parse_model(model_text)
--            )
--        else:
--            model = onnx.parser.parse_model(model_text)
--            self.assertEqual(model.ir_version, 8)
--            self.assertEqual(model.producer_name, "FunctionProtoTest")
--            self.assertEqual(model.producer_version, "1.0")
--            self.assertEqual(len(model.graph.node), 1)
--            self.assertEqual(len(model.graph.node[0].attribute), 1)
--            self.assertEqual(model.graph.node[0].attribute[0].name, "value_float")
--            self.assertEqual(
--                model.graph.node[0].attribute[0].type, onnx.AttributeProto.FLOAT
--            )
--            self.assertEqual(
--                str(model.graph.node[0].attribute[0].f), str(float(test_literal))
--            )
--
--    @parameterized.expand(
--        [
--            ("bfloat16", TensorProto.BFLOAT16),
--            ("bool", TensorProto.BOOL),
--            ("complex64", TensorProto.COMPLEX64),
--            ("complex128", TensorProto.COMPLEX128),
--            ("double", TensorProto.DOUBLE),
--            ("float16", TensorProto.FLOAT16),
--            ("float", TensorProto.FLOAT),
--            ("float8e4m3fn", TensorProto.FLOAT8E4M3FN),
--            ("float8e4m3fnuz", TensorProto.FLOAT8E4M3FNUZ),
--            ("float8e5m2", TensorProto.FLOAT8E5M2),
--            ("float8e5m2fnuz", TensorProto.FLOAT8E5M2FNUZ),
--            ("int4", TensorProto.INT4),
--            ("int8", TensorProto.INT8),
--            ("int16", TensorProto.INT16),
--            ("int32", TensorProto.INT32),
--            ("int64", TensorProto.INT64),
--            ("string", TensorProto.STRING),
--            ("uint4", TensorProto.UINT4),
--            ("uint8", TensorProto.UINT8),
--            ("uint16", TensorProto.UINT16),
--            ("uint32", TensorProto.UINT32),
--            ("uint64", TensorProto.UINT64),
--        ]
--    )
--    def test_parse_graph_types(self, name, itype) -> None:
--        w = '{"0"}' if itype == TensorProto.STRING else "{0}"
--        text_graph = f"""
--           <
--             ir_version: 10,
--             opset_import: [ "" : 19]
--           >
--           agraph (float[N] X) => ({name}[N] C)
--           <
--             {name}[1] weight = {w}
--           >
--           {{
--              C = Cast<to={itype}>(X)
--           }}
--           """
--        graph = onnx.parser.parse_model(text_graph)
--        self.assertEqual(len(graph.graph.node), 1)
--
- 
- if __name__ == "__main__":
-     unittest.main(verbosity=2)
-diff --git a/onnx/test/reference_evaluator_ml_test.py b/onnx/test/reference_evaluator_ml_test.py
-index 3b05da303..10058f9e7 100644
---- a/onnx/test/reference_evaluator_ml_test.py
-+++ b/onnx/test/reference_evaluator_ml_test.py
-@@ -11,7 +11,6 @@ from os import getenv
- 
- import numpy as np  # type: ignore
- from numpy.testing import assert_allclose  # type: ignore
--from parameterized import parameterized
- 
- import onnx
- from onnx import ONNX_ML, TensorProto, TypeProto, ValueInfoProto
-@@ -907,118 +906,6 @@ class TestReferenceEvaluatorAiOnnxMl(unittest.TestCase):
-         check_model(onx)
-         return onx
- 
--    @parameterized.expand(
--        tuple(
--            itertools.chain.from_iterable(
--                (
--                    (
--                        AggregationFunction.SUM if opset5 else "SUM",
--                        np.array(
--                            [[0.576923], [0.576923], [0.576923]], dtype=np.float32
--                        ),
--                        opset5,
--                    ),
--                    (
--                        AggregationFunction.AVERAGE if opset5 else "AVERAGE",
--                        np.array(
--                            [[0.288462], [0.288462], [0.288462]], dtype=np.float32
--                        ),
--                        opset5,
--                    ),
--                    (
--                        AggregationFunction.MIN if opset5 else "MIN",
--                        np.array(
--                            [[0.076923], [0.076923], [0.076923]], dtype=np.float32
--                        ),
--                        opset5,
--                    ),
--                    (
--                        AggregationFunction.MAX if opset5 else "MAX",
--                        np.array([[0.5], [0.5], [0.5]], dtype=np.float32),
--                        opset5,
--                    ),
--                )
--                for opset5 in [True, False]
--            )
--        )
--    )
--    @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
--    def test_tree_ensemble_regressor_aggregation_functions(
--        self, aggregate_function, expected_result, opset5
--    ):
--        x = np.arange(9).reshape((-1, 3)).astype(np.float32) / 10 - 0.5
--        model_factory = (
--            self._get_test_tree_ensemble_opset_latest
--            if opset5
--            else self._get_test_tree_ensemble_regressor
--        )
--        model_proto = model_factory(
--            aggregate_function,
--        )
--        sess = ReferenceEvaluator(model_proto)
--        (actual,) = sess.run(None, {"X": x})
--        assert_allclose(expected_result, actual, atol=1e-6)
--
--    @parameterized.expand(
--        tuple(
--            itertools.chain.from_iterable(
--                (
--                    (
--                        Mode.LEQ if opset5 else "BRANCH_LEQ",
--                        np.array(
--                            [[0.576923], [0.576923], [0.576923]], dtype=np.float32
--                        ),
--                        opset5,
--                    ),
--                    (
--                        Mode.GT if opset5 else "BRANCH_GT",
--                        np.array([[0.5], [0.5], [0.5]], dtype=np.float32),
--                        opset5,
--                    ),
--                    (
--                        Mode.LT if opset5 else "BRANCH_LT",
--                        np.array(
--                            [[0.576923], [0.576923], [0.576923]], dtype=np.float32
--                        ),
--                        opset5,
--                    ),
--                    (
--                        Mode.GTE if opset5 else "BRANCH_GTE",
--                        np.array([[0.5], [0.5], [0.5]], dtype=np.float32),
--                        opset5,
--                    ),
--                    (
--                        Mode.EQ if opset5 else "BRANCH_EQ",
--                        np.array([[1.0], [1.0], [1.0]], dtype=np.float32),
--                        opset5,
--                    ),
--                    (
--                        Mode.NEQ if opset5 else "BRANCH_NEQ",
--                        np.array(
--                            [[0.076923], [0.076923], [0.076923]], dtype=np.float32
--                        ),
--                        opset5,
--                    ),
--                )
--                for opset5 in [True, False]
--            )
--        )
--    )
--    @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
--    def test_tree_ensemble_regressor_rule(self, rule, expected, opset5):
--        x = np.arange(9).reshape((-1, 3)).astype(np.float32) / 10 - 0.5
--        model_factory = (
--            self._get_test_tree_ensemble_opset_latest
--            if opset5
--            else self._get_test_tree_ensemble_regressor
--        )
--        aggregate_function = AggregationFunction.SUM if opset5 else "SUM"
--
--        model_proto = model_factory(aggregate_function, rule)
--        sess = ReferenceEvaluator(model_proto)
--        (actual,) = sess.run(None, {"X": x})
--        assert_allclose(expected, actual, atol=1e-6)
--
-     @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
-     def test_tree_ensemble_regressor_2_targets_opset3(self):
-         X = make_tensor_value_info("X", TensorProto.FLOAT, [None, None])
-@@ -1132,23 +1019,6 @@ class TestReferenceEvaluatorAiOnnxMl(unittest.TestCase):
-         assert_allclose(expected, got[0], atol=1e-6)
-         self.assertIn("op_type=TreeEnsembleRegressor", str(sess.rt_nodes_[0]))
- 
--    @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
--    @parameterized.expand(
--        [(input_type,) for input_type in [TensorProto.FLOAT, TensorProto.DOUBLE]]
--    )
--    def test_tree_ensemble_missing_opset5(self, input_type):
--        model = self._get_test_tree_ensemble_opset_latest(
--            AggregationFunction.SUM, Mode.LEQ, True, input_type
--        )
--        np_dtype = onnx.helper.tensor_dtype_to_np_dtype(input_type)
--        x = np.arange(9).reshape((-1, 3)).astype(np_dtype) / 10 - 0.5
--        x[2, 0] = 5
--        x[1, :] = np.nan
--        expected = np.array([[100001.0], [100100.0], [100100.0]], dtype=np_dtype)
--        session = ReferenceEvaluator(model)
--        (actual,) = session.run(None, {"X": x})
--        assert_allclose(expected, actual, atol=1e-6)
--
-     @unittest.skipIf(not ONNX_ML, reason="onnx not compiled with ai.onnx.ml")
-     def test_tree_ensemble_regressor_missing_opset5_float16(self):
-         model = self._get_test_tree_ensemble_opset_latest(
-diff --git a/onnx/test/reference_evaluator_test.py b/onnx/test/reference_evaluator_test.py
-index c805e1d7b..42a2fbeae 100644
---- a/onnx/test/reference_evaluator_test.py
-+++ b/onnx/test/reference_evaluator_test.py
-@@ -24,7 +24,6 @@ from textwrap import dedent
- from typing import Sequence
- 
- import numpy as np
--import parameterized
- import version_utils
- from numpy.testing import assert_allclose, assert_almost_equal
- 
-@@ -2962,163 +2961,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-         onnx_model = make_model(graph, opset_imports=[make_opsetid("", opset)])
-         return onnx_model
- 
--    @parameterized.parameterized.expand(
--        itertools.product(
--            [
--                (
--                    "ReduceMin",
--                    [
--                        np.array(
--                            [[np.nan, np.nan], [14.422706, 18.80527]], dtype=np.float32
--                        ),
--                        np.array([[2, 15], [10, 4]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceL1",
--                    [
--                        np.array(
--                            [[2.2367053, 2.3516612], [4.076292, 4.2970634]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[18, 6], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceL2",
--                    [
--                        np.array(
--                            [[1.80155, 1.8169948], [2.9928076, 3.1205883]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[11, 18], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceLogSum",
--                    [
--                        np.array(
--                            [[0.9497848, 1.1872643], [1.6764175, 1.70759]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[6, 18], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceLogSumExp",
--                    [
--                        np.array(
--                            [[1.6005973, 1.7445935], [2.5616229, 2.6539795]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[13, 6], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceMax",
--                    [
--                        np.array(
--                            [[1.4217108, 1.5069536], [2.453826, 2.5041783]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[13, 11], [13, 11]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceMean",
--                    [
--                        np.array(
--                            [[0.39247903, 0.78497636], [2.038146, 2.1485317]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[13, 6], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceSumSquare",
--                    [
--                        np.array(
--                            [[3.2455828, 3.3014696], [8.956896, 9.7380705]],
--                            dtype=np.float32,
--                        ),
--                        np.array([[11, 18], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--                (
--                    "ReduceProd",
--                    [
--                        np.array(
--                            [[np.nan, np.nan], [14.422706, 18.80527]], dtype=np.float32
--                        ),
--                        np.array([[2, 15], [13, 6]], dtype=np.int64),
--                    ],
--                ),
--            ],
--            [17, 18],
--        )
--    )
--    def test_op_reduce(self, reduce_op_expected, opset: int):
--        reduce_op, expected = reduce_op_expected
--        X = np.arange(8).reshape((-1, 4)).astype(np.float32)
--
--        results = {}
--
--        model = self._cdist_model(opset, reduce_op)
--        sess = ReferenceEvaluator(model)
--        got = sess.run(None, {"input": X})
--        results["ref", opset] = got
--
--        cl = [
--            n
--            for n in sess.rt_nodes_[0].body.rt_nodes_
--            if n.__class__.__name__.startswith(reduce_op)
--        ]
--        schema = cl[0]._schema
--        new_cl = type(reduce_op, (cl[0].__class__,), {"op_schema": schema})
--        sess = ReferenceEvaluator(model, new_ops=[new_cl])
--        got = sess.run(None, {"input": X})
--        results["ref_cl", opset] = got
--
--        baseline = "constant"
--        for k, v in results.items():
--            for a, b in zip(reversed(expected), reversed(v)):
--                if a.shape != b.shape:
--                    raise AssertionError(
--                        f"Shape mismatch for {reduce_op!r}, {baseline}:{a.shape} != {k}:{b.shape}."
--                    )
--                diff = np.abs(a - b).max()
--                if diff > 1e-6:
--                    raise AssertionError(
--                        f"Discrepancies (max={diff}) for {reduce_op!r}, {baseline} != {k}\n{a}\n!=\n{b}"
--                    )
--
--    @parameterized.parameterized.expand(
--        [
--            (13,),
--            (17,),
--            (18,),
--        ]
--    )
--    def test_mvn(self, opset: int, ref_opset: int = 13):
--        X = make_tensor_value_info("X", TensorProto.FLOAT, [None, None, None, None])
--        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None, None, None, None])
--        nodes = [
--            make_node("MeanVarianceNormalization", ["X"], ["Y"]),
--        ]
--        graph = make_graph(nodes, "g", [X], [Y])
--        x = np.random.rand(3, 3, 3, 1).astype(np.float32)
--
--        onnx_model = make_model(graph, opset_imports=[make_opsetid("", opset)])
--        ref = ReferenceEvaluator(onnx_model)
--        got = ref.run(None, {"X": x})[0]
--
--        ref_onnx_model = make_model(graph, opset_imports=[make_opsetid("", ref_opset)])
--        ref_expected = ReferenceEvaluator(ref_onnx_model)
--        expected = ref_expected.run(None, {"X": x})[0]
--
--        self.assertEqual(expected.shape, got.shape)
--        assert_allclose(expected, got)
--
-     def test_concat_in_a_function(self):
-         def create_model():
-             nodes = []
-@@ -3800,211 +3642,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-         got = ref.run(None, {"X": data})
-         assert_allclose(expected, got[0])
- 
--    @parameterized.parameterized.expand(
--        [
--            (
--                4 * np.arange(12).reshape(3, 4),
--                np.arange(1, 7).reshape(3, 2),
--                np.zeros((3, 2)),
--                1,
--                2,
--                [[0, 4, 4, 6], [5, 7, 6, 7], [6, 7, 7, 7]],
--            ),
--            (
--                4 * np.arange(12).reshape(3, 4),
--                np.arange(1, 7).reshape(3, 2),
--                np.ones((3, 2)),
--                1,
--                2,
--                [[1, 5, 5, 7], [6, 8, 7, 8], [7, 8, 8, 8]],
--            ),
--            (
--                np.arange(24).reshape(3, 8),
--                [[0.25, 0.5, 1], [0.25, 0.5, 1], [0.25, 0.5, 1]],
--                np.zeros((3, 3)),
--                1,
--                3,
--                [
--                    [0, 4, 8, 6, 8, 10, 6, 7],
--                    [32, 36, 40, 22, 24, 26, 14, 15],
--                    [64, 68, 72, 38, 40, 42, 22, 23],
--                ],
--            ),
--            (
--                np.arange(6),
--                [0.25, 0.5],
--                [-1, -2],
--                0,
--                3,
--                [-1, 3, 7, 4, 6, 8],
--            ),
--            (
--                np.ones((9, 12)),
--                np.ones((3, 4)),
--                np.zeros((3, 4)),
--                0,
--                3,
--                None,  # Blocked quantization is defined for 1-D blocks only
--            ),
--            (
--                np.ones((3, 4, 5, 6)),
--                np.ones((3, 4)),
--                np.zeros((3, 4)),
--                2,
--                2,
--                None,  # Scale and ZP must have the same rank as the input
--            ),
--        ]
--    )
--    def test_blocked_quantize_linear(
--        self, x, scale, zero_point, axis, block_size, expected
--    ):
--        X = make_tensor_value_info("X", TensorProto.FLOAT, [None])
--        Y = make_tensor_value_info("Y", TensorProto.INT8, [None])
--
--        scale_data = np.array(scale, dtype=np.float32)
--        zp_data = np.array(zero_point, dtype=np.int8)
--        model = make_model(
--            make_graph(
--                [
--                    make_node(
--                        "QuantizeLinear",
--                        ["X", "scale", "zero"],
--                        ["Y"],
--                        axis=axis,
--                        block_size=block_size,
--                    ),
--                ],
--                "g",
--                [X],
--                [Y],
--                [
--                    make_tensor(
--                        "scale", TensorProto.FLOAT, scale_data.shape, scale_data
--                    ),
--                    make_tensor("zero", TensorProto.INT8, scale_data.shape, zp_data),
--                ],
--            )
--        )
--        ref = ReferenceEvaluator(model)
--
--        data = np.array(x, dtype=np.float32)
--
--        if expected is not None:
--            expected = np.array(expected, dtype=np.int8)
--            got = ref.run(None, {"X": data})
--            assert_allclose(expected, got[0])
--        else:
--            with self.assertRaises(ValueError):
--                ref.run(None, {"X": data})
--
--    @parameterized.parameterized.expand(
--        [
--            (
--                np.arange(12).reshape(3, 4),
--                np.arange(1, 7).reshape(3, 2),
--                np.zeros((3, 2)),
--                1,
--                2,
--                [[0, 1, 4, 6], [12, 15, 24, 28], [40, 45, 60, 66]],
--            ),
--            (
--                np.arange(12).reshape(3, 4),
--                np.arange(1, 7).reshape(3, 2),
--                np.ones((3, 2)),
--                1,
--                2,
--                [[-1, 0, 2, 4], [9, 12, 20, 24], [35, 40, 54, 60]],
--            ),
--            (
--                np.dstack([np.arange(4).reshape(2, 2)] * 4),
--                np.dstack([np.array([[1, 1], [2, 3]]), np.array([[4, 5], [6, 7]])]),
--                np.zeros((2, 2, 2)),
--                2,
--                2,
--                [[[0, 0, 0, 0], [1, 1, 5, 5]], [[4, 4, 12, 12], [9, 9, 21, 21]]],
--            ),
--            (
--                np.arange(24).reshape(3, 8),
--                [[2, 1, 3], [2, 1, 3], [2, 1, 3]],
--                np.zeros((3, 3)),
--                1,
--                3,
--                [
--                    [0, 2, 4, 3, 4, 5, 18, 21],
--                    [16, 18, 20, 11, 12, 13, 42, 45],
--                    [32, 34, 36, 19, 20, 21, 66, 69],
--                ],
--            ),
--            (
--                np.arange(
--                    6,
--                ),
--                [2, 3],
--                [1, 2],
--                0,
--                3,
--                [-2, 0, 2, 3, 6, 9],
--            ),
--            (
--                np.ones((9, 12)),
--                np.ones((3, 4)),
--                np.zeros((3, 4)),
--                0,
--                3,
--                None,  # Blocked quantization is defined for 1-D blocks only
--            ),
--            (
--                np.ones((3, 4, 5, 6)),
--                np.ones((3, 4)),
--                np.zeros((3, 4)),
--                2,
--                2,
--                None,  # Scale and ZP must have the same rank as the input
--            ),
--        ]
--    )
--    def test_blocked_dequantize_linear(
--        self, x, scale, zero_point, axis, block_size, expected
--    ):
--        X = make_tensor_value_info("X", TensorProto.INT8, [None])
--        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None])
--
--        scale_data = np.array(scale, dtype=np.float32)
--        zp_data = np.array(zero_point, dtype=np.int8)
--        model = make_model(
--            make_graph(
--                [
--                    make_node(
--                        "DequantizeLinear",
--                        ["X", "scale", "zero"],
--                        ["Y"],
--                        axis=axis,
--                        block_size=block_size,
--                    ),
--                ],
--                "g",
--                [X],
--                [Y],
--                [
--                    make_tensor(
--                        "scale", TensorProto.FLOAT, scale_data.shape, scale_data
--                    ),
--                    make_tensor("zero", TensorProto.INT8, scale_data.shape, zp_data),
--                ],
--            )
--        )
--        ref = ReferenceEvaluator(model)
--        data = np.array(x, dtype=np.int8)
--
--        if expected is not None:
--            expected = np.array(expected, dtype=np.float32)
--            got = ref.run(None, {"X": data})
--            assert_allclose(expected, got[0])
--        else:
--            with self.assertRaises(ValueError):
--                ref.run(None, {"X": data})
--
-     def test_lrn(self):
-         def _expected(x, alpha, beta, bias, size):
-             square_sum = np.zeros((5, 5, 5, 5)).astype(np.float32)
-@@ -4189,52 +3826,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-         got = _conv_implementation_im2col(**feeds, **kwargs)
-         assert_allclose(expected, got)
- 
--    @parameterized.parameterized.expand(
--        [
--            ("ReduceSum",),
--            ("ReduceL1",),
--            ("ReduceL2",),
--            ("ReduceMin",),
--            ("ReduceMax",),
--            ("ReduceProd",),
--            ("ReduceSumSquare",),
--        ]
--    )
--    def test_reduce_op_no_axis(self, op):
--        X = make_tensor_value_info("X", TensorProto.FLOAT, None)
--        Y = make_tensor_value_info("Y", TensorProto.FLOAT, None)
--        data = np.arange(6).reshape((1, 3, 2)).astype(np.float32)
--        nodes = [make_node(op, ["X"], ["Y"], keepdims=0)]
--        model = make_model(make_graph(nodes, "g", [X], [Y]))
--        ref = ReferenceEvaluator(model)
--        got = ref.run(None, {"X": data})
--        r = got[0]
--        self.assertIsInstance(r, np.ndarray)
--        self.assertEqual(r.shape, ())
--
--    @parameterized.parameterized.expand([(1,), (2,), (3,), (4,), (5,), (6,)])
--    def test_pad(self, dim):
--        X = make_tensor_value_info("X", TensorProto.FLOAT, None)
--        P = make_tensor_value_info("P", TensorProto.INT64, None)
--        V = make_tensor_value_info("V", TensorProto.FLOAT, None)
--        Y = make_tensor_value_info("Y", TensorProto.FLOAT, None)
--        value = np.array([-5], dtype=np.float32)
--
--        node = make_node("Pad", inputs=["X", "P", "V"], outputs=["Y"], mode="constant")
--        model = make_model(make_graph([node], "g", [X, P, V], [Y]))
--        ref = ReferenceEvaluator(model)
--        x = np.array([1], dtype=np.float32).reshape((1,) * dim)
--
--        p = np.array([1, 1] * dim, dtype=np.int64)
--        got = ref.run(None, {"X": x, "P": p, "V": value})[0]
--        self.assertEqual(got.shape, (3,) * dim)
--        self.assertEqual(got.dtype, np.float32)
--
--        p = np.repeat([7, 3], dim).astype(np.int64)
--        got = ref.run(None, {"X": x, "P": p, "V": value})[0]
--        self.assertEqual(got.shape, (11,) * dim)
--        self.assertEqual(got.dtype, np.float32)
--
-     def test_constant_of_shape(self):
-         X = make_tensor_value_info("X", TensorProto.FLOAT, None)
-         Y = make_tensor_value_info("Y", TensorProto.FLOAT, None)
-@@ -5345,124 +4936,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-         for i in range(2, -1, -1):
-             assert_allclose(expected[i], got[i])
- 
--    @parameterized.parameterized.expand(
--        [
--            (["abc", "def"], [".com", ".net"], ["abc.com", "def.net"], (2,)),
--            (["cat", "dog", "snake"], ["s"], ["cats", "dogs", "snakes"], (3,)),
--            ("cat", "s", "cats", ()),
--            (["a", "ß", "y"], ["a", "ß", "y"], ["aa", "ßß", "yy"], (3,)),
--        ]
--    )
--    def test_string_concat(self, a, b, expected, expected_shape):
--        A = make_tensor_value_info("A", TensorProto.STRING, None)
--        B = make_tensor_value_info("B", TensorProto.STRING, None)
--        Y = make_tensor_value_info("Y", TensorProto.STRING, None)
--        node = make_node("StringConcat", inputs=["A", "B"], outputs=["Y"])
--        model = make_model(make_graph([node], "g", [A, B], [Y]))
--        ref = ReferenceEvaluator(model)
--        result, *_ = ref.run(None, {"A": np.array(a), "B": np.array(b)})
--        np.testing.assert_array_equal(result, expected)
--        self.assertIn(result.dtype.kind, {"O", "U"})
--        self.assertEqual(result.shape, expected_shape)
--
--    @parameterized.parameterized.expand(
--        [
--            (
--                ["1,2,3", "4,5,6"],
--                ",",
--                None,
--                [["1", "2", "3"], ["4", "5", "6"]],
--                [3, 3],
--            ),
--            (
--                ["1,", "4,6", ""],
--                ",",
--                None,
--                [["1", ""], ["4", "6"], ["", ""]],
--                [2, 2, 1],
--            ),
--            (
--                ["1", "4,6", "4,5,6"],
--                ",",
--                1,
--                [["1", ""], ["4", "6"], ["4", "5,6"]],
--                [1, 2, 2],
--            ),
--            (
--                [["1,", "4,6", "4,5,6"], ["1,", "4,6", "4,5,6"]],
--                ",",
--                None,
--                [
--                    [["1", "", ""], ["4", "6", ""], ["4", "5", "6"]],
--                    [["1", "", ""], ["4", "6", ""], ["4", "5", "6"]],
--                ],
--                [[2, 2, 3], [2, 2, 3]],
--            ),
--            (
--                ["hello world !", "  hello   world !", " hello world   ! "],
--                None,
--                None,
--                [
--                    ["hello", "world", "!"],
--                    ["hello", "world", "!"],
--                    ["hello", "world", "!"],
--                ],
--                [3, 3, 3],
--            ),
--            (
--                ["hello world !", "  hello   world !", " hello world   ! "],
--                "",
--                None,
--                [
--                    ["hello", "world", "!"],
--                    ["hello", "world", "!"],
--                    ["hello", "world", "!"],
--                ],
--                [3, 3, 3],
--            ),
--            (
--                ["o-n-n--x-", "o-n----nx"],
--                "-",
--                None,
--                [["o", "n", "n", "", "x", ""], ["o", "n", "", "", "", "nx"]],
--                [6, 6],
--            ),
--            (
--                [],
--                " ",
--                2,
--                np.array([]).reshape((0, 0)),
--                [],
--            ),
--        ]
--    )
--    def test_string_split(
--        self,
--        x,
--        delimiter,
--        maxsplit,
--        expected_split,
--        expected_num_splits,
--    ):
--        X = make_tensor_value_info("X", TensorProto.STRING, (None))
--        Splits = make_tensor_value_info("Splits", TensorProto.STRING, (None))
--        MaxSplits = make_tensor_value_info("MaxSplits", TensorProto.INT32, (None))
--        node = make_node(
--            "StringSplit",
--            inputs=["X"],
--            outputs=["Splits", "MaxSplits"],
--            delimiter=delimiter,
--            maxsplit=maxsplit,
--        )
--        model = make_model(make_graph([node], "g", [X], [Splits, MaxSplits]))
--        ref = ReferenceEvaluator(model)
--        x = np.array(x, dtype=object)
--        result, num_splits, *_ = ref.run(None, {"X": x})
--        np.testing.assert_array_equal(result, np.array(expected_split, dtype=object))
--        np.testing.assert_array_equal(
--            num_splits, np.array(expected_num_splits, dtype=np.int64)
--        )
--
-     def test_qlinearconv_int8(self):
-         node = make_node(
-             "QLinearMatMul",
-@@ -5533,47 +5006,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-             np.array([[41, -12, -9], [1, -75, 20]], dtype=np.int8), got[0]
-         )
- 
--    @parameterized.parameterized.expand(
--        [
--            (
--                ["www.google.com", "www.facebook.com", "www.bbc.co.uk"],
--                r"www\.[\w.-]+\.\bcom\b",
--                [True, True, False],
--                (3,),
--            ),
--            (
--                [["Onnx", "tensorflow", "Numpy"], ["Pytorch", "Cython", "numba"]],
--                r"^[A-Z][a-z]*$",
--                [[True, False, True], [True, True, False]],
--                (2, 3),
--            ),
--            (
--                [
--                    "account@gmail.com",
--                    "account@hotmail.com",
--                    "not email",
--                    "account2@yahoo.com",
--                ],
--                r"(\W|^)[\w.\-]{0,25}@(yahoo|gmail)\.com(\W|$)",
--                [True, False, False, True],
--                (4,),
--            ),
--        ]
--    )
--    @unittest.skipIf(
--        sys.platform == "win32", "google-re2 package is not built for win32"
--    )
--    def test_regex_full_match(self, x, pattern, expected, expected_shape):
--        X = make_tensor_value_info("X", TensorProto.STRING, None)
--        Y = make_tensor_value_info("Y", TensorProto.BOOL, None)
--        node = make_node("RegexFullMatch", inputs=["X"], outputs=["Y"], pattern=pattern)
--        model = make_model(make_graph([node], "g", [X], [Y]))
--        ref = ReferenceEvaluator(model)
--        result, *_ = ref.run(None, {"X": np.array(x)})
--        np.testing.assert_array_equal(result, expected)
--        self.assertEqual(result.dtype.kind, "b")
--        self.assertEqual(result.shape, expected_shape)
--
-     @unittest.skipIf(
-         sys.platform == "win32", "google-re2 package is not built for win32"
-     )
-@@ -5586,118 +5018,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-         with self.assertRaises(ValueError):
-             ref.run(None, {"X": np.array(["x"])})
- 
--    @parameterized.parameterized.expand(
--        [
--            (
--                TensorProto.UINT4,
--                [-1, 0, 1.5, 2, 3.3, 10, 20, 40],
--                [0, 0, 2, 2, 4, 10, 20, 30],
--            ),
--            (TensorProto.UINT4, [-1, 0, 1.5, 2, 3.3, 10, 40], [0, 0, 2, 2, 4, 10, 30]),
--            (TensorProto.UINT4, [0], [0]),
--            (
--                TensorProto.INT4,
--                [-20, -14.5, 0, 1.5, 2, 3.3, 10, 20],
--                [-16, -14, 0, 2, 2, 4, 10, 14],
--            ),
--            (
--                TensorProto.INT4,
--                [-20, -14.5, 0, 1.5, 2, 3.3, 10],
--                [-16, -14, 0, 2, 2, 4, 10],
--            ),
--            (TensorProto.INT4, [0], [0]),
--        ]
--    )
--    @unittest.skipIf(
--        version_utils.numpy_older_than("1.22.0"),
--        "The test requires numpy 1.22.0 or later",
--    )
--    def test_quantize_linear_int4(self, qtype, data, expected):
--        X = make_tensor_value_info("X", TensorProto.FLOAT, [None])
--        Y = make_tensor_value_info("Y", TensorProto.FLOAT, [None])
--        model = make_model(
--            make_graph(
--                [
--                    make_node(
--                        "Constant",
--                        [],
--                        ["scale"],
--                        value=make_tensor("scale", TensorProto.FLOAT, [1], [2.0]),
--                    ),
--                    make_node(
--                        "Constant",
--                        [],
--                        ["zero"],
--                        value=make_tensor("zero", qtype, [1], [0]),
--                    ),
--                    make_node("QuantizeLinear", ["X", "scale", "zero"], ["T"]),
--                    make_node("DequantizeLinear", ["T", "scale"], ["Y"], axis=0),
--                ],
--                "g",
--                [X],
--                [Y],
--            )
--        )
--        ref = ReferenceEvaluator(model)
--        got = ref.run(None, {"X": np.asarray(data)})
--        assert_allclose(expected, got[0])
--
--    @parameterized.parameterized.expand(
--        itertools.product(
--            (TensorProto.FLOAT, TensorProto.FLOAT16),
--            (TensorProto.UINT4, TensorProto.INT4),
--        )
--    )
--    def test_cast_int4_output(self, cast_from, cast_to):
--        X = make_tensor_value_info("X", cast_from, [None])
--        Y = make_tensor_value_info("Y", cast_to, [None])
--        model = make_model(
--            make_graph(
--                [
--                    make_node("Cast", ["X"], ["Y"], to=cast_to),
--                ],
--                "g",
--                [X],
--                [Y],
--            )
--        )
--        ref = ReferenceEvaluator(model)
--        data = np.array([0, 1, 2.4, 2.6, 4, 10], dtype=np.float32)
--        signed = cast_to == TensorProto.INT4
--        expected1 = np.array(
--            [subbyte.float32_to_4bit_unpacked(x, signed=signed) for x in data]
--        )
--        got = ref.run(None, {"X": data})
--        self.assertEqual(expected1.tolist(), got[0].tolist())
--
--    @parameterized.parameterized.expand(
--        itertools.product(
--            (TensorProto.UINT4, TensorProto.INT4),
--            (TensorProto.FLOAT, TensorProto.FLOAT16),
--        )
--    )
--    def test_cast_int4_input(self, cast_from, cast_to):
--        X = make_tensor_value_info("X", cast_from, [None])
--        Y = make_tensor_value_info("Y", cast_to, [None])
--        model = make_model(
--            make_graph(
--                [
--                    make_node("Cast", ["X"], ["Y"], to=TensorProto.FLOAT),
--                ],
--                "g",
--                [X],
--                [Y],
--            )
--        )
--        ref = ReferenceEvaluator(model)
--        data = np.array(range(7), dtype=np.float32)
--        cast_from_np = custom.uint4 if cast_from == TensorProto.UINT4 else custom.int4
--        expected1 = np.array(
--            [subbyte.float32_to_4bit_unpacked(x, cast_from_np) for x in data]
--        )
--        got = ref.run(None, {"X": data})
--        self.assertEqual(expected1.tolist(), got[0].tolist())
--
-     def test_a_function_calling_a_function_once(self):
-         X = make_tensor_value_info("X", TensorProto.FLOAT, ["N"])
-         output = make_tensor_value_info("output", TensorProto.FLOAT, ["N"])
-@@ -5930,97 +5250,6 @@ class TestReferenceEvaluator(unittest.TestCase):
-         for v in oinf.functions_.values():
-             self.assertIsInstance(v, MyReferenceEvaluator)
- 
--    @parameterized.parameterized.expand(
--        [
--            ("UINT4", 0.84),
--            ("INT4", 0.84),
--            ("FLOAT8E4M3FN", 0.23),
--            ("FLOAT8E4M3FNUZ", 0.23),
--            ("FLOAT8E5M2", 0.85),
--            ("FLOAT8E5M2FNUZ", 0.85),
--            ("DOUBLE", 0),
--            ("FLOAT", 0),
--            ("FLOAT16", 2e-3),
--            ("BFLOAT16", 2e-2),
--        ]
--    )
--    @skip_if_no_ml_dtypes
--    def test_add_custom_dtype(self, stype, atol):
--        itype = getattr(TensorProto, stype)
--        model = make_model(
--            make_graph(
--                [
--                    make_node("Cast", ["X"], ["Xc"], to=itype),
--                    make_node("Cast", ["Y"], ["Yc"], to=itype),
--                    make_node("Add", ["Xc", "Yc"], ["Zc"]),
--                    make_node("Cast", ["Zc"], ["Z"], to=TensorProto.FLOAT),
--                ],
--                "nd",
--                [
--                    make_tensor_value_info("X", TensorProto.FLOAT, [None, None, None]),
--                    make_tensor_value_info("Y", TensorProto.FLOAT, [None, None, None]),
--                ],
--                [make_tensor_value_info("Z", TensorProto.FLOAT, [None, None, None])],
--            ),
--            opset_imports=[make_opsetid("", 18)],
--            ir_version=9,
--        )
--
--        ref = ReferenceEvaluator(model, verbose=0)
--
--        x = (np.arange(18) / 6).reshape((2, 3, 3)).astype(np.float32)
--        y = (np.arange(18) / 9).reshape((2, 3, 3)).astype(np.float32)
--        feeds = dict(X=x, Y=y)
--        expected = x + y
--        got = ref.run(None, feeds)[0]
--        assert_allclose(expected, got, atol=atol)
--
--    @parameterized.parameterized.expand(
--        [
--            ("DOUBLE",),
--            ("FLOAT",),
--            ("FLOAT16",),
--            ("BFLOAT16",),
--            # Comparison fails with ml_dtypes
--            # ("FLOAT8E4M3FN", ),
--            # ("FLOAT8E4M3FNUZ", ),
--            # ("FLOAT8E5M2", ),
--            # ("FLOAT8E5M2FNUZ", ),
--            # ("INT4", ),
--            # ("UINT4", ),
--        ]
--    )
--    @skip_if_no_ml_dtypes
--    def test_cmp_custom_dtype(self, stype):
--        itype = getattr(TensorProto, stype)
--        model = make_model(
--            make_graph(
--                [
--                    make_node("Cast", ["X"], ["Xc"], to=itype),
--                    make_node("Cast", ["Y"], ["Yc"], to=itype),
--                    make_node("Greater", ["Xc", "Yc"], ["Zc"]),
--                    make_node("Cast", ["Zc"], ["Z"], to=TensorProto.BOOL),
--                ],
--                "nd",
--                [
--                    make_tensor_value_info("X", TensorProto.FLOAT, [None, None, None]),
--                    make_tensor_value_info("Y", TensorProto.FLOAT, [None, None, None]),
--                ],
--                [make_tensor_value_info("Z", TensorProto.FLOAT, [None, None, None])],
--            ),
--            opset_imports=[make_opsetid("", 18)],
--            ir_version=9,
--        )
--
--        ref = ReferenceEvaluator(model)
--
--        x = (np.arange(18) / 18).reshape((2, 3, 3)).astype(np.float32)
--        y = ((np.arange(18) - 9) / 18).reshape((2, 3, 3)).astype(np.float32)
--        feeds = dict(X=x, Y=y)
--        expected = x >= y
--        got = ref.run(None, feeds)[0]
--        assert_almost_equal(expected, got)
--
-     def test_scatter_elements_4d(self):
-         model = make_model(
-             make_graph(
-diff --git a/onnx/test/schema_test.py b/onnx/test/schema_test.py
-index b40f933f7..1d74fcda4 100644
---- a/onnx/test/schema_test.py
-+++ b/onnx/test/schema_test.py
-@@ -7,8 +7,6 @@ import contextlib
- import unittest
- from typing import Sequence
- 
--import parameterized
--
- import onnx
- from onnx import defs
- 
-@@ -211,34 +209,6 @@ class TestFormalParameter(unittest.TestCase):
-         )
- 
- 
--class TestTypeConstraintParam(unittest.TestCase):
--    @parameterized.parameterized.expand(
--        [
--            ("single_type", "T", ["tensor(float)"], "Test description"),
--            (
--                "double_types",
--                "T",
--                ["tensor(float)", "tensor(int64)"],
--                "Test description",
--            ),
--            ("tuple", "T", ("tensor(float)", "tensor(int64)"), "Test description"),
--        ]
--    )
--    def test_init(
--        self,
--        _: str,
--        type_param_str: str,
--        allowed_types: Sequence[str],
--        description: str,
--    ) -> None:
--        type_constraint = defs.OpSchema.TypeConstraintParam(
--            type_param_str, allowed_types, description
--        )
--        self.assertEqual(type_constraint.description, description)
--        self.assertEqual(type_constraint.allowed_type_strs, list(allowed_types))
--        self.assertEqual(type_constraint.type_param_str, type_param_str)
--
--
- class TestAttribute(unittest.TestCase):
-     def test_init(self):
-         name = "test_attr"
-@@ -261,169 +231,5 @@ class TestAttribute(unittest.TestCase):
-         self.assertEqual("attr1 description", attribute.description)
- 
- 
--@parameterized.parameterized_class(
--    [
--        # register to exist domain
--        {
--            "op_type": "CustomOp",
--            "op_version": 5,
--            "op_domain": "",
--            "trap_op_version": [1, 2, 6, 7],
--        },
--        # register to new domain
--        {
--            "op_type": "CustomOp",
--            "op_version": 5,
--            "op_domain": "test",
--            "trap_op_version": [1, 2, 6, 7],
--        },
--    ]
--)
--class TestOpSchemaRegister(unittest.TestCase):
--    op_type: str
--    op_version: int
--    op_domain: str
--    # register some fake schema to check behavior
--    trap_op_version: list[int]
--
--    def setUp(self) -> None:
--        # Ensure the schema is unregistered
--        self.assertFalse(onnx.defs.has(self.op_type, self.op_domain))
--
--    def tearDown(self) -> None:
--        # Clean up the registered schema
--        for version in [*self.trap_op_version, self.op_version]:
--            with contextlib.suppress(onnx.defs.SchemaError):
--                onnx.defs.deregister_schema(self.op_type, version, self.op_domain)
--
--    def test_register_multi_schema(self):
--        for version in [*self.trap_op_version, self.op_version]:
--            op_schema = defs.OpSchema(
--                self.op_type,
--                self.op_domain,
--                version,
--            )
--            onnx.defs.register_schema(op_schema)
--            self.assertTrue(onnx.defs.has(self.op_type, version, self.op_domain))
--        for version in [*self.trap_op_version, self.op_version]:
--            # Also make sure the `op_schema` is accessible after register
--            registered_op = onnx.defs.get_schema(
--                op_schema.name, version, op_schema.domain
--            )
--            op_schema = defs.OpSchema(
--                self.op_type,
--                self.op_domain,
--                version,
--            )
--            self.assertEqual(str(registered_op), str(op_schema))
--
--    def test_using_the_specified_version_in_onnx_check(self):
--        input = f"""
--            <
--                ir_version: 7,
--                opset_import: [
--                    "{self.op_domain}" : {self.op_version}
--                ]
--            >
--            agraph (float[N, 128] X, int32 Y) => (float[N] Z)
--            {{
--                Z = {self.op_domain}.{self.op_type}<attr1=[1,2]>(X, Y)
--            }}
--           """
--        model = onnx.parser.parse_model(input)
--        op_schema = defs.OpSchema(
--            self.op_type,
--            self.op_domain,
--            self.op_version,
--            inputs=[
--                defs.OpSchema.FormalParameter("input1", "T"),
--                defs.OpSchema.FormalParameter("input2", "int32"),
--            ],
--            outputs=[
--                defs.OpSchema.FormalParameter("output1", "T"),
--            ],
--            type_constraints=[("T", ["tensor(float)"], "")],
--            attributes=[
--                defs.OpSchema.Attribute(
--                    "attr1", defs.OpSchema.AttrType.INTS, "attr1 description"
--                )
--            ],
--        )
--        with self.assertRaises(onnx.checker.ValidationError):
--            onnx.checker.check_model(model, check_custom_domain=True)
--        onnx.defs.register_schema(op_schema)
--        # The fake schema will raise check exception if selected in checker
--        for version in self.trap_op_version:
--            onnx.defs.register_schema(
--                defs.OpSchema(
--                    self.op_type,
--                    self.op_domain,
--                    version,
--                    outputs=[
--                        defs.OpSchema.FormalParameter("output1", "int32"),
--                    ],
--                )
--            )
--        onnx.checker.check_model(model, check_custom_domain=True)
--
--    def test_register_schema_raises_error_when_registering_a_schema_twice(self):
--        op_schema = defs.OpSchema(
--            self.op_type,
--            self.op_domain,
--            self.op_version,
--        )
--        onnx.defs.register_schema(op_schema)
--        with self.assertRaises(onnx.defs.SchemaError):
--            onnx.defs.register_schema(op_schema)
--
--    def test_deregister_the_specified_schema(self):
--        for version in [*self.trap_op_version, self.op_version]:
--            op_schema = defs.OpSchema(
--                self.op_type,
--                self.op_domain,
--                version,
--            )
--            onnx.defs.register_schema(op_schema)
--            self.assertTrue(onnx.defs.has(op_schema.name, version, op_schema.domain))
--        onnx.defs.deregister_schema(op_schema.name, self.op_version, op_schema.domain)
--        for version in self.trap_op_version:
--            self.assertTrue(onnx.defs.has(op_schema.name, version, op_schema.domain))
--        # Maybe has lesser op version in trap list
--        if onnx.defs.has(op_schema.name, self.op_version, op_schema.domain):
--            schema = onnx.defs.get_schema(
--                op_schema.name, self.op_version, op_schema.domain
--            )
--            self.assertLess(schema.since_version, self.op_version)
--
--    def test_deregister_schema_raises_error_when_opschema_does_not_exist(self):
--        with self.assertRaises(onnx.defs.SchemaError):
--            onnx.defs.deregister_schema(self.op_type, self.op_version, self.op_domain)
--
--    def test_legacy_schema_accessible_after_deregister(self):
--        op_schema = defs.OpSchema(
--            self.op_type,
--            self.op_domain,
--            self.op_version,
--        )
--        onnx.defs.register_schema(op_schema)
--        schema_a = onnx.defs.get_schema(
--            op_schema.name, op_schema.since_version, op_schema.domain
--        )
--        schema_b = onnx.defs.get_schema(op_schema.name, op_schema.domain)
--
--        def filter_schema(schemas):
--            return [op for op in schemas if op.name == op_schema.name]
--
--        schema_c = filter_schema(onnx.defs.get_all_schemas())
--        schema_d = filter_schema(onnx.defs.get_all_schemas_with_history())
--        self.assertEqual(len(schema_c), 1)
--        self.assertEqual(len(schema_d), 1)
--        # Avoid memory residue and access storage as much as possible
--        self.assertEqual(str(schema_a), str(op_schema))
--        self.assertEqual(str(schema_b), str(op_schema))
--        self.assertEqual(str(schema_c[0]), str(op_schema))
--        self.assertEqual(str(schema_d[0]), str(op_schema))
--
--
- if __name__ == "__main__":
-     unittest.main()
-diff --git a/onnx/test/shape_inference_test.py b/onnx/test/shape_inference_test.py
-index 9e6b96b5b..2425bc339 100644
---- a/onnx/test/shape_inference_test.py
-+++ b/onnx/test/shape_inference_test.py
-@@ -10,7 +10,6 @@ from typing import Any, Sequence
- 
- import numpy as np
- import pytest
--from parameterized import parameterized
- 
- import onnx.shape_inference
- from onnx import (
-@@ -238,86 +237,6 @@ class TestShapeInference(TestShapeInferenceHelper):
-             graph, [make_tensor_value_info("y", TensorProto.FLOAT, (30, 4, 5))]
-         )
- 
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose(self, _, version) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, (2, 3, 4))],
--            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("Y", TensorProto.FLOAT, (3, 2, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose_preexisting(self, _, version) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, (2, 3, 4))],
--            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
--            [make_tensor_value_info("Y", TensorProto.FLOAT, None)],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("Y", TensorProto.FLOAT, (3, 2, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose_scalar(self, _, version) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, ())],
--            [make_node("Transpose", ["X"], ["Y"])],
--            [],
--        )
--
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("Y", TensorProto.FLOAT, ())],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose_partial(self, _, version) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, (2, 3, 4))],
--            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
--            [make_tensor_value_info("Y", TensorProto.UNDEFINED, (3, "a", "b"))],
--        )  # type: ignore
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("Y", TensorProto.FLOAT, (3, 2, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose_preexisting_incorrect_shape(self, *_) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, (2, 3, 4))],
--            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
--            [make_tensor_value_info("Y", TensorProto.FLOAT, (5, 5, 5))],
--        )
--        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
--
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose_preexisting_incorrect_type(self, *_) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, (2, 3, 4))],
--            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])],
--            [make_tensor_value_info("Y", TensorProto.STRING, (3, 2, 4))],
--        )
--        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
--
--    @parameterized.expand(all_versions_for("Transpose"))
--    def test_transpose_incorrect_repeated_perm(self, *_) -> None:
--        graph = self._make_graph(
--            [("X", TensorProto.FLOAT, (2, 3, 4))],
--            [make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 1])],
--            [],
--        )
--        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
--
-     def _make_matmul_test_all_dims_known(
-         self, version, shape1: Sequence[int], shape2: Sequence[int]
-     ) -> None:
-@@ -327,1343 +246,59 @@ class TestShapeInference(TestShapeInferenceHelper):
-         ).shape
-         graph = self._make_graph(
-             [("x", TensorProto.FLOAT, shape1), ("y", TensorProto.FLOAT, shape2)],
--            [make_node("MatMul", ["x", "y"], ["z"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.FLOAT, expected_out_shape)],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("MatMul"))
--    def test_matmul_all_dims_known(self, _, version) -> None:
--        self._make_matmul_test_all_dims_known(version, (2,), (2,))
--
--        self._make_matmul_test_all_dims_known(version, (4, 2), (2, 4))
--        self._make_matmul_test_all_dims_known(version, (5, 2), (2, 4))
--        self._make_matmul_test_all_dims_known(version, (5, 2), (2, 1))
--        self._make_matmul_test_all_dims_known(version, (1, 2), (2, 3))
--        self._make_matmul_test_all_dims_known(version, (2,), (2, 3))
--        self._make_matmul_test_all_dims_known(version, (4, 2), (2,))
--        self._make_matmul_test_all_dims_known(version, (1, 4, 2), (3, 2, 3))
--        self._make_matmul_test_all_dims_known(version, (3, 4, 2), (3, 2, 3))
--        self._make_matmul_test_all_dims_known(version, (5, 1, 4, 2), (1, 3, 2, 3))
--        self._make_matmul_test_all_dims_known(version, (4, 2), (3, 2, 3))
--
--    def _make_matmul_test_allow_unknown(
--        self, version, shape1: Any, shape2: Any, expected_out_shape: Any
--    ) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, shape1), ("y", TensorProto.FLOAT, shape2)],
--            [make_node("MatMul", ["x", "y"], ["z"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.FLOAT, expected_out_shape)],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("MatMul"))
--    def test_matmul_allow_unknown(self, _, version) -> None:
--        self._make_matmul_test_allow_unknown(version, (None,), (None,), ())
--        self._make_matmul_test_allow_unknown(version, (3,), (None,), ())
--        self._make_matmul_test_allow_unknown(version, (2,), (2, "a"), ("a",))
--        self._make_matmul_test_allow_unknown(version, (4, 2), (2, "a"), (4, "a"))
--        self._make_matmul_test_allow_unknown(version, (4, None), (2, "a"), (4, "a"))
--        self._make_matmul_test_allow_unknown(version, (4, None), (None, "a"), (4, "a"))
--        self._make_matmul_test_allow_unknown(
--            version, (1, 4, 2), ("a", 2, 5), ("a", 4, 5)
--        )
--        self._make_matmul_test_allow_unknown(
--            version, (1, 3, 4, 2), ("a", 2, 5), (1, 3, 4, 5)
--        )
--        self._make_matmul_test_allow_unknown(version, (3,), None, None)
--        self._make_matmul_test_allow_unknown(version, None, None, None)
--
--    @parameterized.expand(all_versions_for("Cast"))
--    def test_cast(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Cast", ["x"], ["y"], to=TensorProto.UINT8)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, (2, 4, 3))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Cast"))
--    @unittest.skip(
--        "Issue #5960"
--    )  # FIXME(#5960) propagateElemTypeFromAttributeToOutput does not validate against output type constraints
--    def test_cast_to_complex(self, _, version) -> None:  # noqa: ARG002
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Cast", ["x"], ["y"], to=TensorProto.COMPLEX128)],
--            [],
--        )
--
--        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
--
--    @parameterized.expand(all_versions_for("CastLike"))
--    def test_cast_like(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3)), ("t", TensorProto.FLOAT16, ("N",))],
--            [make_node("CastLike", ["x", "t"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT16, (2, 4, 3))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Col2Im"))
--    def test_col2im(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("input", TensorProto.FLOAT, (1, 5, 5)),
--                ("output_shape", TensorProto.INT64, (2,)),
--                ("kernel_shape", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Col2Im", ["input", "output_shape", "kernel_shape"], ["output"]
--                )
--            ],
--            [],
--            initializer=[
--                make_tensor("output_shape", TensorProto.INT64, (2,), (5, 5)),
--                make_tensor("kernel_shape", TensorProto.INT64, (2,), (1, 5)),
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 5, 5))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Col2Im"))
--    def test_col2im_strides(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("input", TensorProto.FLOAT, (1, 9, 4)),
--                ("output_shape", TensorProto.INT64, (2,)),
--                ("kernel_shape", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Col2Im",
--                    ["input", "output_shape", "kernel_shape"],
--                    ["output"],
--                    strides=[2, 2],
--                )
--            ],
--            [],
--            initializer=[
--                make_tensor("output_shape", TensorProto.INT64, (2,), (5, 5)),
--                make_tensor("kernel_shape", TensorProto.INT64, (2,), (3, 3)),
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 5, 5))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Col2Im"))
--    def test_col2im_pads(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("input", TensorProto.FLOAT, (1, 5, 15)),
--                ("output_shape", TensorProto.INT64, (2,)),
--                ("kernel_shape", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Col2Im",
--                    ["input", "output_shape", "kernel_shape"],
--                    ["output"],
--                    pads=[0, 1, 0, 1],
--                )
--            ],
--            [],
--            initializer=[
--                make_tensor("output_shape", TensorProto.INT64, (2,), (5, 5)),
--                make_tensor("kernel_shape", TensorProto.INT64, (2,), (1, 5)),
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 5, 5))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Col2Im"))
--    def test_col2im_dilations(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("input", TensorProto.FLOAT, (1, 4, 5)),
--                ("output_shape", TensorProto.INT64, (2,)),
--                ("kernel_shape", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Col2Im",
--                    ["input", "output_shape", "kernel_shape"],
--                    ["output"],
--                    dilations=[1, 5],
--                )
--            ],
--            [],
--            initializer=[
--                make_tensor("output_shape", TensorProto.INT64, (2,), (6, 6)),
--                make_tensor("kernel_shape", TensorProto.INT64, (2,), (2, 2)),
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 1, 6, 6))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Col2Im"))
--    def test_col2im_5d(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("input", TensorProto.FLOAT, (1, 10, 12)),
--                ("output_shape", TensorProto.INT64, (3,)),
--                ("kernel_shape", TensorProto.INT64, (3,)),
--            ],
--            [
--                make_node(
--                    "Col2Im", ["input", "output_shape", "kernel_shape"], ["output"]
--                )
--            ],
--            [],
--            initializer=[
--                make_tensor("output_shape", TensorProto.INT64, (3,), (3, 4, 5)),
--                make_tensor("kernel_shape", TensorProto.INT64, (3,), (1, 1, 5)),
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("output", TensorProto.FLOAT, (1, 2, 3, 4, 5))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Concat"))
--    def test_concat(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3)), ("y", TensorProto.FLOAT, (7, 4, 3))],
--            [make_node("Concat", ["x", "y"], ["z"], axis=0)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.FLOAT, (9, 4, 3))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Concat"))
--    def test_concat_missing_shape(self, *_) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (2, 4, 3)),
--                "y",
--                ("z", TensorProto.FLOAT, (None, None, None)),
--            ],
--            [make_node("Concat", ["x", "y", "z"], ["out"], axis=0)],
--            [],
--        )
--        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
--
--    @parameterized.expand(all_versions_for("Concat"))
--    def test_concat_3d_axis_2(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 2, 2)), ("y", TensorProto.FLOAT, (2, 2, 2))],
--            [make_node("Concat", ["x", "y"], ["z"], axis=2)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.FLOAT, (2, 2, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Concat"))
--    def test_concat_param(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, ("a", 2)), ("y", TensorProto.FLOAT, ("a", 3))],
--            [make_node("Concat", ["x", "y"], ["z"], axis=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.FLOAT, ("a", 5))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Concat"))
--    def test_concat_param_single_input(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, ("a", 2))],
--            [make_node("Concat", ["x"], ["z"], axis=0)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.FLOAT, ("a", 2))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_dynamic_shape_known_rank(self, _, version) -> None:
--        self.skipIf(version < 14, "Rank inference is added from Version 14")
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, (2,))],
--            [make_node("Reshape", ["x", "shape"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, (None, None))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_dynamic_shape_symbolic(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, ("M",))],
--            [make_node("Reshape", ["x", "shape"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, None)],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_dynamic_unknown_shape(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, None)],
--            [make_node("Reshape", ["x", "shape"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, None)],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_static_shape(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, (2,))],
--            [make_node("Reshape", ["x", "shape"], ["y"])],
--            [],
--            initializer=[make_tensor("shape", TensorProto.INT64, (2,), (3, 8))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, (3, 8))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_static_shape_inferred(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (2, 4, 3)), ("shape", TensorProto.INT64, (3,))],
--            [make_node("Reshape", ["x", "shape"], ["y"])],
--            [],
--            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (0, 3, -1))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, (2, 3, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_static_shape_zero(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (1, 1, 1)), ("shape", TensorProto.INT64, (3,))],
--            [make_node("Reshape", ["x", "shape"], ["y"])],
--            [],
--            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (0, 1, 1))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, (1, 1, 1))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_static_shape_allowzero(self, _, version) -> None:
--        self.skipIf(version < 14, "allowzero is added from Version 14")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.UINT8, (1, 0, 0)),
--                ("shape", TensorProto.INT64, (3,)),
--            ],
--            [make_node("Reshape", ["x", "shape"], ["y"], allowzero=1)],
--            [],
--            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (0, 1, 1))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.UINT8, (0, 1, 1))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Reshape"))
--    def test_reshape_static_shape_constant(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.UINT8, (2, 4, 3))],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["shape"],
--                    value=make_tensor("shape", TensorProto.INT64, (2,), (3, 8)),
--                ),
--                make_node("Reshape", ["x", "shape"], ["y"]),
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("shape", TensorProto.INT64, (2,)),
--                make_tensor_value_info("y", TensorProto.UINT8, (3, 8)),
--            ],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Upsample"))
--    def test_upsample(self, _, version) -> None:
--        if version == 7:
--            graph = self._make_graph(
--                [("x", TensorProto.INT32, (2, 4, 3, 5))],
--                [make_node("Upsample", ["x"], ["y"], scales=[1.0, 1.1, 1.3, 1.9])],
--                [],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
--        else:
--            graph = self._make_graph(
--                [
--                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                    ("scales", TensorProto.FLOAT, (4,)),
--                ],
--                [make_node("Upsample", ["x", "scales"], ["y"])],
--                [],
--                initializer=[
--                    make_tensor("scales", TensorProto.FLOAT, (4,), (1.0, 1.1, 1.3, 1.9))
--                ],
--            )
--
--            def call_inference():
--                self._assert_inferred(
--                    graph,
--                    [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--                    opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--                )
--
--            if version == 9:
--                call_inference()
--            else:
--                # Upsample is deprecated since Version 10.
--                with self.assertRaises(onnx.checker.ValidationError) as cm:
--                    call_inference()
--                exception = cm.exception
--                assert "Upsample is deprecated" in str(exception)
--
--    @parameterized.expand(all_versions_for("Upsample"))
--    def test_upsample_raw_data(self, _, version) -> None:
--        if version == 7:
--            graph = self._make_graph(
--                [("x", TensorProto.INT32, (1, 3, 4, 5))],
--                [make_node("Upsample", ["x"], ["y"], scales=[2.0, 1.1, 2.3, 1.9])],
--                [],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 9, 9))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
--        else:
--            graph = self._make_graph(
--                [
--                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                    ("scales", TensorProto.FLOAT, (4,)),
--                ],
--                [make_node("Upsample", ["x", "scales"], ["y"])],
--                [],
--                initializer=[
--                    make_tensor(
--                        "scales",
--                        TensorProto.FLOAT,
--                        (4,),
--                        vals=np.array([1.0, 1.1, 1.3, 1.9], dtype="<f4").tobytes(),
--                        raw=True,
--                    )
--                ],
--            )  # Feed raw bytes (force little endian ordering like onnx standard) for test purpose
--
--            def call_inference():
--                self._assert_inferred(
--                    graph,
--                    [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--                    opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--                )
--
--            if version == 9:
--                call_inference()
--            else:
--                # Upsample is deprecated since Version 10.
--                with self.assertRaises(onnx.checker.ValidationError) as cm:
--                    call_inference()
--                exception = cm.exception
--                assert "Upsample is deprecated" in str(exception)
--
--    @parameterized.expand(all_versions_for("Expand"))
--    def test_expand(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.INT32, (3, 1)), ("shape", TensorProto.INT64, (3,))],
--            [make_node("Expand", ["x", "shape"], ["y"])],
--            [],
--            initializer=[make_tensor("shape", TensorProto.INT64, (3,), (2, 1, 6))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 6))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Expand"))
--    def test_expand_scalar_input(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.INT32, ()), ("shape", TensorProto.INT64, (2,))],
--            [make_node("Expand", ["x", "shape"], ["y"])],
--            [],
--            initializer=[make_tensor("shape", TensorProto.INT64, (2,), (4, 8))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (4, 8))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Expand"))
--    def test_expand_raw_data(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.INT32, (3, 1)), ("shape", TensorProto.INT64, (2,))],
--            [make_node("Expand", ["x", "shape"], ["y"])],
--            [],
--            initializer=[
--                make_tensor(
--                    "shape",
--                    TensorProto.INT64,
--                    (2,),
--                    vals=np.array([3, 4], dtype="<i8").tobytes(),
--                    raw=True,
--                )
--            ],
--        )  # Feed raw bytes (force little endian ordering like onnx standard) for test purpose
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (3, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Expand"))
--    def test_expand_dynamic_shape(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (1, 2, None)),
--                ("shape", TensorProto.INT64, (3,)),
--            ],
--            [make_node("Expand", ["x", "shape"], ["y"])],
--            [],
--            initializer=[],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (None, 2, None))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Expand"))
--    def test_expand_symbolic_shape(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (1, 2, None)),
--                ("shape", TensorProto.INT64, ("unk__0",)),
--            ],
--            [make_node("Expand", ["x", "shape"], ["y"])],
--            [],
--            initializer=[],
--        )
--        # if giving a symbolic shape, Expand should not infer any shape or rank inference
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, None)],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size(self, _, version) -> None:
--        if version == 10:
--            graph = self._make_graph(
--                [
--                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                    ("scales", TensorProto.FLOAT, (4,)),
--                ],
--                [make_node("Resize", ["x", "scales"], ["y"])],
--                [],
--                initializer=[
--                    make_tensor("scales", TensorProto.FLOAT, (4,), (1.0, 1.1, 1.3, 1.9))
--                ],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
--        elif version == 11:
--            graph = self._make_graph(
--                [
--                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                    ("roi", TensorProto.FLOAT, (8,)),
--                    ("scales", TensorProto.FLOAT, (4,)),
--                    ("sizes", TensorProto.INT64, (4,)),
--                ],
--                [make_node("Resize", ["x", "roi", "scales", "sizes"], ["y"])],
--                [],
--                initializer=[
--                    make_tensor("sizes", TensorProto.INT64, (4,), (3, 5, 6, 7))
--                ],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.INT32, (3, 5, 6, 7))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
--        else:
--            graph = self._make_graph(
--                [
--                    ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                    ("roi", TensorProto.FLOAT, (8,)),
--                    ("sizes", TensorProto.INT64, (4,)),
--                ],
--                [make_node("Resize", ["x", "roi", "", "sizes"], ["y"])],
--                [],
--                initializer=[
--                    make_tensor("sizes", TensorProto.INT64, (4,), (3, 5, 6, 7))
--                ],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.INT32, (3, 5, 6, 7))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size_axes_2_3(self, _, version) -> None:
--        self.skipIf(version < 18, "axes is from Version 18")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (2,)),
--            ],
--            [make_node("Resize", ["x", "roi", "", "sizes"], ["y"], axes=(2, 3))],
--            [],
--            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 7))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 6, 7))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size_axes_3_2(self, _, version) -> None:
--        self.skipIf(version < 18, "axes is from Version 18")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (2,)),
--            ],
--            [make_node("Resize", ["x", "roi", "", "sizes"], ["y"], axes=(3, 2))],
--            [],
--            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 7))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 7, 6))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size_not_larger(self, _, version) -> None:
--        self.skipIf(
--            version < 18,
--            "keep_aspect_ratio_policy is from Version 18",
--        )
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (3, 5)),
--                ("roi", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Resize",
--                    ["x", "roi", "", "sizes"],
--                    ["y"],
--                    keep_aspect_ratio_policy="not_larger",
--                )
--            ],
--            [],
--            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (4, 6))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size_axes_2_3_not_larger(self, _, version) -> None:
--        self.skipIf(
--            version < 18,
--            "axes & keep_aspect_ratio_policy are from Version 18",
--        )
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Resize",
--                    ["x", "roi", "", "sizes"],
--                    ["y"],
--                    axes=(2, 3),
--                    keep_aspect_ratio_policy="not_larger",
--                )
--            ],
--            [],
--            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 4, 6))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size_not_smaller(self, _, version) -> None:
--        self.skipIf(
--            version < 18,
--            "keep_aspect_ratio_policy is from Version 18",
--        )
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (3, 5)),
--                ("roi", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Resize",
--                    ["x", "roi", "", "sizes"],
--                    ["y"],
--                    keep_aspect_ratio_policy="not_smaller",
--                )
--            ],
--            [],
--            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (6, 10))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_size_axes_2_3_not_smaller(self, _, version) -> None:
--        self.skipIf(
--            version < 18,
--            "axes & keep_aspect_ratio_policy are from Version 18",
--        )
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (2,)),
--            ],
--            [
--                make_node(
--                    "Resize",
--                    ["x", "roi", "", "sizes"],
--                    ["y"],
--                    axes=(2, 3),
--                    keep_aspect_ratio_policy="not_smaller",
--                )
--            ],
--            [],
--            initializer=[make_tensor("sizes", TensorProto.INT64, (2,), (6, 6))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 6, 10))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_scale(self, _, version) -> None:
--        self.skipIf(version < 11, "roi input is from Version 11")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (8,)),
--                ("scales", TensorProto.FLOAT, (4,)),
--            ],
--            [make_node("Resize", ["x", "roi", "scales"], ["y"])],
--            [],
--            initializer=[
--                make_tensor("scales", TensorProto.FLOAT, (4,), (1.0, 1.1, 1.3, 1.9))
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_scale_axes_2_3(self, _, version) -> None:
--        self.skipIf(version < 18, "axes is from Version 18")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (8,)),
--                ("scales", TensorProto.FLOAT, (2,)),
--            ],
--            [make_node("Resize", ["x", "roi", "scales"], ["y"], axes=(2, 3))],
--            [],
--            initializer=[make_tensor("scales", TensorProto.FLOAT, (2,), (1.3, 1.9))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_scale_axes_3_2(self, _, version) -> None:
--        self.skipIf(version < 18, "axes is from Version 18")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (2, 4, 3, 5)),
--                ("roi", TensorProto.FLOAT, (8,)),
--                ("scales", TensorProto.FLOAT, (2,)),
--            ],
--            [make_node("Resize", ["x", "roi", "scales"], ["y"], axes=(3, 2))],
--            [],
--            initializer=[make_tensor("scales", TensorProto.FLOAT, (2,), (1.9, 1.3))],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 4, 3, 9))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_scale_raw_data(self, _, version) -> None:
--        self.skipIf(version < 11, "roi input is from Version 11")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (1, 3, 4, 5)),
--                ("roi", TensorProto.FLOAT, (8,)),
--                ("scales", TensorProto.FLOAT, (4,)),
--            ],
--            [make_node("Resize", ["x", "roi", "scales"], ["y"])],
--            [],
--            initializer=[
--                make_tensor(
--                    "scales",
--                    TensorProto.FLOAT,
--                    (4,),
--                    vals=np.array([2.0, 1.1, 2.3, 1.9], dtype="<f4").tobytes(),
--                    raw=True,
--                )
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 9, 9))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_scale_and_size_but_one_is_empty(self, _, version) -> None:
--        self.skipIf(version < 11, "roi input is from Version 11")
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (1, 3, 4, 5)),
--                ("roi", TensorProto.FLOAT, (8,)),
--                ("scales", TensorProto.FLOAT, (4,)),
--                ("sizes", TensorProto.INT64, (0,)),
--            ],
--            [make_node("Resize", ["x", "roi", "scales", "sizes"], ["y"])],
--            [],
--            initializer=[
--                make_tensor(
--                    "scales",
--                    TensorProto.FLOAT,
--                    (4,),
--                    vals=np.array([2.0, 1.1, 2.3, 1.9], dtype="<f4").tobytes(),
--                    raw=True,
--                ),
--                make_tensor(
--                    "sizes",
--                    TensorProto.INT64,
--                    (0,),
--                    vals=np.array([], dtype="<i8").tobytes(),
--                    raw=True,
--                ),
--            ],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 3, 9, 9))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Resize"))
--    def test_resize_opset11_scales_is_empty(self, _, version) -> None:
--        self.skipIf(version != 11, "This test only works for Version 11")
--        # "scales" input in Resize in opset11 is not optional. It must be an empty tensor
--        # if sizes is needed. Shape inference for Resize shall handle this case.
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.INT32, (1, 3, 4, 5)),
--                ("roi", TensorProto.FLOAT, (8,)),
--                ("scales", TensorProto.FLOAT, (0,)),
--                ("sizes", TensorProto.INT64, (4,)),
--            ],
--            [make_node("Resize", ["x", "roi", "scales", "sizes"], ["y"])],
--            [],
--            initializer=[
--                make_tensor(
--                    "sizes",
--                    TensorProto.INT64,
--                    (4,),
--                    vals=np.array(
--                        [2, 6, 8, 10], dtype="<i8"
--                    ).tobytes(),  # double in all dimensions
--                    raw=True,
--                ),
--            ],
--        )
--
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT32, (2, 6, 8, 10))],
--            opset_imports=[helper.make_opsetid("", version)],
--        )
--
--    @parameterized.expand(all_versions_for("Shape"))
--    def test_shape(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Shape", ["x"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (3,))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Shape"))
--    def test_shape_start_1(self, _, version) -> None:
--        self.skipIf(version < 15, "start and end are from Version 15")
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Shape", ["x"], ["y"], start=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (2,))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Shape"))
--    def test_shape_end_1(self, _, version) -> None:
--        self.skipIf(version < 15, "start and end are from Version 15")
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Shape", ["x"], ["y"], end=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (1,))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Shape"))
--    def test_shape_negative_start(self, _, version) -> None:
--        self.skipIf(version < 15, "start and end are from Version 15")
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Shape", ["x"], ["y"], start=-1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (1,))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Shape"))
--    def test_shape_clip1(self, _, version) -> None:
--        self.skipIf(version < 15, "start and end are from Version 15")
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Shape", ["x"], ["y"], start=-5)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (3,))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Shape"))
--    def test_shape_clip2(self, _, version) -> None:
--        self.skipIf(version < 15, "start and end are from Version 15")
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))],
--            [make_node("Shape", ["x"], ["y"], end=10)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (3,))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Size"))
--    def test_size(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 4, 3))], [make_node("Size", ["x"], ["y"])], []
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, ())],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Gather"))
--    def test_gather(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (4, 3)), ("i", TensorProto.INT64, (2,))],
--            [make_node("Gather", ["x", "i"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (2, 3))],  # type: ignore
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Gather"))
--    def test_gather_axis1(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (4, 3, 5)), ("i", TensorProto.INT64, (1, 2))],
--            [make_node("Gather", ["x", "i"], ["y"], axis=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (4, 1, 2, 5))],  # type: ignore
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Gather"))
--    def test_gather_into_scalar(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (3,)), ("i", TensorProto.INT64, ())],
--            [make_node("Gather", ["x", "i"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, ())],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("GatherElements"))
--    def test_gather_elements(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2, 2)), ("i", TensorProto.INT64, (2, 2))],
--            [make_node("GatherElements", ["x", "i"], ["y"], axis=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (2, 2))],  # type: ignore
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("GatherElements"))
--    def test_gather_elements_axis0(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (3, 3)), ("i", TensorProto.INT64, (2, 3))],
--            [make_node("GatherElements", ["x", "i"], ["y"], axis=0)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (2, 3))],  # type: ignore
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("Scatter"))
--    def test_scatter(self, _, version) -> None:
--        if version >= 11:
--            # Scatter is deprecated in domain_version of 11.
--            with self.assertRaises(onnx.checker.ValidationError) as cm:
--                self._test_scatter(version)
--            exception = cm.exception
--            assert "Scatter is deprecated" in str(exception)
--        else:
--            self._test_scatter(version)
--
--    def _test_scatter(self, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (3, 3)),
--                ("i", TensorProto.INT64, (2, 3)),
--                ("u", TensorProto.FLOAT, (2, 3)),
--            ],
--            [make_node("Scatter", ["x", "i", "u"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (3, 3))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )  # type: ignore
--
--    @parameterized.expand(all_versions_for("Scatter"))
--    def test_scatter_axis1(self, _, version) -> None:
--        if version >= 11:
--            # Scatter is deprecated in domain_version of 11.
--            with self.assertRaises(onnx.checker.ValidationError) as cm:
--                self._test_scatter_axis1(version)
--            exception = cm.exception
--            assert "Scatter is deprecated" in str(exception)
--        else:
--            self._test_scatter_axis1(version)
--
--    def _test_scatter_axis1(self, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (1, 5)),
--                ("i", TensorProto.INT64, (1, 2)),
--                ("u", TensorProto.FLOAT, (1, 2)),
--            ],
--            [make_node("Scatter", ["x", "i", "u"], ["y"], axis=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 5))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )  # type: ignore
--
--    @parameterized.expand(all_versions_for("ScatterElements"))
--    def test_scatter_elements(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (3, 3)),
--                ("i", TensorProto.INT64, (2, 3)),
--                ("u", TensorProto.FLOAT, (2, 3)),
--            ],
--            [make_node("ScatterElements", ["x", "i", "u"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (3, 3))],  # type: ignore
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("ScatterElements"))
--    def test_scatter_elements_axis1(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (1, 5)),
--                ("i", TensorProto.INT64, (1, 2)),
--                ("u", TensorProto.FLOAT, (1, 2)),
--            ],
--            [make_node("ScatterElements", ["x", "i", "u"], ["y"], axis=1)],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 5))],  # type: ignore
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("ScatterND"))
--    def test_scatternd(self, _, version) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (4, 5, 6)),
--                ("indices", TensorProto.INT64, (3, 3, 2)),
--                ("updates", TensorProto.FLOAT, (3, 3, 6)),
--            ],
--            [make_node("ScatterND", ["x", "indices", "updates"], ["y"])],
-+            [make_node("MatMul", ["x", "y"], ["z"])],
-             [],
-         )
-         self._assert_inferred(
-             graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (4, 5, 6))],  # type: ignore
-+            [make_tensor_value_info("z", TensorProto.FLOAT, expected_out_shape)],
-             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
-         )
- 
--    @parameterized.expand(all_versions_for("ScatterND"))
--    def test_scatternd_noshape(self, _, version) -> None:
--        # The shape of 'x_reshaped' cannot be inferred, since it is the output of a dynamic reshape.
--        # Thus the shape of 'y' is also None.
-+    def _make_matmul_test_allow_unknown(
-+        self, version, shape1: Any, shape2: Any, expected_out_shape: Any
-+    ) -> None:
-         graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, (4, 5, 6)),
--                ("indices", TensorProto.INT64, (3, 3, 2)),
--                ("updates", TensorProto.FLOAT, (3, 3, 6)),
--                ("shape", TensorProto.INT64, ("M",)),
--            ],
--            [
--                make_node("Reshape", ["x", "shape"], ["x_reshaped"]),
--                make_node("ScatterND", ["x_reshaped", "indices", "updates"], ["y"]),
--            ],
-+            [("x", TensorProto.FLOAT, shape1), ("y", TensorProto.FLOAT, shape2)],
-+            [make_node("MatMul", ["x", "y"], ["z"])],
-             [],
-         )
-         self._assert_inferred(
-             graph,
--            [
--                make_tensor_value_info("x_reshaped", TensorProto.FLOAT, None),
--                make_tensor_value_info("y", TensorProto.FLOAT, None),
--            ],
-+            [make_tensor_value_info("z", TensorProto.FLOAT, expected_out_shape)],
-             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )  # type: ignore
--
--    @parameterized.expand(all_versions_for("Squeeze"))
--    def test_squeeze(self, _, version) -> None:
--        if version == 11:
--            graph = self._make_graph(
--                [("x", TensorProto.FLOAT, (1, 3, 1, 1, 2, 1))],
--                [make_node("Squeeze", "x", "y", axes=[0, 2, 3, 5])],
--                [],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.FLOAT, (3, 2))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
--        else:
--            graph = self._make_graph(
--                [
--                    ("x", TensorProto.FLOAT, (1, 3, 1, 1, 2, 1)),
--                    ("axes", TensorProto.INT64, (4,)),
--                ],
--                [make_node("Squeeze", ["x", "axes"], "y")],
--                [],
--                initializer=[
--                    make_tensor("axes", TensorProto.INT64, (4,), (0, 2, 3, 5))
--                ],
--            )
--            self._assert_inferred(
--                graph,
--                [make_tensor_value_info("y", TensorProto.FLOAT, (3, 2))],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--            )
-+        )
- 
--    @parameterized.expand(all_versions_for("StringConcat"))
--    def test_stringconcat(self, _, version) -> None:
-+    def _test_scatter(self, version) -> None:
-         graph = self._make_graph(
-             [
--                ("x", TensorProto.STRING, (2, 3, 4)),
--                ("y", TensorProto.STRING, (2, 3, 4)),
-+                ("x", TensorProto.FLOAT, (3, 3)),
-+                ("i", TensorProto.INT64, (2, 3)),
-+                ("u", TensorProto.FLOAT, (2, 3)),
-             ],
--            [make_node("StringConcat", ["x", "y"], "z")],
-+            [make_node("Scatter", ["x", "i", "u"], ["y"])],
-             [],
-         )
-         self._assert_inferred(
-             graph,
--            [make_tensor_value_info("z", TensorProto.STRING, (2, 3, 4))],
-+            [make_tensor_value_info("y", TensorProto.FLOAT, (3, 3))],
-             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("StringConcat"))
--    def test_stringconcat_broadcasting(self, _, version) -> None:
-+        )  # type: ignore
-+    def _test_scatter_axis1(self, version) -> None:
-         graph = self._make_graph(
-             [
--                ("x", TensorProto.STRING, (2, 3, 4)),
--                ("y", TensorProto.STRING, (1, 3, 1)),
-+                ("x", TensorProto.FLOAT, (1, 5)),
-+                ("i", TensorProto.INT64, (1, 2)),
-+                ("u", TensorProto.FLOAT, (1, 2)),
-             ],
--            [make_node("StringConcat", ["x", "y"], "z")],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("z", TensorProto.STRING, (2, 3, 4))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("RegexFullMatch"))
--    def test_regex_full_match(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.STRING, (2, 4, 3, 9))],
--            [make_node("RegexFullMatch", ["x"], ["y"], pattern=r"^[A-Z][a-z]*$")],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.BOOL, (2, 4, 3, 9))],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("RegexFullMatch"))
--    def test_regex_full_match_empty_shape(self, _, version) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.STRING, ())],
--            [make_node("RegexFullMatch", ["x"], ["y"], pattern=r"^[A-Z][a-z]*$")],
-+            [make_node("Scatter", ["x", "i", "u"], ["y"], axis=1)],
-             [],
-         )
-         self._assert_inferred(
-             graph,
--            [make_tensor_value_info("y", TensorProto.BOOL, ())],
-+            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 5))],
-             opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
-+        )  # type: ignore
- 
-     def test_squeeze_no_axes_opset11(self) -> None:
-         graph = self._make_graph(
-@@ -5304,23 +3939,6 @@ class TestShapeInference(TestShapeInferenceHelper):
-         self._make_matmulinteger_test((5, 1, 4, 2), (1, 3, 2, 3))
-         self._make_matmulinteger_test((4, 2), (3, 2, 3))
- 
--    @parameterized.expand(
--        [onnx.TensorProto.FLOAT, onnx.TensorProto.FLOAT16, onnx.TensorProto.BFLOAT16]
--    )
--    def test_quantizelinear(self, elem_type) -> None:
--        graph = self._make_graph(
--            [
--                ("x", elem_type, (30, 4, 5)),
--                ("y_scale", elem_type, ()),
--                ("y_zero_point", TensorProto.UINT8, ()),
--            ],
--            [make_node("QuantizeLinear", ["x", "y_scale", "y_zero_point"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph, [make_tensor_value_info("y", TensorProto.UINT8, (30, 4, 5))]
--        )
--
-     def test_quantizelinear_default_zp(self) -> None:
-         graph = self._make_graph(
-             [("x", TensorProto.FLOAT, (30, 4, 5)), ("y_scale", TensorProto.FLOAT, ())],
-@@ -5426,23 +4044,6 @@ class TestShapeInference(TestShapeInferenceHelper):
-             graph,
-         )
- 
--    @parameterized.expand(
--        [onnx.TensorProto.FLOAT, onnx.TensorProto.FLOAT16, onnx.TensorProto.BFLOAT16]
--    )
--    def test_dequantizelinear(self, elem_type) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.UINT8, (30, 4, 5)),
--                ("x_scale", elem_type, ()),
--                ("x_zero_point", TensorProto.UINT8, ()),
--            ],
--            [make_node("DequantizeLinear", ["x", "x_scale", "x_zero_point"], ["y"])],
--            [],
--        )
--        self._assert_inferred(
--            graph, [make_tensor_value_info("y", elem_type, (30, 4, 5))]
--        )
--
-     def test_dynamicquantizelinear(self) -> None:
-         graph = self._make_graph(
-             [("x", TensorProto.FLOAT, (30, 4, 5))],
-@@ -5551,383 +4152,125 @@ class TestShapeInference(TestShapeInferenceHelper):
-                 make_tensor(
-                     "repeats",
-                     TensorProto.INT64,
--                    (3,),
--                    vals=np.array([1, 2, 3], dtype="<i8").tobytes(),
--                    raw=True,
--                )
--            ],
--        )  # Feed raw bytes (force little endian ordering like onnx standard) for test purpose
--        self._assert_inferred(
--            graph, [make_tensor_value_info("y", TensorProto.FLOAT, (4, 10, 18))]
--        )
--
--    def test_tile_rank_inference(self) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (4, 5, 6)), ("repeats", TensorProto.INT64, (3,))],
--            [make_node("Tile", ["x", "repeats"], ["y"])],
--            [],
--        )
--        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, (None, None, None))])  # type: ignore
--
--    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
--    def test_linearclassifier_1D_input(self) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (5,))],
--            [
--                make_node(
--                    "LinearClassifier",
--                    ["x"],
--                    ["y", "z"],
--                    domain=ONNX_ML_DOMAIN,
--                    coefficients=[0.0008, -0.0008],
--                    intercepts=[2.0, 2.0],
--                    classlabels_ints=[1, 2],
--                )
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("y", TensorProto.INT64, (1,)),
--                make_tensor_value_info("z", TensorProto.FLOAT, (1, 2)),
--            ],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, 1),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
--
--    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
--    def test_linearclassifier_2D_input(self) -> None:
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (4, 5))],
--            [
--                make_node(
--                    "LinearClassifier",
--                    ["x"],
--                    ["y", "z"],
--                    domain=ONNX_ML_DOMAIN,
--                    coefficients=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
--                    intercepts=[2.0, 2.0, 3.0],
--                    classlabels_ints=[1, 2, 3],
--                )
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("y", TensorProto.INT64, (4,)),
--                make_tensor_value_info("z", TensorProto.FLOAT, (4, 3)),
--            ],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, 1),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
--
--    def test_roialign_symbolic(self) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, ("N", "C", "H", "W")),
--                ("rois", TensorProto.FLOAT, ("num_rois", 4)),
--                ("batch_indices", TensorProto.INT64, ("num_rois",)),
--            ],
--            [
--                make_node(
--                    "RoiAlign",
--                    ["x", "rois", "batch_indices"],
--                    ["y"],
--                    output_height=10,
--                    output_width=5,
--                )
--            ],
--            [],
--        )
--        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, ("num_rois", "C", 10, 5))])  # type: ignore
--
--    def test_roialign_symbolic_defaults(self) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, ("N", "C", "H", "W")),
--                ("rois", TensorProto.FLOAT, ("num_rois", 4)),
--                ("batch_indices", TensorProto.INT64, ("num_rois",)),
--            ],
--            [make_node("RoiAlign", ["x", "rois", "batch_indices"], ["y"])],
--            [],
--        )
--        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, ("num_rois", "C", 1, 1))])  # type: ignore
--
--    def test_roialign_num_rois(self) -> None:
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.FLOAT, ("N", "C", "H", "W")),
--                ("rois", TensorProto.FLOAT, ("num_rois", 4)),
--                ("batch_indices", TensorProto.INT64, (15,)),
--            ],
--            [make_node("RoiAlign", ["x", "rois", "batch_indices"], ["y"])],
--            [],
--        )
--        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, (15, "C", 1, 1))])  # type: ignore
--
--    @parameterized.expand(
--        all_versions_for("LabelEncoder") if ONNX_ML else [], skip_on_empty=True
--    )
--    def test_label_encoder_string_int64(self, _, version) -> None:
--        self.skipIf(
--            version < 2, "keys_* attributes were introduced in ai.onnx.ml opset 2"
--        )
--        string_list = ["A", "m", "y"]
--        float_list = [94.17, 36.00, -99.0]
--        int64_list = [12, 28, 86]
--        graph = self._make_graph(
--            [("x", TensorProto.STRING, (6, 1))],
--            [
--                make_node(
--                    "LabelEncoder",
--                    ["x"],
--                    ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_strings=string_list,
--                    values_int64s=int64_list,
--                )
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (6, 1))],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
--
--        graph = self._make_graph(
--            [("x", TensorProto.INT64, (2, 3))],
--            [
--                make_node(
--                    "LabelEncoder",
--                    ["x"],
--                    ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_int64s=int64_list,
--                    values_strings=string_list,
--                )
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.STRING, (2, 3))],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
--
--        graph = self._make_graph(
--            [("x", TensorProto.FLOAT, (2,))],
--            [
--                make_node(
--                    "LabelEncoder",
--                    ["x"],
--                    ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_floats=float_list,
--                    values_int64s=int64_list,
--                )
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, (2,))],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
--                make_opsetid(ONNX_DOMAIN, 11),
-+                    (3,),
-+                    vals=np.array([1, 2, 3], dtype="<i8").tobytes(),
-+                    raw=True,
-+                )
-             ],
-+        )  # Feed raw bytes (force little endian ordering like onnx standard) for test purpose
-+        self._assert_inferred(
-+            graph, [make_tensor_value_info("y", TensorProto.FLOAT, (4, 10, 18))]
-         )
- 
-+    def test_tile_rank_inference(self) -> None:
-         graph = self._make_graph(
--            [("x", TensorProto.INT64, (8,))],
--            [
--                make_node(
--                    "LabelEncoder",
--                    ["x"],
--                    ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_int64s=int64_list,
--                    values_floats=float_list,
--                )
--            ],
-+            [("x", TensorProto.FLOAT, (4, 5, 6)), ("repeats", TensorProto.INT64, (3,))],
-+            [make_node("Tile", ["x", "repeats"], ["y"])],
-             [],
-         )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (8,))],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
-+        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, (None, None, None))])  # type: ignore
- 
-+    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
-+    def test_linearclassifier_1D_input(self) -> None:
-         graph = self._make_graph(
--            [("x", TensorProto.FLOAT, ())],
-+            [("x", TensorProto.FLOAT, (5,))],
-             [
-                 make_node(
--                    "LabelEncoder",
-+                    "LinearClassifier",
-                     ["x"],
--                    ["y"],
-+                    ["y", "z"],
-                     domain=ONNX_ML_DOMAIN,
--                    keys_floats=float_list,
--                    values_strings=string_list,
-+                    coefficients=[0.0008, -0.0008],
-+                    intercepts=[2.0, 2.0],
-+                    classlabels_ints=[1, 2],
-                 )
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
--            [make_tensor_value_info("y", TensorProto.STRING, ())],
-+            [
-+                make_tensor_value_info("y", TensorProto.INT64, (1,)),
-+                make_tensor_value_info("z", TensorProto.FLOAT, (1, 2)),
-+            ],
-             opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
-+                make_opsetid(ONNX_ML_DOMAIN, 1),
-                 make_opsetid(ONNX_DOMAIN, 11),
-             ],
-         )
- 
-+    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
-+    def test_linearclassifier_2D_input(self) -> None:
-         graph = self._make_graph(
--            [("x", TensorProto.STRING, (1, 2))],
-+            [("x", TensorProto.FLOAT, (4, 5))],
-             [
-                 make_node(
--                    "LabelEncoder",
-+                    "LinearClassifier",
-                     ["x"],
--                    ["y"],
-+                    ["y", "z"],
-                     domain=ONNX_ML_DOMAIN,
--                    keys_strings=string_list,
--                    values_floats=float_list,
-+                    coefficients=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
-+                    intercepts=[2.0, 2.0, 3.0],
-+                    classlabels_ints=[1, 2, 3],
-                 )
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
--            [make_tensor_value_info("y", TensorProto.FLOAT, (1, 2))],
-+            [
-+                make_tensor_value_info("y", TensorProto.INT64, (4,)),
-+                make_tensor_value_info("z", TensorProto.FLOAT, (4, 3)),
-+            ],
-             opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
-+                make_opsetid(ONNX_ML_DOMAIN, 1),
-                 make_opsetid(ONNX_DOMAIN, 11),
-             ],
-         )
- 
--    @parameterized.expand(
--        all_versions_for("LabelEncoder") if ONNX_ML else [], skip_on_empty=True
--    )
--    def test_label_encoder_tensor_attributes(self, _, version) -> None:
--        self.skipIf(
--            version < 4, "tensor attributes were introduced in ai.onnx.ml opset 4"
--        )
--        key_tensor = make_tensor(
--            "keys_tensor", TensorProto.STRING, [4], ["a", "b", "cc", "ddd"]
--        )
--        values_tensor = make_tensor(
--            "values_tensor", TensorProto.INT64, [4], [1, 2, 3, 4]
--        )
-+    def test_roialign_symbolic(self) -> None:
-         graph = self._make_graph(
--            [("x", TensorProto.STRING, ("M", None, 3, 12))],
-+            [
-+                ("x", TensorProto.FLOAT, ("N", "C", "H", "W")),
-+                ("rois", TensorProto.FLOAT, ("num_rois", 4)),
-+                ("batch_indices", TensorProto.INT64, ("num_rois",)),
-+            ],
-             [
-                 make_node(
--                    "LabelEncoder",
--                    ["x"],
-+                    "RoiAlign",
-+                    ["x", "rois", "batch_indices"],
-                     ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_tensor=key_tensor,
--                    values_tensor=values_tensor,
--                    default_tensor=make_tensor(
--                        "default_tensor", TensorProto.INT64, [1], [0]
--                    ),
-+                    output_height=10,
-+                    output_width=5,
-                 )
-             ],
-             [],
-         )
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", TensorProto.INT64, ("M", None, 3, 12))],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, version),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
--
--    @parameterized.expand(
--        all_versions_for("LabelEncoder") if ONNX_ML else [], skip_on_empty=True
--    )
--    def test_label_encoder_tensor_attributes_invalid_configurations(
--        self, _, version
--    ) -> None:
--        self.skipIf(version < 4, "tensor attributes introduced in ai.onnx.ml opset 4")
--        key_tensor = make_tensor(
--            "keys_tensor", TensorProto.STRING, [4], ["a", "b", "cc", "ddd"]
--        )
--        values_tensor = make_tensor(
--            "values_tensor", TensorProto.INT64, [4], [1, 2, 3, 4]
--        )
--
--        opset_imports = [
--            make_opsetid(ONNX_ML_DOMAIN, version),
--            make_opsetid(ONNX_DOMAIN, 11),
--        ]
-+        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, ("num_rois", "C", 10, 5))])  # type: ignore
- 
--        # default_tensor should be INT64, same type as values_tensor
-+    def test_roialign_symbolic_defaults(self) -> None:
-         graph = self._make_graph(
--            [("x", TensorProto.STRING, ("M", None, 3, 12))],
-             [
--                make_node(
--                    "LabelEncoder",
--                    ["x"],
--                    ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_tensor=key_tensor,
--                    values_tensor=values_tensor,
--                    default_tensor=make_tensor(
--                        "default_tensor", TensorProto.STRING, [1], [0]
--                    ),
--                )
-+                ("x", TensorProto.FLOAT, ("N", "C", "H", "W")),
-+                ("rois", TensorProto.FLOAT, ("num_rois", 4)),
-+                ("batch_indices", TensorProto.INT64, ("num_rois",)),
-             ],
-+            [make_node("RoiAlign", ["x", "rois", "batch_indices"], ["y"])],
-             [],
-         )
-+        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, ("num_rois", "C", 1, 1))])  # type: ignore
- 
--        self.assertRaises(
--            onnx.shape_inference.InferenceError,
--            self._inferred,
--            graph,
--            opset_imports=opset_imports,
--        )
--
--        # default_tensor should be a singleton of shape (1,)
-+    def test_roialign_num_rois(self) -> None:
-         graph = self._make_graph(
--            [("x", TensorProto.STRING, ("M", None, 3, 12))],
-             [
--                make_node(
--                    "LabelEncoder",
--                    ["x"],
--                    ["y"],
--                    domain=ONNX_ML_DOMAIN,
--                    keys_tensor=key_tensor,
--                    values_strings=["a", "b", "cc", "ddd"],
--                    default_tensor=make_tensor(
--                        "default_tensor", TensorProto.STRING, [1, 2], [0, 0]
--                    ),
--                )
-+                ("x", TensorProto.FLOAT, ("N", "C", "H", "W")),
-+                ("rois", TensorProto.FLOAT, ("num_rois", 4)),
-+                ("batch_indices", TensorProto.INT64, (15,)),
-             ],
-+            [make_node("RoiAlign", ["x", "rois", "batch_indices"], ["y"])],
-             [],
-         )
--
--        self.assertRaises(
--            onnx.shape_inference.InferenceError,
--            self._inferred,
--            graph,
--            opset_imports=opset_imports,
--        )
-+        self._assert_inferred(graph, [make_tensor_value_info("y", TensorProto.FLOAT, (15, "C", 1, 1))])  # type: ignore
- 
-     def make_sparse(
-         self,
-@@ -8136,105 +6479,6 @@ class TestShapeInference(TestShapeInferenceHelper):
-         )
-         self._assert_inferred(graph, [output_tensor_val_info])  # type: ignore
- 
--    @parameterized.expand(all_versions_for("StringSplit"))
--    def test_string_split_basic(self, _, version) -> None:
--        substrings = make_tensor_value_info(
--            "substrings",
--            TensorProto.STRING,
--            (2, None),
--        )
--        length = make_tensor_value_info("length", TensorProto.INT64, (2,))
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.STRING, (2,)),
--            ],
--            [make_node("StringSplit", ["x"], ["substrings", "length"])],
--            [substrings, length],
--        )
--        self._assert_inferred(
--            graph,
--            [substrings, length],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("StringSplit"))
--    def test_string_split_symbolic(self, _, version) -> None:
--        substrings = make_tensor_value_info(
--            "substrings",
--            TensorProto.STRING,
--            ("A", None),
--        )
--        length = make_tensor_value_info("length", TensorProto.INT64, ("A",))
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.STRING, ("A",)),
--            ],
--            [make_node("StringSplit", ["x"], ["substrings", "length"])],
--            [substrings, length],
--        )
--        self._assert_inferred(
--            graph,
--            [substrings, length],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("StringSplit"))
--    def test_string_split_nested(self, _, version) -> None:
--        substrings = make_tensor_value_info(
--            "substrings", TensorProto.STRING, (2, 4, 3, None)
--        )
--        length = make_tensor_value_info("length", TensorProto.INT64, (2, 4, 3))
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.STRING, (2, 4, 3)),
--            ],
--            [make_node("StringSplit", ["x"], ["substrings", "length"], maxsplit=2)],
--            [substrings, length],
--        )
--        self._assert_inferred(
--            graph,
--            [substrings, length],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("StringSplit"))
--    def test_string_split_zero_dimensional_input(self, _, version) -> None:
--        substrings = make_tensor_value_info("substrings", TensorProto.STRING, (None,))
--        length = make_tensor_value_info("length", TensorProto.INT64, ())
--
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.STRING, ()),
--            ],
--            [make_node("StringSplit", ["x"], ["substrings", "length"], maxsplit=2)],
--            [substrings, length],
--        )
--        self._assert_inferred(
--            graph,
--            [substrings, length],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(all_versions_for("StringSplit"))
--    def test_string_split_empty_input(self, _, version) -> None:
--        substrings = make_tensor_value_info(
--            "substrings", TensorProto.STRING, ("M", 3, 0, None)
--        )
--        length = make_tensor_value_info("length", TensorProto.INT64, ("M", 3, 0))
--
--        graph = self._make_graph(
--            [
--                ("x", TensorProto.STRING, ("M", 3, 0)),
--            ],
--            [make_node("StringSplit", ["x"], ["substrings", "length"], maxsplit=2)],
--            [substrings, length],
--        )
--        self._assert_inferred(
--            graph,
--            [substrings, length],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
-     def test_optional_tensor_get_element(self) -> None:
-         tensor_type_proto = helper.make_tensor_type_proto(
-             elem_type=TensorProto.DOUBLE, shape=[2, 1, 4]
-@@ -8759,114 +7003,28 @@ class TestShapeInference(TestShapeInferenceHelper):
-         graph = self._make_graph(
-             [
-                 ("input1", TensorProto.FLOAT, (220, 310, 3)),
--                ("input2", TensorProto.FLOAT, (110, 210, 3)),
--                ("input3", TensorProto.FLOAT, (90, 110, 3)),
--            ],
--            [
--                make_node(
--                    "SequenceConstruct", ["input1", "input2", "input3"], ["in_sequence"]
--                ),
--                make_node("SequenceMap", ["in_sequence"], ["shapes"], body=body_graph),
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_sequence_value_info(
--                    "in_sequence", TensorProto.FLOAT, (None, None, 3)
--                ),
--                make_tensor_sequence_value_info("shapes", TensorProto.INT64, (3,)),
--            ],
--        )  # type: ignore
--
--    def test_hammingwindow(self):
--        graph = self._make_graph(
--            [],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["shape"],
--                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
--                ),
--                make_node("HammingWindow", ["shape"], ["y"]),
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("shape", TensorProto.INT64, ()),
--                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
--            ],
--        )  # type: ignore
--
--        graph = self._make_graph(
--            [],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["shape"],
--                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
--                ),
--                make_node("HammingWindow", ["shape"], ["y"], periodic=0),
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("shape", TensorProto.INT64, ()),
--                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
--            ],
--        )  # type: ignore
--
--    def test_hannwindow(self):
--        graph = self._make_graph(
--            [],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["shape"],
--                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
--                ),
--                make_node("HannWindow", ["shape"], ["y"]),
--            ],
--            [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("shape", TensorProto.INT64, ()),
--                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
--            ],
--        )  # type: ignore
--
--        graph = self._make_graph(
--            [],
-+                ("input2", TensorProto.FLOAT, (110, 210, 3)),
-+                ("input3", TensorProto.FLOAT, (90, 110, 3)),
-+            ],
-             [
-                 make_node(
--                    "Constant",
--                    [],
--                    ["shape"],
--                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-+                    "SequenceConstruct", ["input1", "input2", "input3"], ["in_sequence"]
-                 ),
--                make_node("HannWindow", ["shape"], ["y"], periodic=0),
-+                make_node("SequenceMap", ["in_sequence"], ["shapes"], body=body_graph),
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
-             [
--                make_tensor_value_info("shape", TensorProto.INT64, ()),
--                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
-+                make_tensor_sequence_value_info(
-+                    "in_sequence", TensorProto.FLOAT, (None, None, 3)
-+                ),
-+                make_tensor_sequence_value_info("shapes", TensorProto.INT64, (3,)),
-             ],
-         )  # type: ignore
- 
--    def test_blackmanwindow(self):
-+    def test_hammingwindow(self):
-         graph = self._make_graph(
-             [],
-             [
-@@ -8876,7 +7034,7 @@ class TestShapeInference(TestShapeInferenceHelper):
-                     ["shape"],
-                     value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-                 ),
--                make_node("BlackmanWindow", ["shape"], ["y"]),
-+                make_node("HammingWindow", ["shape"], ["y"]),
-             ],
-             [],
-         )
-@@ -8897,7 +7055,7 @@ class TestShapeInference(TestShapeInferenceHelper):
-                     ["shape"],
-                     value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-                 ),
--                make_node("BlackmanWindow", ["shape"], ["y"], periodic=0),
-+                make_node("HammingWindow", ["shape"], ["y"], periodic=0),
-             ],
-             [],
-         )
-@@ -8909,463 +7067,91 @@ class TestShapeInference(TestShapeInferenceHelper):
-             ],
-         )  # type: ignore
- 
--    @parameterized.expand(
--        [
--            (
--                name,
--                version,
--                test_aspect,
--                input_shape,
--                axis,
--                onesided,
--                inverse,
--                expected_shape,
--            )
--            for (name, version), (
--                test_aspect,
--                input_shape,
--                axis,
--                onesided,
--                inverse,
--                expected_shape,
--            ) in itertools.product(
--                all_versions_for("DFT"),
--                (
--                    ("reals_default_axis", (2, 5, 1), None, None, None, (2, 5, 2)),
--                    ("reals_axis_0", (3, 5, 10, 1), 0, 0, 0, (3, 5, 10, 2)),
--                    ("reals_axis_1", (3, 5, 10, 1), 1, 0, 0, (3, 5, 10, 2)),
--                    ("reals_axis_2", (3, 5, 10, 1), 2, 0, 0, (3, 5, 10, 2)),
--                    ("reals_axis_neg", (3, 5, 10, 1), -2, 0, 0, (3, 5, 10, 2)),
--                    ("reals_axis_0_onesided", (3, 5, 10, 1), 0, 1, 0, (2, 5, 10, 2)),
--                    ("reals_axis_1_onesided", (3, 5, 10, 1), 1, 1, 0, (3, 3, 10, 2)),
--                    ("reals_axis_2_onesided", (3, 5, 10, 1), 2, 1, 0, (3, 5, 6, 2)),
--                    ("reals_axis_neg_onesided", (3, 5, 10, 1), -2, 1, 0, (3, 5, 6, 2)),
--                    ("complex_default_axis", (2, 5, 2), None, None, None, (2, 5, 2)),
--                    ("complex_onesided", (2, 5, 2), 1, 1, None, (2, 3, 2)),
--                    ("real_inverse", (2, 5, 1), 1, None, 1, (2, 5, 2)),
--                    ("complex_inverse", (2, 5, 2), 1, None, 1, (2, 5, 2)),
--                ),
--            )
--        ]
--    )
--    def test_dft(
--        self,
--        _: str,
--        version: int,
--        _test_aspect: str,
--        input_shape: tuple[int],
--        axis: int | None,
--        onesided: int | None,
--        inverse: int | None,
--        expected_shape: tuple[int],
--    ) -> None:
--        # Build the attributes for different opset versions
--        attributes = {}
--        if onesided is not None:
--            attributes["onesided"] = onesided
--        if inverse is not None:
--            attributes["inverse"] = inverse
--
--        if version < 20:
--            if axis is not None:
--                attributes["axis"] = axis
--            nodes = [make_node("DFT", ["input", ""], ["output"], **attributes)]  # type: ignore[arg-type]
--            value_infos = []
--        else:
--            assert version >= 20
--            if axis is not None:
--                nodes = [
--                    make_node(
--                        "Constant",
--                        [],
--                        ["axis"],
--                        value=make_tensor("axis", TensorProto.INT64, (), (axis,)),
--                    ),
--                    make_node("DFT", ["input", "", "axis"], ["output"], **attributes),  # type: ignore[arg-type]
--                ]
--                value_infos = [make_tensor_value_info("axis", TensorProto.INT64, ())]
--            else:
--                nodes = [
--                    make_node("DFT", ["input", "", ""], ["output"], **attributes),  # type: ignore[arg-type]
--                ]
--                value_infos = []
--
--        # Construct the graph
-+    def test_hannwindow(self):
-         graph = self._make_graph(
-             [],
-             [
-                 make_node(
-                     "Constant",
-                     [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        input_shape,
--                        np.ones(input_shape, dtype=np.float32).flatten(),
--                    ),
-+                    ["shape"],
-+                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-                 ),
--                *nodes,
-+                make_node("HannWindow", ["shape"], ["y"]),
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
-             [
--                make_tensor_value_info("input", TensorProto.FLOAT, input_shape),
--                *value_infos,
--                make_tensor_value_info("output", TensorProto.FLOAT, expected_shape),
-+                make_tensor_value_info("shape", TensorProto.INT64, ()),
-+                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
-             ],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(
--        [
--            (
--                name,
--                version,
--                test_aspect,
--                input_shape,
--                axis,
--                onesided,
--                inverse,
--                expected_shape,
--            )
--            for (name, version), (
--                test_aspect,
--                input_shape,
--                axis,
--                onesided,
--                inverse,
--                expected_shape,
--            ) in itertools.product(
--                all_versions_for("DFT"),
--                (
--                    ("reals_default_axis", (2, 5, 1), None, None, None, (2, 42, 2)),
--                    ("reals_axis_0", (3, 5, 10, 1), 0, 0, 0, (42, 5, 10, 2)),
--                    ("reals_axis_1", (3, 5, 10, 1), 1, 0, 0, (3, 42, 10, 2)),
--                    ("reals_axis_2", (3, 5, 10, 1), 2, 0, 0, (3, 5, 42, 2)),
--                    ("reals_axis_neg", (3, 5, 10, 1), -2, 0, 0, (3, 5, 42, 2)),
--                    ("reals_axis_0_onesided", (3, 5, 10, 1), 0, 1, 0, (22, 5, 10, 2)),
--                    ("reals_axis_1_onesided", (3, 5, 10, 1), 1, 1, 0, (3, 22, 10, 2)),
--                    ("reals_axis_2_onesided", (3, 5, 10, 1), 2, 1, 0, (3, 5, 22, 2)),
--                    ("reals_axis_neg_onesided", (3, 5, 10, 1), -2, 1, 0, (3, 5, 22, 2)),
--                    ("complex_default_axis", (2, 5, 2), None, None, None, (2, 42, 2)),
--                    ("complex_onesided", (2, 5, 2), 1, 1, None, (2, 22, 2)),
--                    ("real_inverse", (2, 5, 1), 1, None, 1, (2, 42, 2)),
--                    ("complex_inverse", (2, 5, 2), 1, None, 1, (2, 42, 2)),
--                ),
--            )
--        ]
--    )
--    def test_dft_dft_length(
--        self,
--        _: str,
--        version: int,
--        _test_aspect: str,
--        input_shape: tuple[int],
--        axis: int | None,
--        onesided: int | None,
--        inverse: int | None,
--        expected_shape: tuple[int],
--    ) -> None:
--        # Build the attributes for different opset versions
--        attributes = {}
--        if onesided is not None:
--            attributes["onesided"] = onesided
--        if inverse is not None:
--            attributes["inverse"] = inverse
--
--        dft_length = 42
--
--        if version < 20:
--            if axis is not None:
--                attributes["axis"] = axis
--            nodes = [
--                make_node(
--                    "Constant",
--                    [],
--                    ["dft_length"],
--                    value=make_tensor(
--                        "dft_length", TensorProto.INT64, (), (dft_length,)
--                    ),
--                ),
--                make_node("DFT", ["input", "dft_length"], ["output"], **attributes),  # type: ignore[arg-type]
--            ]
--            value_infos = [make_tensor_value_info("dft_length", TensorProto.INT64, ())]
--        else:
--            assert version >= 20
--            if axis is not None:
--                nodes = [
--                    make_node(
--                        "Constant",
--                        [],
--                        ["axis"],
--                        value=make_tensor("axis", TensorProto.INT64, (), (axis,)),
--                    ),
--                    make_node(
--                        "Constant",
--                        [],
--                        ["dft_length"],
--                        value=make_tensor(
--                            "dft_length", TensorProto.INT64, (), (dft_length,)
--                        ),
--                    ),
--                    make_node("DFT", ["input", "dft_length", "axis"], ["output"], **attributes),  # type: ignore[arg-type]
--                ]
--                value_infos = [
--                    make_tensor_value_info("dft_length", TensorProto.INT64, ()),
--                    make_tensor_value_info("axis", TensorProto.INT64, ()),
--                ]
--            else:
--                nodes = [
--                    make_node(
--                        "Constant",
--                        [],
--                        ["dft_length"],
--                        value=make_tensor(
--                            "dft_length", TensorProto.INT64, (), (dft_length,)
--                        ),
--                    ),
--                    make_node("DFT", ["input", "dft_length", ""], ["output"], **attributes),  # type: ignore[arg-type]
--                ]
--                value_infos = [
--                    make_tensor_value_info("dft_length", TensorProto.INT64, ())
--                ]
-+        )  # type: ignore
- 
--        # Construct the graph
-         graph = self._make_graph(
-             [],
-             [
-                 make_node(
-                     "Constant",
-                     [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        input_shape,
--                        np.ones(input_shape, dtype=np.float32).flatten(),
--                    ),
-+                    ["shape"],
-+                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-                 ),
--                *nodes,
-+                make_node("HannWindow", ["shape"], ["y"], periodic=0),
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
-             [
--                make_tensor_value_info("input", TensorProto.FLOAT, input_shape),
--                *value_infos,
--                make_tensor_value_info("output", TensorProto.FLOAT, expected_shape),
--            ],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, version)],
--        )
--
--    @parameterized.expand(
--        [
--            ("last", 3),
--            ("last_negative", -1),
--            ("out_of_range", 4),
--            ("out_of_range_negative", -5),
--        ]
--    )
--    def test_dft_invalid_axis_opset17(self, _: str, axis: int) -> None:
--        graph = self._make_graph(
--            [],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        (2, 5, 5, 2),
--                        np.ones((2, 5, 5, 2), dtype=np.float32).flatten(),
--                    ),
--                ),
--                make_node("DFT", ["input", ""], ["output"], onesided=1, axis=axis),
-+                make_tensor_value_info("shape", TensorProto.INT64, ()),
-+                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
-             ],
--            [],
--        )
--        with self.assertRaises(onnx.shape_inference.InferenceError):
--            self._assert_inferred(
--                graph,
--                [
--                    make_tensor_value_info("input", TensorProto.FLOAT, (2, 5, 5, 2)),
--                    make_tensor_value_info("output", TensorProto.FLOAT, (2, 3, 5, 2)),
--                ],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 17)],
--            )
-+        )  # type: ignore
- 
--    @parameterized.expand(
--        [
--            ("last", 3),
--            ("last_negative", -1),
--            ("out_of_range", 4),
--            ("out_of_range_negative", -5),
--        ]
--    )
--    def test_dft_invalid_axis_opset20(self, _: str, axis: int) -> None:
-+    def test_blackmanwindow(self):
-         graph = self._make_graph(
-             [],
-             [
-                 make_node(
-                     "Constant",
-                     [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        (2, 5, 5, 2),
--                        np.ones((2, 5, 5, 2), dtype=np.float32).flatten(),
--                    ),
--                ),
--                make_node(
--                    "Constant",
--                    [],
--                    ["axis"],
--                    value=make_tensor("axis", TensorProto.INT64, (), (axis,)),
--                ),
--                make_node("DFT", ["input", "", "axis"], ["output"]),
--            ],
--            [],
--        )
--        with self.assertRaises(onnx.shape_inference.InferenceError):
--            self._assert_inferred(
--                graph,
--                [
--                    make_tensor_value_info("input", TensorProto.FLOAT, (2, 5, 5, 2)),
--                    make_tensor_value_info("axis", TensorProto.INT64, ()),
--                    make_tensor_value_info("output", TensorProto.FLOAT, (2, 3, 5, 2)),
--                ],
--                opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
--            )
--
--    @parameterized.expand(
--        [
--            ("real", (2, 5, 5, 1)),
--            ("complex", (2, 5, 5, 2)),
--        ]
--    )
--    def test_dft_dynamic_axis_opset20(self, _: str, shape: tuple[int, ...]) -> None:
--        graph = self._make_graph(
--            [("axis", TensorProto.INT64, ())],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        shape,
--                        np.ones(shape, dtype=np.float32).flatten(),
--                    ),
-+                    ["shape"],
-+                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-                 ),
--                make_node("DFT", ["input", "", "axis"], ["output"]),
-+                make_node("BlackmanWindow", ["shape"], ["y"]),
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
-             [
--                make_tensor_value_info("input", TensorProto.FLOAT, shape),
--                make_tensor_value_info("output", TensorProto.FLOAT, (2, 5, 5, 2)),
-+                make_tensor_value_info("shape", TensorProto.INT64, ()),
-+                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
-             ],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
--        )
-+        )  # type: ignore
- 
--    @parameterized.expand(
--        [
--            ("real", (2, 5, 5, 1)),
--            ("complex", (2, 5, 5, 2)),
--        ]
--    )
--    def test_dft_dynamic_axis_onesided_dft_length_opset20(
--        self, _: str, shape: tuple[int, ...]
--    ) -> None:
-         graph = self._make_graph(
--            [("axis", TensorProto.INT64, ())],
--            [
--                make_node(
--                    "Constant",
--                    [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        shape,
--                        np.ones(shape, dtype=np.float32).flatten(),
--                    ),
--                ),
--                make_node(
--                    "Constant",
--                    [],
--                    ["dft_length"],
--                    value=make_tensor(
--                        "dft_length",
--                        TensorProto.INT64,
--                        (),
--                        np.array([42], dtype=np.int64),
--                    ),
--                ),
--                make_node(
--                    "DFT", ["input", "dft_length", "axis"], ["output"], onesided=1
--                ),
--            ],
-             [],
--        )
--        self._assert_inferred(
--            graph,
--            [
--                make_tensor_value_info("input", TensorProto.FLOAT, shape),
--                make_tensor_value_info("dft_length", TensorProto.INT64, ()),
--                make_tensor_value_info(
--                    "output", TensorProto.FLOAT, (None, None, None, 2)
--                ),
--            ],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
--        )
--
--    @parameterized.expand(
--        [
--            ("real", (2, 5, 5, 1)),
--            ("complex", (2, 5, 5, 2)),
--        ]
--    )
--    def test_dft_dynamic_axis_onesided_opset20(
--        self, _: str, shape: tuple[int, ...]
--    ) -> None:
--        graph = self._make_graph(
--            [("axis", TensorProto.INT64, ())],
-             [
-                 make_node(
-                     "Constant",
-                     [],
--                    ["input"],
--                    value=make_tensor(
--                        "input",
--                        TensorProto.FLOAT,
--                        shape,
--                        np.ones(shape, dtype=np.float32).flatten(),
--                    ),
-+                    ["shape"],
-+                    value=make_tensor("shape", TensorProto.INT64, (), (10,)),
-                 ),
--                make_node("DFT", ["input", "", "axis"], ["output"], onesided=1),
-+                make_node("BlackmanWindow", ["shape"], ["y"], periodic=0),
-             ],
-             [],
-         )
-         self._assert_inferred(
-             graph,
-             [
--                make_tensor_value_info("input", TensorProto.FLOAT, shape),
--                make_tensor_value_info(
--                    "output", TensorProto.FLOAT, (None, None, None, 2)
--                ),
-+                make_tensor_value_info("shape", TensorProto.INT64, ()),
-+                make_tensor_value_info("y", TensorProto.FLOAT, (10,)),
-             ],
--            opset_imports=[helper.make_opsetid(ONNX_DOMAIN, 20)],
--        )
-+        )  # type: ignore
- 
-     def test_dft_onesided_default_axis_opset17(self) -> None:
-         # Opset 17 sets default axis to be 1.
-@@ -9846,139 +7632,6 @@ class TestShapeInference(TestShapeInferenceHelper):
-             ],
-         )
- 
--    @parameterized.expand([TensorProto.FLOAT, TensorProto.DOUBLE, TensorProto.FLOAT16])
--    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
--    def test_tree_ensemble(self, dtype) -> None:
--        interior_nodes = 5
--        leaves = 9
--        tree = make_node(
--            "TreeEnsemble",
--            ["x"],
--            ["y"],
--            domain=ONNX_ML_DOMAIN,
--            n_targets=5,
--            nodes_featureids=[0] * interior_nodes,
--            nodes_splits=make_tensor(
--                "nodes_splits",
--                dtype,
--                (interior_nodes,),
--                list(range(interior_nodes)),
--            ),
--            nodes_modes=make_tensor(
--                "nodes_modes",
--                TensorProto.UINT8,
--                (interior_nodes,),
--                [0] * interior_nodes,
--            ),
--            nodes_truenodeids=[0] * interior_nodes,
--            nodes_falsenodeids=[0] * interior_nodes,
--            nodes_trueleafs=[0] * interior_nodes,
--            nodes_falseleafs=[0] * interior_nodes,
--            membership_values=make_tensor(
--                "membership_values",
--                dtype,
--                (7,),
--                [0.0, 0.1, 0.2, np.nan, 0.4, 0.5, 1.0],
--            ),
--            leaf_targetids=[0] * leaves,
--            leaf_weights=make_tensor("leaf_weights", dtype, (leaves,), [1] * leaves),
--            tree_roots=[0],
--        )
--
--        graph = self._make_graph(
--            [("x", dtype, ("Batch Size", "Features"))],
--            [tree],
--            [],
--        )
--
--        self._assert_inferred(
--            graph,
--            [make_tensor_value_info("y", dtype, ("Batch Size", 5))],
--            opset_imports=[
--                make_opsetid(ONNX_ML_DOMAIN, 5),
--                make_opsetid(ONNX_DOMAIN, 11),
--            ],
--        )
--
--    @parameterized.expand(
--        [
--            {
--                "nodes_truenodeids": [0] * 6,
--                "leaf_weights": make_tensor(
--                    "leaf_weights", TensorProto.DOUBLE, (9,), [1] * 9
--                ),
--                "nodes_splits": make_tensor(
--                    "nodes_splits", TensorProto.DOUBLE, (5,), [1] * 5
--                ),
--            },
--            {
--                "nodes_truenodeids": [0] * 5,
--                "leaf_weights": make_tensor(
--                    "leaf_weights", TensorProto.FLOAT, (9,), [1] * 9
--                ),
--                "nodes_splits": make_tensor(
--                    "nodes_splits", TensorProto.DOUBLE, (5,), [1] * 5
--                ),
--            },
--            {
--                "nodes_truenodeids": [0] * 5,
--                "leaf_weights": make_tensor(
--                    "leaf_weights", TensorProto.DOUBLE, (18,), [1] * 18
--                ),
--                "nodes_splits": make_tensor(
--                    "nodes_splits", TensorProto.DOUBLE, (5,), [1] * 5
--                ),
--            },
--            {
--                "nodes_truenodeids": [0] * 5,
--                "leaf_weights": make_tensor(
--                    "leaf_weights", TensorProto.DOUBLE, (9,), [1] * 9
--                ),
--                "nodes_splits": make_tensor(
--                    "nodes_splits", TensorProto.FLOAT, (5,), [1] * 5
--                ),
--            },
--        ]
--    )
--    @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
--    def test_tree_ensemble_fails_if_invalid_attributes(
--        self,
--        nodes_truenodeids,
--        leaf_weights,
--        nodes_splits,
--    ) -> None:
--        interior_nodes = 5
--        leaves = 9
--        tree = make_node(
--            "TreeEnsemble",
--            ["x"],
--            ["y"],
--            domain=ONNX_ML_DOMAIN,
--            n_targets=5,
--            nodes_featureids=[0] * interior_nodes,
--            nodes_splits=nodes_splits,
--            nodes_modes=make_tensor(
--                "nodes_modes",
--                TensorProto.UINT8,
--                (interior_nodes,),
--                [0] * interior_nodes,
--            ),
--            nodes_truenodeids=nodes_truenodeids,
--            nodes_falsenodeids=[0] * interior_nodes,
--            nodes_trueleafs=[0] * interior_nodes,
--            nodes_falseleafs=[0] * interior_nodes,
--            leaf_targetids=[0] * leaves,
--            leaf_weights=leaf_weights,
--            tree_roots=[0],
--        )
--
--        graph = self._make_graph(
--            [("x", TensorProto.DOUBLE, ("Batch Size", "Features"))],
--            [tree],
--            [],
--        )
--        self.assertRaises(onnx.shape_inference.InferenceError, self._inferred, graph)
--
-     @unittest.skipUnless(ONNX_ML, "ONNX_ML required to test ai.onnx.ml operators")
-     def test_tree_ensemble_classifier(self) -> None:
-         tree = make_node(
-diff --git a/onnx/test/test_backend_reference.py b/onnx/test/test_backend_reference.py
-index 71ce7651e..b482f2778 100644
---- a/onnx/test/test_backend_reference.py
-+++ b/onnx/test/test_backend_reference.py
-@@ -193,6 +193,15 @@ backend_test.exclude("(test_eyelike_without_dtype)")
- # The following tests fail due to discrepancies (small but still higher than 1e-7).
- backend_test.exclude("test_adam_multiple")  # 1e-2
- 
-+backend_test.exclude(
-+    "("
-+    "test_affine_grid_2d_align_corners_expanded_cpu"
-+    "|test_affine_grid_2d_expanded_cpu"
-+    "|test_affine_grid_3d_align_corners_expanded_cpu"
-+    "|test_affine_grid_3d_expanded_cpu"
-+    ")"
-+)
-+
- # Currently google-re2/Pillow is not supported on Win32 and is required for the reference implementation of RegexFullMatch.
- if sys.platform == "win32":
-     backend_test.exclude("test_regex_full_match_basic_cpu")
-diff --git a/onnx/test/test_external_data.py b/onnx/test/test_external_data.py
-index fc4b2f802..d755c04cc 100644
---- a/onnx/test/test_external_data.py
-+++ b/onnx/test/test_external_data.py
-@@ -12,7 +12,6 @@ import uuid
- from typing import Any, Sequence
- 
- import numpy as np
--import parameterized
- 
- import onnx
- from onnx import (
-@@ -112,621 +111,6 @@ class TestLoadExternalDataBase(unittest.TestCase):
-         checker.check_model(self.model_filename)
- 
- 
--@parameterized.parameterized_class(
--    [
--        {"serialization_format": "protobuf"},
--        {"serialization_format": "textproto"},
--    ]
--)
--class TestLoadExternalData(TestLoadExternalDataBase):
--    def test_load_external_data(self) -> None:
--        model = onnx.load_model(self.model_filename, self.serialization_format)
--        initializer_tensor = model.graph.initializer[0]
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    def test_load_external_data_for_model(self) -> None:
--        model = onnx.load_model(
--            self.model_filename, self.serialization_format, load_external_data=False
--        )
--        load_external_data_for_model(model, self.temp_dir)
--        initializer_tensor = model.graph.initializer[0]
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    def test_save_external_data(self) -> None:
--        model = onnx.load_model(self.model_filename, self.serialization_format)
--
--        temp_dir = os.path.join(self.temp_dir, "save_copy")
--        os.mkdir(temp_dir)
--        new_model_filename = os.path.join(temp_dir, "model.onnx")
--        onnx.save_model(model, new_model_filename, self.serialization_format)
--
--        new_model = onnx.load_model(new_model_filename, self.serialization_format)
--        initializer_tensor = new_model.graph.initializer[0]
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = new_model.graph.node[0].attribute[0].t
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--
--@parameterized.parameterized_class(
--    [
--        {"serialization_format": "protobuf"},
--        {"serialization_format": "textproto"},
--    ]
--)
--class TestLoadExternalDataSingleFile(TestLoadExternalDataBase):
--    def create_external_data_tensors(
--        self, tensors_data: list[tuple[list[Any], Any]]
--    ) -> list[TensorProto]:
--        tensor_filename = "tensors.bin"
--        tensors = []
--
--        with open(os.path.join(self.temp_dir, tensor_filename), "ab") as data_file:
--            for value, tensor_name in tensors_data:
--                tensor = from_array(np.array(value))
--                offset = data_file.tell()
--                if offset % 4096 != 0:
--                    data_file.write(b"\0" * (4096 - offset % 4096))
--                    offset = offset + 4096 - offset % 4096
--
--                data_file.write(tensor.raw_data)
--                set_external_data(
--                    tensor,
--                    location=tensor_filename,
--                    offset=offset,
--                    length=data_file.tell() - offset,
--                )
--                tensor.name = tensor_name
--                tensor.ClearField("raw_data")
--                tensor.data_location = onnx.TensorProto.EXTERNAL
--                tensors.append(tensor)
--
--        return tensors
--
--    def test_load_external_single_file_data(self) -> None:
--        model = onnx.load_model(self.model_filename, self.serialization_format)
--
--        initializer_tensor = model.graph.initializer[0]
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    def test_save_external_single_file_data(self) -> None:
--        model = onnx.load_model(self.model_filename, self.serialization_format)
--
--        temp_dir = os.path.join(self.temp_dir, "save_copy")
--        os.mkdir(temp_dir)
--        new_model_filename = os.path.join(temp_dir, "model.onnx")
--        onnx.save_model(model, new_model_filename, self.serialization_format)
--
--        new_model = onnx.load_model(new_model_filename, self.serialization_format)
--        initializer_tensor = new_model.graph.initializer[0]
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = new_model.graph.node[0].attribute[0].t
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    @parameterized.parameterized.expand(itertools.product((True, False), (True, False)))
--    def test_save_external_invalid_single_file_data_and_check(
--        self, use_absolute_path: bool, use_model_path: bool
--    ) -> None:
--        model = onnx.load_model(self.model_filename, self.serialization_format)
--
--        model_dir = os.path.join(self.temp_dir, "save_copy")
--        os.mkdir(model_dir)
--
--        traversal_external_data_dir = os.path.join(
--            self.temp_dir, "invlid_external_data"
--        )
--        os.mkdir(traversal_external_data_dir)
--
--        if use_absolute_path:
--            traversal_external_data_location = os.path.join(
--                traversal_external_data_dir, "tensors.bin"
--            )
--        else:
--            traversal_external_data_location = "../invlid_external_data/tensors.bin"
--
--        external_data_dir = os.path.join(self.temp_dir, "external_data")
--        os.mkdir(external_data_dir)
--        new_model_filepath = os.path.join(model_dir, "model.onnx")
--
--        def convert_model_to_external_data_no_check(model: ModelProto, location: str):
--            for tensor in model.graph.initializer:
--                if tensor.HasField("raw_data"):
--                    set_external_data(tensor, location)
--
--        convert_model_to_external_data_no_check(
--            model,
--            location=traversal_external_data_location,
--        )
--
--        onnx.save_model(model, new_model_filepath, self.serialization_format)
--        if use_model_path:
--            with self.assertRaises(onnx.checker.ValidationError):
--                _ = onnx.load_model(new_model_filepath, self.serialization_format)
--        else:
--            onnx_model = onnx.load_model(
--                new_model_filepath, self.serialization_format, load_external_data=False
--            )
--            with self.assertRaises(onnx.checker.ValidationError):
--                load_external_data_for_model(onnx_model, external_data_dir)
--
--
--@parameterized.parameterized_class(
--    [
--        {"serialization_format": "protobuf"},
--        {"serialization_format": "textproto"},
--    ]
--)
--class TestSaveAllTensorsAsExternalData(unittest.TestCase):
--    serialization_format: str = "protobuf"
--
--    def setUp(self) -> None:
--        self._temp_dir_obj = tempfile.TemporaryDirectory()
--        self.temp_dir: str = self._temp_dir_obj.name
--        self.initializer_value = np.arange(6).reshape(3, 2).astype(np.float32) + 512
--        self.attribute_value = np.arange(6).reshape(2, 3).astype(np.float32) + 256
--        self.model = self.create_test_model_proto()
--
--    def get_temp_model_filename(self):
--        return os.path.join(self.temp_dir, str(uuid.uuid4()) + ".onnx")
--
--    def create_data_tensors(
--        self, tensors_data: list[tuple[list[Any], Any]]
--    ) -> list[TensorProto]:
--        tensors = []
--        for value, tensor_name in tensors_data:
--            tensor = from_array(np.array(value))
--            tensor.name = tensor_name
--            tensors.append(tensor)
--
--        return tensors
--
--    def create_test_model_proto(self) -> ModelProto:
--        tensors = self.create_data_tensors(
--            [
--                (self.attribute_value, "attribute_value"),  # type: ignore[list-item]
--                (self.initializer_value, "input_value"),  # type: ignore[list-item]
--            ]
--        )
--
--        constant_node = onnx.helper.make_node(
--            "Constant", inputs=[], outputs=["values"], value=tensors[0]
--        )
--
--        inputs = [
--            helper.make_tensor_value_info(
--                "input_value", onnx.TensorProto.FLOAT, self.initializer_value.shape
--            )
--        ]
--
--        graph = helper.make_graph(
--            [constant_node],
--            "test_graph",
--            inputs=inputs,
--            outputs=[],
--            initializer=[tensors[1]],
--        )
--        return helper.make_model(graph)
--
--    @unittest.skipIf(
--        serialization_format != "protobuf",
--        "check_model supports protobuf only when provided as a path",
--    )
--    def test_check_model(self) -> None:
--        checker.check_model(self.model)
--
--    def test_convert_model_to_external_data_with_size_threshold(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--
--        convert_model_to_external_data(self.model, size_threshold=1024)
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--        initializer_tensor = model.graph.initializer[0]
--        self.assertFalse(initializer_tensor.HasField("data_location"))
--
--    def test_convert_model_to_external_data_without_size_threshold(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--        convert_model_to_external_data(self.model, size_threshold=0)
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--        initializer_tensor = model.graph.initializer[0]
--        self.assertTrue(initializer_tensor.HasField("data_location"))
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--    def test_convert_model_to_external_data_from_one_file_with_location(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--        external_data_file = str(uuid.uuid4())
--
--        convert_model_to_external_data(
--            self.model,
--            size_threshold=0,
--            all_tensors_to_one_file=True,
--            location=external_data_file,
--        )
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, external_data_file)))
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--
--        # test convert model from external data
--        convert_model_from_external_data(model)
--        model_file_path = self.get_temp_model_filename()
--        onnx.save_model(model, model_file_path, self.serialization_format)
--        model = onnx.load_model(model_file_path, self.serialization_format)
--        initializer_tensor = model.graph.initializer[0]
--        self.assertFalse(len(initializer_tensor.external_data))
--        self.assertEqual(initializer_tensor.data_location, TensorProto.DEFAULT)
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        self.assertFalse(len(attribute_tensor.external_data))
--        self.assertEqual(attribute_tensor.data_location, TensorProto.DEFAULT)
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    def test_convert_model_to_external_data_from_one_file_without_location_uses_model_name(
--        self,
--    ) -> None:
--        model_file_path = self.get_temp_model_filename()
--
--        convert_model_to_external_data(
--            self.model, size_threshold=0, all_tensors_to_one_file=True
--        )
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        self.assertTrue(os.path.isfile(model_file_path))
--        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, model_file_path)))
--
--    def test_convert_model_to_external_data_one_file_per_tensor_without_attribute(
--        self,
--    ) -> None:
--        model_file_path = self.get_temp_model_filename()
--
--        convert_model_to_external_data(
--            self.model,
--            size_threshold=0,
--            all_tensors_to_one_file=False,
--            convert_attribute=False,
--        )
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        self.assertTrue(os.path.isfile(model_file_path))
--        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "input_value")))
--        self.assertFalse(os.path.isfile(os.path.join(self.temp_dir, "attribute_value")))
--
--    def test_convert_model_to_external_data_one_file_per_tensor_with_attribute(
--        self,
--    ) -> None:
--        model_file_path = self.get_temp_model_filename()
--
--        convert_model_to_external_data(
--            self.model,
--            size_threshold=0,
--            all_tensors_to_one_file=False,
--            convert_attribute=True,
--        )
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        self.assertTrue(os.path.isfile(model_file_path))
--        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "input_value")))
--        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "attribute_value")))
--
--    def test_convert_model_to_external_data_does_not_convert_attribute_values(
--        self,
--    ) -> None:
--        model_file_path = self.get_temp_model_filename()
--
--        convert_model_to_external_data(
--            self.model,
--            size_threshold=0,
--            convert_attribute=False,
--            all_tensors_to_one_file=False,
--        )
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        self.assertTrue(os.path.isfile(os.path.join(self.temp_dir, "input_value")))
--        self.assertFalse(os.path.isfile(os.path.join(self.temp_dir, "attribute_value")))
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--        initializer_tensor = model.graph.initializer[0]
--        self.assertTrue(initializer_tensor.HasField("data_location"))
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        self.assertFalse(attribute_tensor.HasField("data_location"))
--
--    def test_convert_model_to_external_data_converts_attribute_values(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--
--        convert_model_to_external_data(
--            self.model, size_threshold=0, convert_attribute=True
--        )
--        onnx.save_model(self.model, model_file_path, self.serialization_format)
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--
--        initializer_tensor = model.graph.initializer[0]
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--        self.assertTrue(initializer_tensor.HasField("data_location"))
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--        self.assertTrue(attribute_tensor.HasField("data_location"))
--
--    def test_save_model_does_not_convert_to_external_data_and_saves_the_model(
--        self,
--    ) -> None:
--        model_file_path = self.get_temp_model_filename()
--        onnx.save_model(
--            self.model,
--            model_file_path,
--            self.serialization_format,
--            save_as_external_data=False,
--        )
--        self.assertTrue(os.path.isfile(model_file_path))
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--        initializer_tensor = model.graph.initializer[0]
--        self.assertFalse(initializer_tensor.HasField("data_location"))
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        self.assertFalse(attribute_tensor.HasField("data_location"))
--
--    def test_save_model_does_convert_and_saves_the_model(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--        onnx.save_model(
--            self.model,
--            model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            all_tensors_to_one_file=True,
--            location=None,
--            size_threshold=0,
--            convert_attribute=False,
--        )
--
--        model = onnx.load_model(model_file_path, self.serialization_format)
--
--        initializer_tensor = model.graph.initializer[0]
--        self.assertTrue(initializer_tensor.HasField("data_location"))
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        self.assertFalse(attribute_tensor.HasField("data_location"))
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    def test_save_model_without_loading_external_data(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--        onnx.save_model(
--            self.model,
--            model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            location=None,
--            size_threshold=0,
--            convert_attribute=False,
--        )
--        # Save without load_external_data
--        model = onnx.load_model(
--            model_file_path, self.serialization_format, load_external_data=False
--        )
--        onnx.save_model(
--            model,
--            model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            location=None,
--            size_threshold=0,
--            convert_attribute=False,
--        )
--        # Load the saved model again; Only works if the saved path is under the same directory
--        model = onnx.load_model(model_file_path, self.serialization_format)
--
--        initializer_tensor = model.graph.initializer[0]
--        self.assertTrue(initializer_tensor.HasField("data_location"))
--        np.testing.assert_allclose(to_array(initializer_tensor), self.initializer_value)
--
--        attribute_tensor = model.graph.node[0].attribute[0].t
--        self.assertFalse(attribute_tensor.HasField("data_location"))
--        np.testing.assert_allclose(to_array(attribute_tensor), self.attribute_value)
--
--    def test_save_model_with_existing_raw_data_should_override(self) -> None:
--        model_file_path = self.get_temp_model_filename()
--        original_raw_data = self.model.graph.initializer[0].raw_data
--        onnx.save_model(
--            self.model,
--            model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            size_threshold=0,
--        )
--        self.assertTrue(os.path.isfile(model_file_path))
--
--        model = onnx.load_model(
--            model_file_path, self.serialization_format, load_external_data=False
--        )
--        initializer_tensor = model.graph.initializer[0]
--        initializer_tensor.raw_data = b"dummpy_raw_data"
--        # If raw_data and external tensor exist at the same time, override existing raw_data
--        load_external_data_for_tensor(initializer_tensor, self.temp_dir)
--        self.assertEqual(initializer_tensor.raw_data, original_raw_data)
--
--
--@parameterized.parameterized_class(
--    [
--        {"serialization_format": "protobuf"},
--        {"serialization_format": "textproto"},
--    ]
--)
--class TestExternalDataToArray(unittest.TestCase):
--    serialization_format: str = "protobuf"
--
--    def setUp(self) -> None:
--        self._temp_dir_obj = tempfile.TemporaryDirectory()
--        self.temp_dir: str = self._temp_dir_obj.name
--        self._model_file_path: str = os.path.join(self.temp_dir, "model.onnx")
--        self.large_data = np.random.rand(10, 60, 100).astype(np.float32)
--        self.small_data = (200, 300)
--        self.model = self.create_test_model()
--
--    @property
--    def model_file_path(self):
--        return self._model_file_path
--
--    def tearDown(self) -> None:
--        self._temp_dir_obj.cleanup()
--
--    def create_test_model(self) -> ModelProto:
--        X = helper.make_tensor_value_info("X", TensorProto.FLOAT, self.large_data.shape)
--        input_init = helper.make_tensor(
--            name="X",
--            data_type=TensorProto.FLOAT,
--            dims=self.large_data.shape,
--            vals=self.large_data.tobytes(),
--            raw=True,
--        )
--
--        shape_data = np.array(self.small_data, np.int64)
--        shape_init = helper.make_tensor(
--            name="Shape",
--            data_type=TensorProto.INT64,
--            dims=shape_data.shape,
--            vals=shape_data.tobytes(),
--            raw=True,
--        )
--        C = helper.make_tensor_value_info("C", TensorProto.INT64, self.small_data)
--
--        reshape = onnx.helper.make_node(
--            "Reshape",
--            inputs=["X", "Shape"],
--            outputs=["Y"],
--        )
--        cast = onnx.helper.make_node(
--            "Cast", inputs=["Y"], outputs=["C"], to=TensorProto.INT64
--        )
--
--        graph_def = helper.make_graph(
--            [reshape, cast],
--            "test-model",
--            [X],
--            [C],
--            initializer=[input_init, shape_init],
--        )
--        model = helper.make_model(graph_def, producer_name="onnx-example")
--        return model
--
--    @unittest.skipIf(
--        serialization_format != "protobuf",
--        "check_model supports protobuf only when provided as a path",
--    )
--    def test_check_model(self) -> None:
--        checker.check_model(self.model)
--
--    def test_reshape_inference_with_external_data_fail(self) -> None:
--        onnx.save_model(
--            self.model,
--            self.model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            all_tensors_to_one_file=False,
--            size_threshold=0,
--        )
--        model_without_external_data = onnx.load(
--            self.model_file_path, self.serialization_format, load_external_data=False
--        )
--        # Shape inference of Reshape uses ParseData
--        # ParseData cannot handle external data and should throw the error as follows:
--        # Cannot parse data from external tensors. Please load external data into raw data for tensor: Shape
--        self.assertRaises(
--            shape_inference.InferenceError,
--            shape_inference.infer_shapes,
--            model_without_external_data,
--            strict_mode=True,
--        )
--
--    def test_to_array_with_external_data(self) -> None:
--        onnx.save_model(
--            self.model,
--            self.model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            all_tensors_to_one_file=False,
--            size_threshold=0,
--        )
--        # raw_data of external tensor is not loaded
--        model = onnx.load(
--            self.model_file_path, self.serialization_format, load_external_data=False
--        )
--        # Specify self.temp_dir to load external tensor
--        loaded_large_data = to_array(model.graph.initializer[0], self.temp_dir)
--        np.testing.assert_allclose(loaded_large_data, self.large_data)
--
--    def test_save_model_with_external_data_multiple_times(self) -> None:
--        # Test onnx.save should respectively handle typical tensor and external tensor properly
--        # 1st save: save two tensors which have raw_data
--        # Only w_large will be stored as external tensors since it's larger than 1024
--        onnx.save_model(
--            self.model,
--            self.model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            all_tensors_to_one_file=False,
--            location=None,
--            size_threshold=1024,
--            convert_attribute=True,
--        )
--        model_without_loading_external = onnx.load(
--            self.model_file_path, self.serialization_format, load_external_data=False
--        )
--        large_input_tensor = model_without_loading_external.graph.initializer[0]
--        self.assertTrue(large_input_tensor.HasField("data_location"))
--        np.testing.assert_allclose(
--            to_array(large_input_tensor, self.temp_dir), self.large_data
--        )
--
--        small_shape_tensor = model_without_loading_external.graph.initializer[1]
--        self.assertTrue(not small_shape_tensor.HasField("data_location"))
--        np.testing.assert_allclose(to_array(small_shape_tensor), self.small_data)
--
--        # 2nd save: one tensor has raw_data (small); one external tensor (large)
--        # Save them both as external tensors this time
--        onnx.save_model(
--            model_without_loading_external,
--            self.model_file_path,
--            self.serialization_format,
--            save_as_external_data=True,
--            all_tensors_to_one_file=False,
--            location=None,
--            size_threshold=0,
--            convert_attribute=True,
--        )
--
--        model_without_loading_external = onnx.load(
--            self.model_file_path, self.serialization_format, load_external_data=False
--        )
--        large_input_tensor = model_without_loading_external.graph.initializer[0]
--        self.assertTrue(large_input_tensor.HasField("data_location"))
--        np.testing.assert_allclose(
--            to_array(large_input_tensor, self.temp_dir), self.large_data
--        )
--
--        small_shape_tensor = model_without_loading_external.graph.initializer[1]
--        self.assertTrue(small_shape_tensor.HasField("data_location"))
--        np.testing.assert_allclose(
--            to_array(small_shape_tensor, self.temp_dir), self.small_data
--        )
--
--
- class TestNotAllowToLoadExternalDataOutsideModelDirectory(TestLoadExternalDataBase):
-     """Essential test to check that onnx (validate) C++ code will not allow to load external_data outside the model
-     directory.
-@@ -791,17 +175,6 @@ class TestNotAllowToLoadExternalDataOutsideModelDirectoryOnWindows(
-             checker.check_model(self.model_filename)
- 
- 
--class TestSaveAllTensorsAsExternalDataWithPath(TestSaveAllTensorsAsExternalData):
--    def get_temp_model_filename(self) -> pathlib.Path:
--        return pathlib.Path(super().get_temp_model_filename())
--
--
--class TestExternalDataToArrayWithPath(TestExternalDataToArray):
--    @property
--    def model_file_path(self) -> pathlib.Path:
--        return pathlib.Path(self._model_file_path)
--
--
- class TestFunctionsAndSubGraphs(unittest.TestCase):
-     def setUp(self) -> None:
-         self._temp_dir_obj = tempfile.TemporaryDirectory()
-diff --git a/onnx/test/tools_test.py b/onnx/test/tools_test.py
-index fd4413786..f843c1fbc 100644
---- a/onnx/test/tools_test.py
-+++ b/onnx/test/tools_test.py
-@@ -112,32 +112,6 @@ class TestToolsFunctions(unittest.TestCase):
-         y2 = oinf2.run(None, {"X": x})[0]  # type: ignore[index]
-         assert_allclose(y1, y2)
- 
--    def test_replace_range(self):
--        dtype = np.float32
--        value = np.random.randn(2, 100).astype(dtype)
--        A = numpy_helper.from_array(value, name="A")
--        value = np.array([1], dtype=dtype)
--        C = numpy_helper.from_array(value, name="C")
--
--        X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [None, None])
--        Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [None])
--        node0 = helper.make_node("Constant", [], ["A"], value=A)
--        node1 = helper.make_node("MatMul", ["X", "A"], ["AX"])
--        node2 = helper.make_node("Sub", ["AX", "C"], ["Y"])
--        graph = helper.make_graph([node0, node1, node2], "lr", [X], [Y], [C])
--        model_def = helper.make_model(graph)
--
--        x = np.array([1, 2, 4, 5, 5, 4]).astype(np.float32).reshape((3, 2))
--        oinf1 = ReferenceEvaluator(model_def)
--        y1 = oinf1.run(None, {"X": x})[0]  # type: ignore[index]
--        repl = replace_initializer_by_constant_of_shape(model_def, use_range=True)
--        node_types = {n.op_type for n in repl.graph.node}
--        self.assertIn("Range", node_types)
--        self.assertNotIn("ConstantOfShape", node_types)
--        oinf2 = ReferenceEvaluator(repl)
--        y2 = oinf2.run(None, {"X": x})[0]  # type: ignore[index]
--        assert_allclose(y1.shape, y2.shape)
--
-     def test_replace_constant_function(self):
-         dtype = np.float32
-         value = np.random.randn(2, 100).astype(dtype)
-@@ -182,49 +156,6 @@ class TestToolsFunctions(unittest.TestCase):
-         y2 = oinf2.run(None, {"X": x})[0]  # type: ignore[index]
-         assert_allclose(y1, y2)
- 
--    def test_replace_range_function(self):
--        dtype = np.float32
--        value = np.random.randn(2, 100).astype(dtype)
--        A = numpy_helper.from_array(value, name="A")
--        value = np.array([1], dtype=dtype)
--        C = numpy_helper.from_array(value, name="C")
--
--        X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [None, None])
--        Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [None])
--        nodeC = helper.make_node("Constant", [], ["C"], value=C)
--        node0 = helper.make_node("Constant", [], ["A"], value=A)
--        node1 = helper.make_node("MatMul", ["X", "A"], ["AX"])
--        node2 = helper.make_node("Sub", ["AX", "C"], ["Y"])
--        opset_imports = [
--            helper.make_opsetid("", onnx_opset_version()),
--            helper.make_opsetid("custom", 1),
--        ]
--        fct = helper.make_function(
--            "custom",
--            "unittest",
--            ["X"],
--            ["Y"],
--            [nodeC, node0, node1, node2],
--            opset_imports,
--        )
--
--        node = helper.make_node("unittest", ["X"], ["Y"], domain="custom")
--        graph = helper.make_graph([node], "lr", [X], [Y], [C])
--        model_def = helper.make_model(
--            graph, functions=[fct], opset_imports=opset_imports
--        )
--
--        x = np.array([1, 2, 4, 5, 5, 4]).astype(np.float32).reshape((3, 2))
--        oinf1 = ReferenceEvaluator(model_def)
--        y1 = oinf1.run(None, {"X": x})[0]  # type: ignore[index]
--        repl = replace_initializer_by_constant_of_shape(model_def, use_range=True)
--        node_types = {n.op_type for n in repl.functions[0].node}
--        self.assertIn("Range", node_types)
--        self.assertNotIn("ConstantOfShape", node_types)
--        oinf2 = ReferenceEvaluator(repl)
--        y2 = oinf2.run(None, {"X": x})[0]  # type: ignore[index]
--        assert_allclose(y1.shape, y2.shape)
--
-     def test_replace_constant_graph(self):
-         value = np.array([0], dtype=np.float32)
-         zero = numpy_helper.from_array(value, name="zero")
-@@ -274,54 +205,6 @@ class TestToolsFunctions(unittest.TestCase):
-         y1[:] = 0.5
-         assert_allclose(y1, y2)
- 
--    def test_replace_range_graph(self):
--        value = np.array([0], dtype=np.float32)
--        zero = numpy_helper.from_array(value, name="zero")
--
--        X = helper.make_tensor_value_info("X", onnx.TensorProto.FLOAT, [None, None])
--        Y = helper.make_tensor_value_info("Y", onnx.TensorProto.FLOAT, [None])
--
--        rsum = helper.make_node("ReduceSum", ["X"], ["rsum"])
--        cond = helper.make_node("Greater", ["rsum", "zero"], ["cond"])
--
--        then_out = helper.make_tensor_value_info(
--            "then_out", onnx.TensorProto.FLOAT, None
--        )
--        then_cst = numpy_helper.from_array(np.array([1] * 129).astype(np.float32))
--
--        then_const_node = helper.make_node(
--            "Constant", inputs=[], outputs=["then_out"], value=then_cst, name="cst1"
--        )
--        then_body = helper.make_graph([then_const_node], "then_body", [], [then_out])
--
--        else_out = helper.make_tensor_value_info(
--            "else_out", onnx.TensorProto.FLOAT, None
--        )
--        else_cst = numpy_helper.from_array(np.array([-1] * 129).astype(np.float32))
--        else_const_node = helper.make_node(
--            "Constant", inputs=[], outputs=["else_out"], value=else_cst, name="cst2"
--        )
--        else_body = helper.make_graph([else_const_node], "else_body", [], [else_out])
--
--        if_node = onnx.helper.make_node(
--            "If", ["cond"], ["Y"], then_branch=then_body, else_branch=else_body
--        )
--        graph = helper.make_graph([rsum, cond, if_node], "if", [X], [Y], [zero])
--        onnx_model = helper.make_model(
--            graph, opset_imports=[helper.make_opsetid("", onnx_opset_version())]
--        )
--        self.assertNotIn("ConstantOfShape", str(onnx_model))
--
--        x = np.ones((3, 2), dtype=np.float32)
--        oinf1 = ReferenceEvaluator(onnx_model)
--        y1 = oinf1.run(None, {"X": x})[0]  # type: ignore[index]
--        repl = replace_initializer_by_constant_of_shape(onnx_model, use_range=True)
--        self.assertNotIn("ConstantOfShape", str(repl))
--        self.assertIn("Range", str(repl))
--        oinf2 = ReferenceEvaluator(repl)
--        y2 = oinf2.run(None, {"X": x})[0]  # type: ignore[index]
--        assert_allclose(y1.shape, y2.shape)
--
- 
- if __name__ == "__main__":
-     unittest.main(verbosity=2)
-diff --git a/onnx/test/version_converter/automatic_downgrade_test.py b/onnx/test/version_converter/automatic_downgrade_test.py
-index a94aea1a9..f639d44f8 100644
---- a/onnx/test/version_converter/automatic_downgrade_test.py
-+++ b/onnx/test/version_converter/automatic_downgrade_test.py
-@@ -7,7 +7,6 @@ import unittest
- 
- import automatic_conversion_test_base
- import numpy as np
--import parameterized
- 
- import onnx
- from onnx import helper
-@@ -22,35 +21,6 @@ class TestAutomaticDowngrade(automatic_conversion_test_base.TestAutomaticConvers
-     def _test_op_downgrade(self, op: str, *args, **kwargs):
-         self._test_op_conversion(op, *args, **kwargs, is_upgrade=False)
- 
--    @parameterized.parameterized.expand(
--        [
--            "ReduceL1",
--            "ReduceL2",
--            "ReduceLogSum",
--            "ReduceLogSumExp",
--            "ReduceMean",
--            "ReduceMax",
--            "ReduceMin",
--            "ReduceProd",
--            "ReduceSum",
--            "ReduceSumSquare",
--        ]
--    )
--    def test_reduce_ops(self, op) -> None:
--        # TODO: need to add test cases for missing axes input which depends on this pr:
--        # https://github.com/onnx/onnx/pull/5613
--        axes = helper.make_tensor(
--            "b", onnx.TensorProto.INT64, dims=[3], vals=np.array([0, 1, 2])
--        )
--        self._test_op_downgrade(
--            op,
--            from_opset=13,
--            input_shapes=[[3, 4, 5], [3]],
--            output_shapes=[[1, 1, 1]],
--            input_types=[onnx.TensorProto.FLOAT, onnx.TensorProto.INT64],
--            initializer=[axes],
--        )
--
-     def test_dft20_no_axis(self) -> None:
-         self._test_model_conversion(
-             to_opset=19,
-diff --git a/onnx/test/version_converter_test.py b/onnx/test/version_converter_test.py
-index 1790e5997..4a4c27766 100644
---- a/onnx/test/version_converter_test.py
-+++ b/onnx/test/version_converter_test.py
-@@ -8,7 +8,6 @@ import struct
- import unittest
- 
- import numpy as np
--import parameterized
- 
- import onnx.version_converter
- from onnx import (
-@@ -2006,169 +2005,6 @@ class TestVersionConverter(unittest.TestCase):
-         assert converted_model.graph.node[3].op_type == "Reshape"
-         assert converted_model.opset_import[0].version == 13
- 
--    @parameterized.parameterized.expand(
--        [
--            ("per_tensor", (16, 3), (1,), None, None, None, TensorProto.INT8, True),
--            (
--                "per_axis_none_block_shape",
--                (16, 3),
--                (16,),
--                1,
--                None,
--                None,
--                TensorProto.INT8,
--                True,
--            ),
--            (
--                "per_axis_zero_block_shape",
--                (16, 3),
--                (16,),
--                1,
--                0,
--                None,
--                TensorProto.INT8,
--                True,
--            ),
--            (
--                "per_tensor_positive_block_shape",
--                (16, 3),
--                (1,),
--                1,
--                2,
--                None,
--                TensorProto.INT8,
--                False,
--            ),
--            (
--                "per_axis_positive_block_shape",
--                (16, 3),
--                (16,),
--                1,
--                2,
--                None,
--                TensorProto.INT8,
--                False,
--            ),
--            ("blocked_2d", (16, 3), (4, 3), 0, 4, None, TensorProto.INT8, False),
--            ("blocked_3d", (4, 3, 32), (4, 3, 8), 2, 4, None, TensorProto.INT8, False),
--            (
--                "per_axis_output_dtype",
--                (16, 3),
--                (16,),
--                1,
--                None,
--                TensorProto.FLOAT8E4M3FN,
--                None,
--                False,
--            ),
--            (
--                "per_axis_unsupported_type",
--                (16, 3),
--                (16,),
--                1,
--                None,
--                None,
--                TensorProto.UINT16,
--                False,
--            ),
--        ]
--    )
--    def test_quantize_21_20(
--        self,
--        _: str,
--        x_shape: tuple[int, ...],
--        scale_shape: tuple[int, ...],
--        axis: int,
--        block_size: int,
--        output_dtype: int | None,
--        zero_point_dtype: int | None,
--        compatible: bool,
--    ) -> None:
--        def test(
--            input_shape, scale_shape, axis, block_size, output_dtype, zero_point_dtype
--        ) -> None:
--            nodes = [
--                helper.make_node(
--                    "QuantizeLinear",
--                    ["X", "S"],
--                    ["Y"],
--                    axis=axis,
--                    block_size=block_size,
--                    output_dtype=output_dtype,
--                )
--            ]
--            inputs = [
--                helper.make_tensor_value_info("X", TensorProto.FLOAT, input_shape),
--                helper.make_tensor_value_info("S", TensorProto.FLOAT, scale_shape),
--            ]
--            if zero_point_dtype:
--                inputs.append(
--                    helper.make_tensor_value_info("ZP", zero_point_dtype, scale_shape)
--                )
--                nodes[0].input.append("ZP")
--            output_type_ = output_dtype or zero_point_dtype
--            graph = helper.make_graph(
--                nodes,
--                "test",
--                inputs,
--                [helper.make_tensor_value_info("Y", output_type_, input_shape)],
--            )
--            _ = self._converted(graph, helper.make_operatorsetid("", 21), 20)
--
--        context_manager = (
--            contextlib.nullcontext() if compatible else self.assertRaises(RuntimeError)
--        )
--        with context_manager:  # type: ignore[attr-defined]
--            test(x_shape, scale_shape, axis, block_size, output_dtype, zero_point_dtype)
--
--    @parameterized.parameterized.expand(
--        [
--            ("per_tensor", (16, 3), (1,), None, None, True),
--            ("per_axis_none_block_shape", (16, 3), (16,), 1, None, True),
--            ("per_axis_zero_block_shape", (16, 3), (16,), 1, 0, True),
--            ("per_tensor_positive_block_shape", (16, 3), (1,), 1, 2, False),
--            ("per_axis_positive_block_shape", (16, 3), (16,), 1, 2, False),
--            ("blocked_2d", (16, 3), (4, 3), 0, 4, False),
--            ("blocked_3d", (4, 3, 32), (4, 3, 8), 2, 4, False),
--        ]
--    )
--    def test_dequantize_21_20(
--        self,
--        _: str,
--        y_shape: tuple[int, ...],
--        scale_shape: tuple[int, ...],
--        axis: int,
--        block_size: int,
--        compatible: bool,
--    ) -> None:
--        def test(input_shape, scale_shape, axis, block_size) -> None:
--            nodes = [
--                helper.make_node(
--                    "DequantizeLinear",
--                    ["X", "S", "ZP"],
--                    ["Y"],
--                    axis=axis,
--                    block_size=block_size,
--                )
--            ]
--            graph = helper.make_graph(
--                nodes,
--                "test",
--                [
--                    helper.make_tensor_value_info("X", TensorProto.INT8, input_shape),
--                    helper.make_tensor_value_info("S", TensorProto.FLOAT, scale_shape),
--                    helper.make_tensor_value_info("ZP", TensorProto.INT8, scale_shape),
--                ],
--                [helper.make_tensor_value_info("Y", TensorProto.FLOAT, input_shape)],
--            )
--            _ = self._converted(graph, helper.make_operatorsetid("", 21), 20)
--
--        context_manager = (
--            contextlib.nullcontext() if compatible else self.assertRaises(RuntimeError)
--        )
--        with context_manager:  # type: ignore[attr-defined]
--            test(y_shape, scale_shape, axis, block_size)
--
- 
- if __name__ == "__main__":
-     unittest.main()
-diff --git a/requirements-dev.txt b/requirements-dev.txt
-index ea38712d8..165b3f7f4 100644
---- a/requirements-dev.txt
-+++ b/requirements-dev.txt
-@@ -2,7 +2,6 @@ build
- jupyter
- nbval
- numpy
--parameterized
- protobuf
- pytest
- pytest-cov
-diff --git a/requirements-release.txt b/requirements-release.txt
-index 9a9d85351..0c19ebdb5 100644
---- a/requirements-release.txt
-+++ b/requirements-release.txt
-@@ -3,7 +3,6 @@ ipython
- nbval
- numpy==1.24.3; python_version<"3.9"
- numpy==2.0.0; python_version>="3.9"
--parameterized
- protobuf==4.21.12; python_version<"3.12"
- protobuf==4.25.1; python_version>="3.12"
- pytest
-diff --git a/requirements.txt b/requirements.txt
-index 46dd7f7fd..62dac8a3b 100644
---- a/requirements.txt
-+++ b/requirements.txt
-@@ -1,3 +1,2 @@
- numpy>=1.20
- protobuf >= 3.14.0, < 4
--parameterized >= 0.8.1, < 1
--- 
-2.52.0
-

diff --git a/changelog b/changelog
new file mode 100644
index 0000000..7a35d96
--- /dev/null
+++ b/changelog
@@ -0,0 +1,108 @@
+* Thu Jun 04 2026 Python Maint <python-maint@redhat.com> - 1.17.0-15
+- Rebuilt for Python 3.15
+
+* Wed Feb 21 2024 Diego Herrera C <dherrera@redhat.com>- 1.21.0-1
+- Update to 1.21.0
+
+* Sun May 04 2026 Autumn Nash <autumnnash@microsoft.com> - 1.17.0-13
+- Replace hardcoded redhat-linux-build with %%{_vpath_builddir} via env var
+
+* Mon Feb 16 2026 Diego Herrera <dherrera@fedoraproject.org> - 1.17.0-12
+- Re-enable s390x
+
+* Tue Feb 10 2026 Marcin Juszkiewicz - 1.17.0-11
+- skip 3 tests on riscv64: test_float8_e4m3fn_negative_nan,
+  test_float8_e5m2_negative_nan, test_maxpool_2d_uint8_cpu
+
+* Fri Jan 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 1.17.0-10
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
+
+* Thu Jan 15 2026 Diego Herrera <dherrera@fedoraproject.org> - 1.17.0-9
+- Disable tests that depend on python-parameterized
+- Clean up patches
+
+* Fri Sep 19 2025 Python Maint <python-maint@redhat.com> - 1.17.0-8
+- Rebuilt for Python 3.14.0rc3 bytecode
+
+* Fri Aug 15 2025 Python Maint <python-maint@redhat.com> - 1.17.0-7
+- Rebuilt for Python 3.14.0rc2 bytecode
+
+* Thu Jul 24 2025 Fedora Release Engineering <releng@fedoraproject.org> - 1.17.0-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
+
+* Tue Jun 17 2025 Python Maint <python-maint@redhat.com> - 1.17.0-5
+- Rebuilt for Python 3.14
+
+* Fri Mar 28 2025 Miro Hrončok <mhroncok@redhat.com> - 1.17.0-4
+- Don't needlessly try to generate test requirements by tox
+- Fixes: rhbz#2354087
+
+* Sat Jan 18 2025 Benjamin A. Beasley <code@musicinmybrain.net> - 1.17.0-3
+- Drop i686 support (leaf package on that architecture)
+
+* Fri Jan 17 2025 Fedora Release Engineering <releng@fedoraproject.org> - 1.17.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
+
+* Fri Oct 25 2024 Sandro <devel@penguinpee.nl> - 1.17.0-1
+- Update to 1.17.0 (RHBZ#2235011)
+- Add support for NumPy 2.x
+
+* Thu Jul 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.15.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
+
+* Tue Jul 02 2024 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.15.0-3
+- Backport of fix for CVE-2024-5187
+
+* Sat Jun 08 2024 Python Maint <python-maint@redhat.com> - 1.15.0-2
+- Rebuilt for Python 3.13
+
+* Thu Apr 11 2024 Diego Herrera C <dherrera@redhat.com> - 1.15.0-1
+- Release 1.15.0
+
+* Sat Feb 24 2024 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.1-2
+- Backport of fixes for CVE-2024-27318 and CVE-2024-27319
+
+* Wed Feb 21 2024 Diego Herrera C <dherrera@redhat.com>- 1.14.1-1
+- Release 1.14.1
+
+* Tue Jan 23 2024 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.0-10
+- Build using protobuf-devel
+
+* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Wed Sep 20 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-8
+- Fix onnxruntime patch
+
+* Wed Aug 30 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-7
+- Add fix to use with onnxruntime
+
+* Sat Aug 5 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-6
+- Lower version requirement for parameterized.
+- Lower version requirement for protobuf.
+
+* Sat Aug 5 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-5
+- Build python libs using the proper macros.
+
+* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Mon Jun 19 2023 Python Maint <python-maint@redhat.com> - 1.14.0-3
+- Rebuilt for Python 3.12
+
+* Wed Jun 07 2023 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.0-2
+- Patch protobuf headers with ONNX_API
+- Ship .proto files
+
+* Sat Jun 03 2023 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.0-1
+- Release 1.14.0
+
+* Thu May 18 2023 Diego Herrera <dherrera@redhat.com> - 1.13.0-3
+- Fix License entry to comply with SPDX
+- Add onnx-libs as an explicit dependency to the python package
+
+* Sat Dec 17 2022 Alejandro Alvarez Ayllon <aalvarez@fedoraproject.org> - 1.13.0-2
+- Release 1.13.0
+
+* Wed Nov 23 2022 Alejandro Alvarez Ayllon <aalvarez@fedoraproject.org> - 1.12.0-1
+- Release 1.12.0

diff --git a/onnx.spec b/onnx.spec
index f08b051..ef0e8a5 100644
--- a/onnx.spec
+++ b/onnx.spec
@@ -1,6 +1,8 @@
+%global so_version 1
+
 Name:       onnx
-Version:    1.17.0
-Release:    15%{?dist}
+Version:    1.21.0
+Release:    %autorelease
 Summary:    Open standard for machine learning interoperability
 License:    Apache-2.0
 
@@ -8,14 +10,8 @@ URL:        https://github.com/onnx/onnx
 Source0:    https://github.com/onnx/onnx/archive/v%{version}/%{name}-%{version}.tar.gz
 # Build shared libraries and fix install location 
 Patch:     0000-Build-shared-libraries-and-fix-install-location.patch
-# Use system protobuf and require parameterized
-Patch:     0001-Use-system-protobuf-and-require-parameterized.patch
-# Let pyproject_wheel use binaries from cmake_build
-Patch:     0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
-# Add fixes for use with onnxruntime
-Patch:     0003-Add-fixes-for-use-with-onnxruntime.patch
-# Add fixes for use with onnxruntime
-Patch:     0004-Remove-python-parameterized-dependency.patch
+# Remove obsoleted testing dependency
+Patch:     0002-Remove-python-parameterized-dependency.patch
 
 %if %{undefined fc40} && %{undefined fc41}
 # https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
@@ -32,7 +28,9 @@ BuildRequires:  python3-devel
 BuildRequires:  python3-pip
 BuildRequires:  python3-pybind11
 BuildRequires:  python3-pytest
-BuildRequires:  protobuf3-devel
+BuildRequires:  python3-nanobind
+BuildRequires:  python3-ml-dtypes 
+BuildRequires:  protobuf-devel
 
 %global _description %{expand:
 %{name} provides an open source format for AI models, both deep learning and
@@ -61,15 +59,6 @@ Requires:   %{name}-libs = %{version}-%{release}
 %prep
 %autosetup -p1 -n onnx-%{version}
 
-# Use system protobuf
-sed -r -i 's/protobuf>=3.20.2/protobuf>=3.14.0/' pyproject.toml
-
-# Drop nbval options from pytest. Plugin is not available in Fedora.
-sed -r \
-    -e 's/--nbval //' \
-    -e 's/--nbval-current-env //' \
-    -i pyproject.toml
-
 %generate_buildrequires
 %pyproject_buildrequires requirements-reference.txt
 
@@ -78,13 +67,13 @@ export VPATH_BUILDDIR=%{_vpath_builddir}
 %cmake \
     -DONNX_USE_LITE_PROTO=OFF \
     -DONNX_USE_PROTOBUF_SHARED_LIBS=ON \
-    -DBUILD_ONNX_PYTHON=ON \
-    -DPYTHON_EXECUTABLE=%{python3} \
+    -DONNX_BUILD_PYTHON=ON \
+    -DPython_EXECUTABLE=python3.14 \
     -DPY_EXT_SUFFIX=%{python3_ext_suffix} \
     -DPY_SITEARCH=%{python3_sitearch} \
-    -DCMAKE_SKIP_RPATH:BOOL=ON
-# Generate protobuf header and source files
-%cmake_build -- gen_onnx_proto
+    -DCMAKE_SKIP_RPATH:BOOL=ON \
+    -DONNX_DISABLE_STATIC_REGISTRATION=ON
+
 # Build 
 %cmake_build
 # Build python libs
@@ -116,8 +105,8 @@ export PYTEST_ADDOPTS="-k 'not test_make_tensor_raw'"
 %files libs
 %license LICENSE
 %doc README.md
-%{_libdir}/libonnx.so.%{version}
-%{_libdir}/libonnx_proto.so.%{version}
+%{_libdir}/libonnx.so.%{so_version}{,.*}
+%{_libdir}/libonnx_proto.so.%{so_version}{,.*}
 
 %files devel
 %{_libdir}/libonnx.so
@@ -131,111 +120,4 @@ export PYTEST_ADDOPTS="-k 'not test_make_tensor_raw'"
 %{_bindir}/check-node
 
 %changelog
-* Thu Jun 04 2026 Python Maint <python-maint@redhat.com> - 1.17.0-15
-- Rebuilt for Python 3.15
-
-* Wed May 13 2026 Miroslav Suchy <msuchy@redhat.com> - 1.17.0-14
-- Use protobuf3 instead of protobuf
-
-* Sun May 04 2026 Autumn Nash <autumnnash@microsoft.com> - 1.17.0-13
-- Replace hardcoded redhat-linux-build with %%{_vpath_builddir} via env var
-
-* Mon Feb 16 2026 Diego Herrera <dherrera@fedoraproject.org> - 1.17.0-12
-- Re-enable s390x
-
-* Tue Feb 10 2026 Marcin Juszkiewicz - 1.17.0-11
-- skip 3 tests on riscv64: test_float8_e4m3fn_negative_nan,
-  test_float8_e5m2_negative_nan, test_maxpool_2d_uint8_cpu
-
-* Fri Jan 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 1.17.0-10
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
-
-* Thu Jan 15 2026 Diego Herrera <dherrera@fedoraproject.org> - 1.17.0-9
-- Disable tests that depend on python-parameterized
-- Clean up patches
-
-* Fri Sep 19 2025 Python Maint <python-maint@redhat.com> - 1.17.0-8
-- Rebuilt for Python 3.14.0rc3 bytecode
-
-* Fri Aug 15 2025 Python Maint <python-maint@redhat.com> - 1.17.0-7
-- Rebuilt for Python 3.14.0rc2 bytecode
-
-* Thu Jul 24 2025 Fedora Release Engineering <releng@fedoraproject.org> - 1.17.0-6
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
-
-* Tue Jun 17 2025 Python Maint <python-maint@redhat.com> - 1.17.0-5
-- Rebuilt for Python 3.14
-
-* Fri Mar 28 2025 Miro Hrončok <mhroncok@redhat.com> - 1.17.0-4
-- Don't needlessly try to generate test requirements by tox
-- Fixes: rhbz#2354087
-
-* Sat Jan 18 2025 Benjamin A. Beasley <code@musicinmybrain.net> - 1.17.0-3
-- Drop i686 support (leaf package on that architecture)
-
-* Fri Jan 17 2025 Fedora Release Engineering <releng@fedoraproject.org> - 1.17.0-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
-
-* Fri Oct 25 2024 Sandro <devel@penguinpee.nl> - 1.17.0-1
-- Update to 1.17.0 (RHBZ#2235011)
-- Add support for NumPy 2.x
-
-* Thu Jul 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.15.0-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
-
-* Tue Jul 02 2024 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.15.0-3
-- Backport of fix for CVE-2024-5187
-
-* Sat Jun 08 2024 Python Maint <python-maint@redhat.com> - 1.15.0-2
-- Rebuilt for Python 3.13
-
-* Thu Apr 11 2024 Diego Herrera C <dherrera@redhat.com> - 1.15.0-1
-- Release 1.15.0
-
-* Sat Feb 24 2024 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.1-2
-- Backport of fixes for CVE-2024-27318 and CVE-2024-27319
-
-* Wed Feb 21 2024 Diego Herrera C <dherrera@redhat.com>- 1.14.1-1
-- Release 1.14.1
-
-* Tue Jan 23 2024 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.0-10
-- Build using protobuf-devel
-
-* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-9
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
-
-* Wed Sep 20 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-8
-- Fix onnxruntime patch
-
-* Wed Aug 30 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-7
-- Add fix to use with onnxruntime
-
-* Sat Aug 5 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-6
-- Lower version requirement for parameterized.
-- Lower version requirement for protobuf.
-
-* Sat Aug 5 2023 Diego Herrera C <dherrera@redhat.com> - 1.14.0-5
-- Build python libs using the proper macros.
-
-* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
-
-* Mon Jun 19 2023 Python Maint <python-maint@redhat.com> - 1.14.0-3
-- Rebuilt for Python 3.12
-
-* Wed Jun 07 2023 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.0-2
-- Patch protobuf headers with ONNX_API
-- Ship .proto files
-
-* Sat Jun 03 2023 Alejandro Alvarez Ayllon <a.alvarezayllon@gmail.com> - 1.14.0-1
-- Release 1.14.0
-
-* Thu May 18 2023 Diego Herrera <dherrera@redhat.com> - 1.13.0-3
-- Fix License entry to comply with SPDX
-- Add onnx-libs as an explicit dependency to the python package
-
-* Sat Dec 17 2022 Alejandro Alvarez Ayllon <aalvarez@fedoraproject.org> - 1.13.0-2
-- Release 1.13.0
-
-* Wed Nov 23 2022 Alejandro Alvarez Ayllon <aalvarez@fedoraproject.org> - 1.12.0-1
-- Release 1.12.0
+%autochangelog

diff --git a/sources b/sources
index e375b38..06ede11 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (onnx-1.17.0.tar.gz) = 5a18e2b19ec9c18c8b115fb7e12ed98eddaa581c95f15c4dd420cd6c86e7caa04f9a393da589e76b89cf9b3544abd3749a8c77c2446782f37502eb74e9b1f661
+SHA512 (onnx-1.21.0.tar.gz) = 3cee4c0fbc9e260e360a62a59e324e0b127a5749f958e0704989b407a4c1179c637ef86e41a406e7868537a62a11a821e3433005eb0725f979145f8d514926bd

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-08 15:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-08 15:18 [rpms/onnx] test-1.21.0: Release 1.21.0 Diego Herrera

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox