public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/onnx] test-1.21.0: Disable tests that depend on python-parameterized
@ 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 : 8f9af18ab5adc738cb55ab43512e8c94bcc7e16f
Author : Diego Herrera <dherrera@redhat.com>
Date   : 2026-01-15T20:17:01-03:00
Stats  : +5823/-207 in 11 file(s)
URL    : https://src.fedoraproject.org/rpms/onnx/c/8f9af18ab5adc738cb55ab43512e8c94bcc7e16f?branch=test-1.21.0

Log:
Disable tests that depend on python-parameterized

---
diff --git a/.gitignore b/.gitignore
index 7a219dd..7102235 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+results_*
+*.rpm
 /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 6ba8967..39511d1 100644
--- a/0000-Build-shared-libraries-and-fix-install-location.patch
+++ b/0000-Build-shared-libraries-and-fix-install-location.patch
@@ -8,10 +8,10 @@ Subject: [PATCH 0/6] Build shared libraries and fix install location
  1 file changed, 20 insertions(+), 2 deletions(-)
 
 diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 4dd56b6e..7f79cc9a 100644
+index d15d97edc..d6e04d2e9 100644
 --- a/CMakeLists.txt
 +++ b/CMakeLists.txt
-@@ -367,7 +367,7 @@ list(REMOVE_ITEM __tmp_srcs "${ONNX_ROOT}/onnx/cpp2py_export.cc")
+@@ -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})
  
@@ -20,7 +20,7 @@ index 4dd56b6e..7f79cc9a 100644
  add_dependencies(onnx_proto gen_onnx_operators_proto gen_onnx_data_proto)
  target_include_directories(onnx_proto PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-@@ -400,6 +400,8 @@ else()
+@@ -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)
@@ -29,7 +29,7 @@ index 4dd56b6e..7f79cc9a 100644
  endif()
  target_compile_definitions(onnx_proto PRIVATE ${ONNX_API_DEFINE})
  
-@@ -423,7 +425,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
+@@ -522,7 +524,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
    # So, create a object library
    add_library(onnx OBJECT ${ONNX_SRCS})
  else()
@@ -40,7 +40,7 @@ index 4dd56b6e..7f79cc9a 100644
  endif()
  
  target_include_directories(onnx PUBLIC
-@@ -606,6 +610,17 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
+@@ -689,6 +693,17 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
          FILES_MATCHING
          PATTERN "*.h")
  
@@ -58,7 +58,7 @@ index 4dd56b6e..7f79cc9a 100644
  configure_file(
    ${PROJECT_SOURCE_DIR}/cmake/ONNXConfigVersion.cmake.in
    ${PROJECT_BINARY_DIR}/ONNXConfigVersion.cmake
-@@ -623,6 +638,9 @@ install(EXPORT ONNXTargets DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ONNX")
+@@ -747,6 +762,9 @@ endif()
  install(TARGETS
    onnx onnx_proto
    EXPORT ONNXTargets DESTINATION ${CMAKE_INSTALL_LIBDIR})
@@ -69,5 +69,5 @@ index 4dd56b6e..7f79cc9a 100644
  if(ONNX_BUILD_TESTS)
    include(${ONNX_ROOT}/cmake/unittest.cmake)
 -- 
-2.43.0
+2.52.0
 

diff --git a/0001-Use-system-protobuf-and-require-parameterized.patch b/0001-Use-system-protobuf-and-require-parameterized.patch
new file mode 100644
index 0000000..76d5007
--- /dev/null
+++ b/0001-Use-system-protobuf-and-require-parameterized.patch
@@ -0,0 +1,21 @@
+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-Build-shared-libraries-and-fix-install-location.patch b/0002-Build-shared-libraries-and-fix-install-location.patch
deleted file mode 100644
index 0d140bf..0000000
--- a/0002-Build-shared-libraries-and-fix-install-location.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 057080c775b2dedcbc6308b04efe8bed8cdd27c7 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 1/4] Build shared libraries and fix install location
-
----
- CMakeLists.txt | 22 ++++++++++++++++++++--
- 1 file changed, 20 insertions(+), 2 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index d15d97ed..d6e04d2e 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})
- 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}
-+                                        SOVERSION ${ONNX_VERSION})
- 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")
- 
- if(ONNX_BUILD_TESTS)
-   include(${ONNX_ROOT}/cmake/unittest.cmake)
--- 
-2.46.2
-

diff --git a/0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch b/0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
new file mode 100644
index 0000000..c125320
--- /dev/null
+++ b/0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
@@ -0,0 +1,33 @@
+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, "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-Use-system-protobuf-and-require-parameterized.patch b/0002-Use-system-protobuf-and-require-parameterized.patch
deleted file mode 100644
index 6fe771f..0000000
--- a/0002-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 7f3a9ad0..46dd7f7f 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.46.2
-

diff --git a/0003-Add-fixes-for-use-with-onnxruntime.patch b/0003-Add-fixes-for-use-with-onnxruntime.patch
new file mode 100644
index 0000000..41bc68e
--- /dev/null
+++ b/0003-Add-fixes-for-use-with-onnxruntime.patch
@@ -0,0 +1,68 @@
+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/0003-Let-pyproject_wheel-use-binaries-from-cmake_build.patch b/0003-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
deleted file mode 100644
index 269169b..0000000
--- a/0003-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 7d2cb9e5..af9049a1 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, "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.46.2
-

diff --git a/0004-Add-fixes-for-use-with-onnxruntime.patch b/0004-Add-fixes-for-use-with-onnxruntime.patch
deleted file mode 100644
index 68b4c6d..0000000
--- a/0004-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 74bd0a63..573d0901 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 00000000..2495b931
---- /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.46.2
-

diff --git a/0004-Remove-python-parameterized-dependency.patch b/0004-Remove-python-parameterized-dependency.patch
new file mode 100644
index 0000000..40e2c85
--- /dev/null
+++ b/0004-Remove-python-parameterized-dependency.patch
@@ -0,0 +1,5681 @@
+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/onnx.spec b/onnx.spec
index 9b41741..54f2167 100644
--- a/onnx.spec
+++ b/onnx.spec
@@ -1,19 +1,21 @@
 Name:       onnx
 Version:    1.17.0
-Release:    8%{?dist}
+Release:    9%{?dist}
 Summary:    Open standard for machine learning interoperability
 License:    Apache-2.0
 
 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 
-Patch0:     0000-Build-shared-libraries-and-fix-install-location.patch
+Patch:     0000-Build-shared-libraries-and-fix-install-location.patch
 # Use system protobuf and require parameterized
-Patch2:     0002-Use-system-protobuf-and-require-parameterized.patch
+Patch:     0001-Use-system-protobuf-and-require-parameterized.patch
 # Let pyproject_wheel use binaries from cmake_build
-Patch3:     0003-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
+Patch:     0002-Let-pyproject_wheel-use-binaries-from-cmake_build.patch
 # Add fixes for use with onnxruntime
-Patch4:     0004-Add-fixes-for-use-with-onnxruntime.patch
+Patch:     0003-Add-fixes-for-use-with-onnxruntime.patch
+# Add fixes for use with onnxruntime
+Patch:     0004-Remove-python-parameterized-dependency.patch
 
 # https://bugzilla.redhat.com/show_bug.cgi?id=2212096
 ExcludeArch:    s390x
@@ -122,6 +124,10 @@ export LD_LIBRARY_PATH=%{buildroot}/%{_libdir}
 %{_bindir}/check-node
 
 %changelog
+* 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
 

^ 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: Disable tests that depend on python-parameterized Diego Herrera

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