GameServerO / MLPY /Lib /site-packages /onnx /test /version_converter_test.py
Kano001's picture
Upload 2707 files
dc2106c verified
raw
history blame
81.9 kB
# Copyright (c) ONNX Project Contributors
# SPDX-License-Identifier: Apache-2.0
import contextlib
import struct
import unittest
from typing import Optional, Tuple
import numpy as np
import parameterized
import onnx.version_converter
from onnx import (
GraphProto,
ModelProto,
OperatorSetIdProto,
TensorProto,
checker,
helper,
)
class TestVersionConverter(unittest.TestCase):
def _converted(
self,
graph: GraphProto,
initial_version: OperatorSetIdProto,
target_version: int,
) -> ModelProto:
orig_model = helper.make_model(
graph, producer_name="onnx-test", opset_imports=[initial_version]
)
# print(type(orig_model))
converted_model = onnx.version_converter.convert_version(
orig_model, target_version
)
checker.check_model(converted_model)
return converted_model
# Test 1: Backwards Incompatible Conversion: Reshape: 8 -> 2
def test_backwards_incompatible(self) -> None:
def test() -> None:
nodes = [
helper.make_node("Add", ["W", "Z"], ["shape"]),
helper.make_node("Reshape", ["X", "shape"], ["A"]),
helper.make_node("Add", ["A", "W"], ["Y"]),
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("W", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("Z", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
self._converted(graph, helper.make_operatorsetid("", 8), 2)
self.assertRaises(RuntimeError, test)
# Test 2: Backwards Compatible Conversion (No Adaptations): Add: 3 -> 2
def test_backwards_compatible(self) -> None:
nodes = [helper.make_node("Add", ["X1", "X2"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (5,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 3), 2)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Add"
assert converted_model.opset_import[0].version == 2
# Test 3: Non-Existent Op Conversion: Cos: 8 -> 6
def test_non_existent_op(self) -> None:
def test() -> None:
nodes = [helper.make_node("Cos", ["X"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
self._converted(graph, helper.make_operatorsetid("", 8), 6)
self.assertRaises(RuntimeError, test)
# Test Add Adapter: 8 -> 5
def test_add_8_5(self) -> None:
nodes = [helper.make_node("Add", ["X1", "X2"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 5)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Add"
assert converted_model.opset_import[0].version == 5
# Test Add Adapter: 5 -> 8
def test_add_5_8(self) -> None:
nodes = [helper.make_node("Add", ["X1", "X2"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Add"
assert converted_model.opset_import[0].version == 8
# Test Add Adapter: 5 -> 8, requiring insertion of an Unsqueeze node
def test_add_5_8_with_unsqueeze(self) -> None:
nodes = [helper.make_node("Add", ["X1", "X2"], ["Y"], axis=0, broadcast=1)]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (5, 2)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (5,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Unsqueeze"
assert converted_model.graph.node[1].op_type == "Add"
assert converted_model.opset_import[0].version == 8
# Test Mul Adapter: 8 -> 5
def test_mul_8_5(self) -> None:
nodes = [helper.make_node("Mul", ["X1", "X2"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 5)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Mul"
assert converted_model.opset_import[0].version == 5
# Test Mul Adapter: 5 -> 8
def test_mul_5_8(self) -> None:
nodes = [helper.make_node("Mul", ["X1", "X2"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Mul"
assert converted_model.opset_import[0].version == 8
# Test Gemm Adapter: 1 -> 8
def test_gemm_up(self) -> None:
nodes = [helper.make_node("Gemm", ["A", "B", "C"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info(
"A",
TensorProto.FLOAT,
(
5,
5,
),
),
helper.make_tensor_value_info(
"B",
TensorProto.FLOAT,
(
5,
5,
),
),
helper.make_tensor_value_info(
"C",
TensorProto.FLOAT,
(
5,
5,
),
),
],
[
helper.make_tensor_value_info(
"Y",
TensorProto.FLOAT,
(
5,
5,
),
)
],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 1), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Gemm"
assert converted_model.opset_import[0].version == 8
# Test Gemm Adapter: 8 -> 1
def test_gemm_down(self) -> None:
nodes = [helper.make_node("Gemm", ["A", "B", "C"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info(
"A",
TensorProto.FLOAT,
(
5,
5,
),
),
helper.make_tensor_value_info(
"B",
TensorProto.FLOAT,
(
5,
5,
),
),
helper.make_tensor_value_info(
"C",
TensorProto.FLOAT,
(
5,
5,
),
),
],
[
helper.make_tensor_value_info(
"Y",
TensorProto.FLOAT,
(
5,
5,
),
)
],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 1)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Gemm"
assert converted_model.opset_import[0].version == 1
# Test Relu Adapter: 5 -> 7
def test_relu_5_7(self) -> None:
nodes = [helper.make_node("Relu", ["X"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 7)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Relu"
assert converted_model.opset_import[0].version == 7
# Test Relu Adapter: 7 -> 5
def test_relu_7_5(self) -> None:
nodes = [helper.make_node("Relu", ["X"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 7), 5)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Relu"
assert converted_model.opset_import[0].version == 5
# Test BatchNormalization Adapter: 8 -> 5
def test_batch_normalization_8_5(self) -> None:
nodes = [
helper.make_node(
"BatchNormalization", ["X", "scale", "B", "mean", "var"], ["Y"]
)
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("scale", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("B", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("mean", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("var", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 5)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "BatchNormalization"
assert converted_model.opset_import[0].version == 5
# Test BatchNormalization Adapter: 5 -> 8
def test_batch_normalization_5_8(self) -> None:
nodes = [
helper.make_node(
"BatchNormalization", ["X", "scale", "B", "mean", "var"], ["Y"]
)
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("scale", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("B", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("mean", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("var", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "BatchNormalization"
assert converted_model.opset_import[0].version == 8
# Test Concat Adapter: 3 -> 5
def test_concat_3_5(self) -> None:
nodes = [helper.make_node("Concat", ["X1", "X2", "X3", "X4", "X5"], ["Y"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X3", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X4", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X5", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 3), 5)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Concat"
assert converted_model.opset_import[0].version == 5
# Test Concat Adapter: 5 -> 3
def test_concat_5_3(self) -> None:
nodes = [
helper.make_node("Concat", ["X1", "X2", "X3", "X4", "X5"], ["Y"], axis=0)
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("X1", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X2", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X3", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X4", TensorProto.FLOAT, (1,)),
helper.make_tensor_value_info("X5", TensorProto.FLOAT, (1,)),
],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 3)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Concat"
assert converted_model.opset_import[0].version == 3
# Test Reshape Adapter: 6 -> 4
def test_reshape_6_4(self) -> None:
nodes = [
helper.make_node(
"Constant",
[],
["shape"],
value=helper.make_tensor("", TensorProto.INT64, [1], [5]),
),
helper.make_node("Reshape", ["X", "shape"], ["Y"]),
]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 6), 4)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Reshape"
assert converted_model.opset_import[0].version == 4
# Test Reshape Adapter: 4 -> 6
def test_reshape_4_6(self) -> None:
nodes = [helper.make_node("Reshape", ["X"], ["Y"], shape=[5])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 4), 6)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.graph.node[1].op_type == "Reshape"
assert converted_model.opset_import[0].version == 6
# Test Sum Adapter: 7 -> 8
def test_sum_7_8(self) -> None:
nodes = [
helper.make_node(
"Sum", ["data_0", "data_1", "data_2", "data_3", "data_4"], ["sum"]
)
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("data_0", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_2", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_3", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_4", TensorProto.FLOAT, (5,)),
],
[helper.make_tensor_value_info("sum", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 7), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Sum"
assert converted_model.opset_import[0].version == 8
# Test Sum Adapter: 5 -> 8
def test_sum_5_8(self) -> None:
nodes = [
helper.make_node(
"Sum", ["data_0", "data_1", "data_2", "data_3", "data_4"], ["sum"]
)
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("data_0", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_2", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_3", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_4", TensorProto.FLOAT, (5,)),
],
[helper.make_tensor_value_info("sum", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 5), 7)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Sum"
assert converted_model.opset_import[0].version == 7
# Test Sum Adapter: 8 -> 5
def test_sum_8_5(self) -> None:
nodes = [
helper.make_node(
"Sum", ["data_0", "data_1", "data_2", "data_3", "data_4"], ["sum"]
)
]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info("data_0", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_1", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_2", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_3", TensorProto.FLOAT, (5,)),
helper.make_tensor_value_info("data_4", TensorProto.FLOAT, (5,)),
],
[helper.make_tensor_value_info("sum", TensorProto.FLOAT, (5,))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 5)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Sum"
assert converted_model.opset_import[0].version == 5
# Test AveragePool Adapter: 1 -> 8
def test_averagepool_up(self) -> None:
nodes = [helper.make_node("AveragePool", ["X"], ["Y"], kernel_shape=[1, 1])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5, 5, 5, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5, 5, 5, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 1), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "AveragePool"
assert converted_model.opset_import[0].version == 8
# Test AveragePool Adapter: 8 -> 1
def test_averagepool_down(self) -> None:
nodes = [helper.make_node("AveragePool", ["X"], ["Y"], kernel_shape=[1, 1])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5, 5, 5, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5, 5, 5, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 1)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "AveragePool"
assert converted_model.opset_import[0].version == 1
# Test Dropout Adapter: 1 -> 8
def test_dropout_up(self) -> None:
nodes = [helper.make_node("Dropout", ["data"], ["output"], is_test=1)]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info(
"data",
TensorProto.FLOAT,
(
5,
5,
),
)
],
[
helper.make_tensor_value_info(
"output",
TensorProto.FLOAT,
(
5,
5,
),
)
],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 1), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Dropout"
assert converted_model.opset_import[0].version == 8
# Test Dropout Adapter: 8 -> 1
def test_dropout_down(self) -> None:
nodes = [helper.make_node("Dropout", ["data"], ["output"])]
graph = helper.make_graph(
nodes,
"test",
[
helper.make_tensor_value_info(
"data",
TensorProto.FLOAT,
(
5,
5,
),
)
],
[
helper.make_tensor_value_info(
"output",
TensorProto.FLOAT,
(
5,
5,
),
)
],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 1)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Dropout"
assert converted_model.opset_import[0].version == 1
# Test Max Adapter: 7 -> 8
def test_max_7_8(self) -> None:
from_opset = 7
to_opset = 8
data_type = TensorProto.FLOAT
data_shape = (2, 3, 4)
nodes = [onnx.helper.make_node("Max", inputs=["X"], outputs=["Y"])]
graph = helper.make_graph(
nodes,
"test_max",
[onnx.helper.make_tensor_value_info("X", data_type, data_shape)],
[onnx.helper.make_tensor_value_info("Y", data_type, data_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Max"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Min Adapter: 7 -> 8
def test_min_7_8(self) -> None:
from_opset = 7
to_opset = 8
data_type = TensorProto.FLOAT
data_shape = (2, 3, 4)
nodes = [onnx.helper.make_node("Min", inputs=["X"], outputs=["Y"])]
graph = helper.make_graph(
nodes,
"test_min",
[onnx.helper.make_tensor_value_info("X", data_type, data_shape)],
[onnx.helper.make_tensor_value_info("Y", data_type, data_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Min"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Mean Adapter: 7 -> 8
def test_mean_7_8(self) -> None:
from_opset = 7
to_opset = 8
data_type = TensorProto.FLOAT
data_shape = (3,)
nodes = [onnx.helper.make_node("Mean", inputs=["X"], outputs=["Y"])]
graph = helper.make_graph(
nodes,
"test_mean",
[onnx.helper.make_tensor_value_info("X", data_type, data_shape)],
[onnx.helper.make_tensor_value_info("Y", data_type, data_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Mean"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test MaxPool Adapter: 1 -> 8
def test_maxpool_up(self) -> None:
nodes = [helper.make_node("MaxPool", ["X"], ["Y"], kernel_shape=[1, 1])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5, 5, 5, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5, 5, 5, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 1), 8)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "MaxPool"
assert converted_model.opset_import[0].version == 8
# Test Upsample Adapter: 6 -> 7
def test_upsample_6_7(self) -> None:
from_opset = 6
to_opset = 7
data_type = TensorProto.FLOAT
nodes = [
onnx.helper.make_node(
"Upsample",
inputs=["X"],
outputs=["Y"],
mode="nearest",
width_scale=3.0,
height_scale=2.0,
)
]
graph = helper.make_graph(
nodes,
"test_upsample_6_7",
[onnx.helper.make_tensor_value_info("X", data_type, [1, 1, 2, 2])],
[onnx.helper.make_tensor_value_info("Y", data_type, [1, 1, 4, 6])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert len(converted_model.graph.node) == 1
assert converted_model.graph.node[0].op_type == "Upsample"
attribute_names = [
attr.name for attr in converted_model.graph.node[0].attribute
]
assert "scales" in attribute_names
assert "width_scale" not in attribute_names
assert "height_scale" not in attribute_names
assert converted_model.opset_import[0].version == to_opset
# Test MaxPool Adapter: 8 -> 1
def test_maxpool_down(self) -> None:
nodes = [helper.make_node("MaxPool", ["X"], ["Y"], kernel_shape=[1, 1])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5, 5, 5, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (5, 5, 5, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 8), 1)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "MaxPool"
assert converted_model.opset_import[0].version == 1
# Test BatchNormalization Adapter: 8 -> 9
def test_batch_normalization_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [
helper.make_node(
"BatchNormalization",
inputs=["x", "s", "bias", "mean", "var"],
outputs=["y"],
)
]
input_shape = (1, 2, 1, 3)
x = helper.make_tensor_value_info("x", data_type, input_shape)
scale = helper.make_tensor_value_info("s", data_type, [input_shape[1]])
B = helper.make_tensor_value_info("bias", data_type, [input_shape[1]])
mean = helper.make_tensor_value_info("mean", data_type, [input_shape[1]])
var = helper.make_tensor_value_info("var", data_type, [input_shape[1]])
y = helper.make_tensor_value_info("y", data_type, input_shape)
graph = helper.make_graph(
nodes, "test_batchnormalization_8_9", [x, scale, B, mean, var], [y]
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "BatchNormalization"
assert converted_model.opset_import[0].version == to_opset
# Test BatchNormalization Adapter: 9 -> 8
def test_batchnormalization_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.FLOAT
nodes = [
onnx.helper.make_node(
"BatchNormalization",
inputs=["X", "scale", "B", "mean", "var"],
outputs=["Y"],
)
]
input_shape = (2, 3, 4, 5)
x = onnx.helper.make_tensor_value_info("X", data_type, input_shape)
scale = onnx.helper.make_tensor_value_info("scale", data_type, [input_shape[1]])
B = onnx.helper.make_tensor_value_info("B", data_type, [input_shape[1]])
mean = onnx.helper.make_tensor_value_info("mean", data_type, [input_shape[1]])
var = onnx.helper.make_tensor_value_info("var", data_type, [input_shape[1]])
y = onnx.helper.make_tensor_value_info("Y", data_type, input_shape)
graph = onnx.helper.make_graph(
nodes, "test_batchnormalization", [x, scale, B, mean, var], [y]
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "BatchNormalization"
assert converted_model.opset_import[0].version == to_opset
# Test Constant Adapter: 8 -> 9
def test_constant_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
output_shape = [2, 3, 4]
output_value = np.arange(24)
nodes = [
helper.make_node(
"Constant",
inputs=[],
outputs=["Y"],
value=helper.make_tensor("", data_type, output_shape, output_value),
)
]
graph = helper.make_graph(
nodes,
"test_constant",
[],
[onnx.helper.make_tensor_value_info("Y", data_type, output_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Constant Adapter: 9 -> 8
def test_constant_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
output_shape = [2, 3, 4]
output_value = np.arange(24)
nodes = [
helper.make_node(
"Constant",
inputs=[],
outputs=["Y"],
value=helper.make_tensor("", data_type, output_shape, output_value),
)
]
graph = helper.make_graph(
nodes,
"test_constant",
[],
[onnx.helper.make_tensor_value_info("Y", data_type, output_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Flatten Adapter: 8 -> 9
def test_flatten_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [onnx.helper.make_node("Flatten", inputs=["X"], outputs=["Y"], axis=1)]
graph = helper.make_graph(
nodes,
"test_flatten",
[onnx.helper.make_tensor_value_info("X", data_type, [2, 3, 4])],
[onnx.helper.make_tensor_value_info("Y", data_type, [2, 12])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Flatten"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Flatten Adapter: 9 -> 8
def test_flatten_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
nodes = [onnx.helper.make_node("Flatten", inputs=["X"], outputs=["Y"], axis=1)]
graph = helper.make_graph(
nodes,
"test_flatten",
[onnx.helper.make_tensor_value_info("X", data_type, [2, 3, 4])],
[onnx.helper.make_tensor_value_info("Y", data_type, [2, 12])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[1].op_type == "Flatten"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test PRelu Adapter: 8 -> 9
def test_prelu_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [onnx.helper.make_node("PRelu", inputs=["X", "Slope"], outputs=["Y"])]
input_shape = [2, 3, 4]
graph = helper.make_graph(
nodes,
"test_prelu",
[
onnx.helper.make_tensor_value_info("X", data_type, input_shape),
onnx.helper.make_tensor_value_info("Slope", data_type, input_shape),
],
[onnx.helper.make_tensor_value_info("Y", data_type, input_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "PRelu"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test PRelu Adapter: 9 -> 8
def test_prelu_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
nodes = [onnx.helper.make_node("PRelu", inputs=["X", "Slope"], outputs=["Y"])]
input_shape = [2, 3, 4]
graph = helper.make_graph(
nodes,
"test_prelu",
[
onnx.helper.make_tensor_value_info("X", data_type, input_shape),
onnx.helper.make_tensor_value_info("Slope", data_type, input_shape),
],
[onnx.helper.make_tensor_value_info("Y", data_type, input_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[2].op_type == "PRelu"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Greater Adapter: 8 -> 9
def test_greater_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [onnx.helper.make_node("Greater", inputs=["X1", "X2"], outputs=["Y"])]
input_shape = [2, 3, 4]
graph = helper.make_graph(
nodes,
"test_greater",
[
onnx.helper.make_tensor_value_info("X1", data_type, input_shape),
onnx.helper.make_tensor_value_info("X2", data_type, input_shape),
],
[onnx.helper.make_tensor_value_info("Y", TensorProto.BOOL, input_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Greater"
assert (
converted_model.graph.output[0].type.tensor_type.elem_type
== TensorProto.BOOL
)
assert converted_model.opset_import[0].version == to_opset
# Test Greater Adapter: 9 -> 8
def test_greater_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
nodes = [onnx.helper.make_node("Greater", inputs=["X1", "X2"], outputs=["Y"])]
input_shape = [2, 3, 4]
graph = helper.make_graph(
nodes,
"test_greater",
[
onnx.helper.make_tensor_value_info("X1", data_type, input_shape),
onnx.helper.make_tensor_value_info("X2", data_type, input_shape),
],
[onnx.helper.make_tensor_value_info("Y", TensorProto.BOOL, input_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[2].op_type == "Greater"
assert (
converted_model.graph.output[0].type.tensor_type.elem_type
== TensorProto.BOOL
)
assert converted_model.opset_import[0].version == to_opset
# Test Less Adapter: 8 -> 9
def test_less_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [onnx.helper.make_node("Less", inputs=["X1", "X2"], outputs=["Y"])]
input_shape = [2, 3, 4]
graph = helper.make_graph(
nodes,
"test_less",
[
onnx.helper.make_tensor_value_info("X1", data_type, input_shape),
onnx.helper.make_tensor_value_info("X2", data_type, input_shape),
],
[onnx.helper.make_tensor_value_info("Y", TensorProto.BOOL, input_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Less"
assert (
converted_model.graph.output[0].type.tensor_type.elem_type
== TensorProto.BOOL
)
assert converted_model.opset_import[0].version == to_opset
# Test Less Adapter: 9 -> 8
def test_less_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
nodes = [onnx.helper.make_node("Less", inputs=["X1", "X2"], outputs=["Y"])]
input_shape = [2, 3, 4]
graph = helper.make_graph(
nodes,
"test_less",
[
onnx.helper.make_tensor_value_info("X1", data_type, input_shape),
onnx.helper.make_tensor_value_info("X2", data_type, input_shape),
],
[onnx.helper.make_tensor_value_info("Y", TensorProto.BOOL, input_shape)],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[2].op_type == "Less"
assert (
converted_model.graph.output[0].type.tensor_type.elem_type
== TensorProto.BOOL
)
assert converted_model.opset_import[0].version == to_opset
# Test MatMul Adapter: 8 -> 9
def test_matmul_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [onnx.helper.make_node("MatMul", inputs=["X1", "X2"], outputs=["Y"])]
graph = helper.make_graph(
nodes,
"test_matmul",
[
onnx.helper.make_tensor_value_info("X1", data_type, [3, 4]),
onnx.helper.make_tensor_value_info("X2", data_type, [4, 3]),
],
[onnx.helper.make_tensor_value_info("Y", data_type, [3, 3])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "MatMul"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test MatMul Adapter: 9 -> 8
def test_matmul_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
nodes = [onnx.helper.make_node("MatMul", inputs=["X1", "X2"], outputs=["Y"])]
graph = helper.make_graph(
nodes,
"test_matmul",
[
onnx.helper.make_tensor_value_info("X1", data_type, [3, 4]),
onnx.helper.make_tensor_value_info("X2", data_type, [4, 3]),
],
[onnx.helper.make_tensor_value_info("Y", data_type, [3, 3])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[2].op_type == "MatMul"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Gemm Adapter: 8 -> 9
def test_gemm_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [
onnx.helper.make_node("Gemm", inputs=["X1", "X2", "X3"], outputs=["Y"])
]
graph = helper.make_graph(
nodes,
"test_gemm",
[
onnx.helper.make_tensor_value_info("X1", data_type, [3, 4]),
onnx.helper.make_tensor_value_info("X2", data_type, [4, 3]),
onnx.helper.make_tensor_value_info("X3", data_type, [3, 3]),
],
[onnx.helper.make_tensor_value_info("Y", data_type, [3, 3])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Gemm"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Gemm Adapter: 9 -> 8
def test_gemm_9_8(self) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.UINT64
nodes = [
onnx.helper.make_node("Gemm", inputs=["X1", "X2", "X3"], outputs=["Y"])
]
graph = helper.make_graph(
nodes,
"test_gemm",
[
onnx.helper.make_tensor_value_info("X1", data_type, [3, 4]),
onnx.helper.make_tensor_value_info("X2", data_type, [4, 3]),
onnx.helper.make_tensor_value_info("X3", data_type, [3, 3]),
],
[onnx.helper.make_tensor_value_info("Y", data_type, [3, 3])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[3].op_type == "Gemm"
assert converted_model.graph.output[0].type.tensor_type.elem_type == data_type
assert converted_model.opset_import[0].version == to_opset
# Test Upsample Adapter: 8 -> 9
def test_upsample_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
nodes = [
onnx.helper.make_node(
"Upsample",
inputs=["X"],
outputs=["Y"],
mode="nearest",
scales=[1.0, 1.0, 2.0, 3.0],
)
]
graph = helper.make_graph(
nodes,
"test_upsample_8_9",
[onnx.helper.make_tensor_value_info("X", data_type, [1, 1, 2, 2])],
[onnx.helper.make_tensor_value_info("Y", data_type, [1, 1, 4, 6])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert len(converted_model.graph.node) == 2
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.graph.node[1].op_type == "Upsample"
assert len(converted_model.graph.node[1].attribute) == 1
assert converted_model.graph.node[1].attribute[0].name == "mode"
assert converted_model.opset_import[0].version == to_opset
# Test Helper for Upsample Adapter: 9 -> 8
def helper_upsample_with_initializer(self, raw_scale: bool = False) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.FLOAT
nodes = [
onnx.helper.make_node(
"Upsample", inputs=["X", "Scales"], outputs=["Y"], mode="nearest"
)
]
scale_value = [1.0, 1.0, 2.0, 3.0]
scale_tensor = onnx.helper.make_tensor(
"Scales",
onnx.TensorProto.FLOAT,
[4],
bytes(struct.pack("4f", *scale_value)) if raw_scale else scale_value,
raw_scale,
)
graph = helper.make_graph(
nodes,
"test_upsample",
[
onnx.helper.make_tensor_value_info("X", data_type, [1, 1, 2, 2]),
onnx.helper.make_tensor_value_info("Scales", data_type, [4]),
],
[onnx.helper.make_tensor_value_info("Y", data_type, [1, 1, 4, 6])],
[scale_tensor],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Upsample"
assert len(converted_model.graph.initializer) == 0
assert len(converted_model.graph.node[0].attribute) == 2
assert converted_model.graph.node[0].attribute[1].name == "scales"
assert converted_model.opset_import[0].version == to_opset
# Test Helper for Upsample Adapter: 9 -> 8
def helper_upsample_with_constant(self, raw_scale: bool = False) -> None:
from_opset = 9
to_opset = 8
data_type = TensorProto.FLOAT
scale_value = [1.0, 1.0, 2.0, 3.0]
scale_tensor = onnx.helper.make_tensor(
"const_value",
onnx.TensorProto.FLOAT,
[4],
bytes(struct.pack("4f", *scale_value)) if raw_scale else scale_value,
raw_scale,
)
nodes = [
onnx.helper.make_node(
"Constant", inputs=[], outputs=["Constant_Output"], value=scale_tensor
),
onnx.helper.make_node(
"Upsample",
inputs=["X", "Constant_Output"],
outputs=["Y"],
mode="nearest",
),
]
graph = helper.make_graph(
nodes,
"test_upsample",
[onnx.helper.make_tensor_value_info("X", data_type, [1, 1, 2, 2])],
[onnx.helper.make_tensor_value_info("Y", data_type, [1, 1, 4, 6])],
value_info=[
onnx.helper.make_tensor_value_info("Constant_Output", data_type, [4])
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert len(converted_model.graph.node) == 1
assert converted_model.graph.node[0].op_type == "Upsample"
assert len(converted_model.graph.node[0].attribute) == 2
assert converted_model.graph.node[0].attribute[1].name == "scales"
assert converted_model.opset_import[0].version == to_opset
# Test Upsample Adapter: 9 -> 8
def test_upsample_with_constant_node_9_8(self) -> None:
self.helper_upsample_with_constant(raw_scale=False)
# Test Upsample Adapter: 9 -> 8
def test_upsample_with_initializer_9_8(self) -> None:
self.helper_upsample_with_initializer(raw_scale=False)
# Test Upsample Adapter: 9 -> 8
def test_upsample_with_raw_initializer_9_8(self) -> None:
self.helper_upsample_with_constant(raw_scale=True)
# Test Upsample Adapter: 9 -> 8
def test_upsample_with_raw_constant_node_9_8(self) -> None:
self.helper_upsample_with_constant(raw_scale=True)
# Test Scan Adapter: 8 -> 9
def test_scan_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type = TensorProto.FLOAT
node1 = onnx.helper.make_node(
"Add",
inputs=["sum_in", "next"],
outputs=["sum_out"],
)
node2 = onnx.helper.make_node(
"Identity",
inputs=["sum_out"],
outputs=["scan_out"],
)
g = onnx.helper.make_graph(
[node1, node2],
"scan_body",
[
onnx.helper.make_tensor_value_info("sum_in", data_type, [2]),
onnx.helper.make_tensor_value_info("next", data_type, [2]),
],
[
onnx.helper.make_tensor_value_info("sum_out", data_type, [2]),
onnx.helper.make_tensor_value_info("scan_out", data_type, [2]),
],
)
no_sequence_lens = "" # optional input, not supplied
nodes = [
onnx.helper.make_node(
"Scan",
inputs=[no_sequence_lens, "initial", "x"],
outputs=["y", "z"],
body=g,
num_scan_inputs=1,
)
]
initial = onnx.helper.make_tensor_value_info("initial", data_type, [1, 2])
x = onnx.helper.make_tensor_value_info("x", data_type, [1, 3, 2])
y = onnx.helper.make_tensor_value_info("y", data_type, [1, 2])
z = onnx.helper.make_tensor_value_info("z", data_type, [1, 3, 2])
graph = onnx.helper.make_graph(nodes, "test_scan_8_9", [initial, x], [y, z])
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Scan"
assert converted_model.opset_import[0].version == to_opset
# Test Cast Adapter: 8 -> 9
def test_cast_8_9(self) -> None:
from_opset = 8
to_opset = 9
data_type_from = TensorProto.FLOAT
data_type_to = TensorProto.UINT32
nodes = [
onnx.helper.make_node(
"Cast", inputs=["X"], outputs=["Y"], to=TensorProto.UINT32
)
]
graph = helper.make_graph(
nodes,
"test_cast",
[onnx.helper.make_tensor_value_info("X", data_type_from, [2, 3])],
[onnx.helper.make_tensor_value_info("Y", data_type_to, [2, 3])],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "Cast"
assert (
converted_model.graph.output[0].type.tensor_type.elem_type == data_type_to
)
assert converted_model.opset_import[0].version == to_opset
# Test Split Adapter: 13 -> 12
def test_split_13_12(self) -> None:
nodes = [
helper.make_node(
"Constant",
[],
["split"],
value=helper.make_tensor("", TensorProto.INT64, [2], [2, 3]),
),
helper.make_node("Split", ["X", "split"], ["Y1", "Y2"]),
]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[
helper.make_tensor_value_info("Y1", TensorProto.FLOAT, (2,)),
helper.make_tensor_value_info("Y2", TensorProto.FLOAT, (3,)),
],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 13), 12)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Split"
assert converted_model.opset_import[0].version == 12
# Test Split Adapter: 12 -> 13
def test_split_12_13(self) -> None:
nodes = [helper.make_node("Split", ["X"], ["Y1", "Y2"], split=[2, 3])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5,))],
[
helper.make_tensor_value_info("Y1", TensorProto.FLOAT, (2,)),
helper.make_tensor_value_info("Y2", TensorProto.FLOAT, (3,)),
],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 12), 13)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.graph.node[1].op_type == "Split"
assert converted_model.opset_import[0].version == 13
# Test AxesInputToAttribute Adapter: 13 -> 12
def test_axes_input_to_attr_13_12(self) -> None:
nodes = [
helper.make_node(
"Constant",
[],
["axes"],
value=helper.make_tensor("", TensorProto.INT64, [1], [0]),
),
helper.make_node("ReduceSum", ["X", "axes"], ["Y"]),
]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (1, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 13), 12)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "ReduceSum"
assert converted_model.opset_import[0].version == 12
# Test AxesAttributeToInput Adapter: 12 -> 13
def test_axes_attr_to_input_12_13(self) -> None:
nodes = [helper.make_node("ReduceSum", ["X"], ["Y"], axes=[0])]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (5, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (1, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 12), 13)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.opset_import[0].version == 13
# Test Slice Adapter: 9 -> 10
def test_slice_9_10(self) -> None:
nodes = [
helper.make_node(
"Slice", ["X"], ["Y"], axes=[0, 1], starts=[0, 0], ends=[3, 10]
)
]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (20, 10, 5))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (3, 10, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 9), 10)
assert converted_model.graph.node[0].op_type == "Constant"
assert converted_model.graph.node[1].op_type == "Constant"
assert converted_model.graph.node[2].op_type == "Constant"
assert converted_model.graph.node[3].op_type == "Slice"
assert converted_model.opset_import[0].version == 10
assert len(converted_model.graph.node[3].input) == 4
assert len(converted_model.graph.node[3].attribute) == 0
# Test RNN Adapter: 13 -> 14
def test_rnn_13_14(self) -> None:
from_opset = 13
to_opset = 14
data_type = TensorProto.FLOAT
seq_length = 1
batch_size = 2
input_size = 3
num_directions = 1
hidden_size = 5
nodes = [
onnx.helper.make_node(
"RNN",
inputs=["X", "W", "R"],
outputs=["", "Y_h"],
hidden_size=hidden_size,
)
]
graph = helper.make_graph(
nodes,
"test_rnn",
[
onnx.helper.make_tensor_value_info(
"X", data_type, [seq_length, batch_size, input_size]
),
onnx.helper.make_tensor_value_info(
"W", data_type, [num_directions, hidden_size, input_size]
),
onnx.helper.make_tensor_value_info(
"R", data_type, [num_directions, hidden_size, hidden_size]
),
onnx.helper.make_tensor_value_info(
"B", data_type, [num_directions, 2 * hidden_size]
),
],
[
onnx.helper.make_tensor_value_info(
"Y_h", data_type, [num_directions, batch_size, hidden_size]
)
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "RNN"
assert converted_model.opset_import[0].version == to_opset
assert len(converted_model.graph.node[0].attribute) == 2
assert converted_model.graph.node[0].attribute[1].name == "layout"
# Test GRU Adapter: 13 -> 14
def test_gru_13_14(self) -> None:
from_opset = 13
to_opset = 14
data_type = TensorProto.FLOAT
seq_length = 1
batch_size = 2
input_size = 3
num_directions = 1
hidden_size = 5
nodes = [
onnx.helper.make_node(
"GRU",
inputs=["X", "W", "R"],
outputs=["", "Y_h"],
hidden_size=hidden_size,
)
]
graph = helper.make_graph(
nodes,
"test_gru",
[
onnx.helper.make_tensor_value_info(
"X", data_type, [seq_length, batch_size, input_size]
),
onnx.helper.make_tensor_value_info(
"W", data_type, [num_directions, 3 * hidden_size, input_size]
),
onnx.helper.make_tensor_value_info(
"R", data_type, [num_directions, 3 * hidden_size, hidden_size]
),
onnx.helper.make_tensor_value_info(
"B", data_type, [num_directions, 6 * hidden_size]
),
],
[
onnx.helper.make_tensor_value_info(
"Y_h", data_type, [num_directions, batch_size, hidden_size]
)
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "GRU"
assert converted_model.opset_import[0].version == to_opset
assert len(converted_model.graph.node[0].attribute) == 2
assert converted_model.graph.node[0].attribute[1].name == "layout"
# Test LSTM Adapter: 13 -> 14
def test_lstm_13_14(self) -> None:
from_opset = 13
to_opset = 14
data_type = TensorProto.FLOAT
seq_length = 1
batch_size = 2
input_size = 3
num_directions = 1
hidden_size = 5
nodes = [
onnx.helper.make_node(
"LSTM",
inputs=["X", "W", "R"],
outputs=["", "Y_h"],
hidden_size=hidden_size,
)
]
graph = helper.make_graph(
nodes,
"test_lstm",
[
onnx.helper.make_tensor_value_info(
"X", data_type, [seq_length, batch_size, input_size]
),
onnx.helper.make_tensor_value_info(
"W", data_type, [num_directions, 4 * hidden_size, input_size]
),
onnx.helper.make_tensor_value_info(
"R", data_type, [num_directions, 4 * hidden_size, hidden_size]
),
onnx.helper.make_tensor_value_info(
"B", data_type, [num_directions, 8 * hidden_size]
),
],
[
onnx.helper.make_tensor_value_info(
"Y_h", data_type, [num_directions, batch_size, hidden_size]
)
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "LSTM"
assert converted_model.opset_import[0].version == to_opset
assert len(converted_model.graph.node[0].attribute) == 2
assert converted_model.graph.node[0].attribute[1].name == "layout"
# Test RNN Adapter: 14 -> 13
def test_rnn_14_13(self) -> None:
from_opset = 14
to_opset = 13
data_type = TensorProto.FLOAT
seq_length = 1
batch_size = 2
input_size = 3
num_directions = 1
hidden_size = 5
nodes = [
onnx.helper.make_node(
"RNN",
inputs=["X", "W", "R"],
outputs=["", "Y_h"],
hidden_size=hidden_size,
layout=0,
)
]
graph = helper.make_graph(
nodes,
"test_rnn",
[
onnx.helper.make_tensor_value_info(
"X", data_type, [seq_length, batch_size, input_size]
),
onnx.helper.make_tensor_value_info(
"W", data_type, [num_directions, hidden_size, input_size]
),
onnx.helper.make_tensor_value_info(
"R", data_type, [num_directions, hidden_size, hidden_size]
),
onnx.helper.make_tensor_value_info(
"B", data_type, [num_directions, 2 * hidden_size]
),
],
[
onnx.helper.make_tensor_value_info(
"Y_h", data_type, [num_directions, batch_size, hidden_size]
)
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "RNN"
assert converted_model.opset_import[0].version == to_opset
assert len(converted_model.graph.node[0].attribute) == 1
# Test GRU Adapter: 14 -> 13
def test_gru_14_13(self) -> None:
from_opset = 14
to_opset = 13
data_type = TensorProto.FLOAT
seq_length = 1
batch_size = 2
input_size = 3
num_directions = 1
hidden_size = 5
nodes = [
onnx.helper.make_node(
"GRU",
inputs=["X", "W", "R"],
outputs=["", "Y_h"],
hidden_size=hidden_size,
layout=0,
)
]
graph = helper.make_graph(
nodes,
"test_gru",
[
onnx.helper.make_tensor_value_info(
"X", data_type, [seq_length, batch_size, input_size]
),
onnx.helper.make_tensor_value_info(
"W", data_type, [num_directions, 3 * hidden_size, input_size]
),
onnx.helper.make_tensor_value_info(
"R", data_type, [num_directions, 3 * hidden_size, hidden_size]
),
onnx.helper.make_tensor_value_info(
"B", data_type, [num_directions, 6 * hidden_size]
),
],
[
onnx.helper.make_tensor_value_info(
"Y_h", data_type, [num_directions, batch_size, hidden_size]
)
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "GRU"
assert converted_model.opset_import[0].version == to_opset
assert len(converted_model.graph.node[0].attribute) == 1
# Test LSTM Adapter: 14 -> 13
def test_lstm_14_13(self) -> None:
from_opset = 14
to_opset = 13
data_type = TensorProto.FLOAT
seq_length = 1
batch_size = 2
input_size = 3
num_directions = 1
hidden_size = 5
nodes = [
onnx.helper.make_node(
"LSTM",
inputs=["X", "W", "R"],
outputs=["", "Y_h"],
hidden_size=hidden_size,
layout=0,
)
]
graph = helper.make_graph(
nodes,
"test_lstm",
[
onnx.helper.make_tensor_value_info(
"X", data_type, [seq_length, batch_size, input_size]
),
onnx.helper.make_tensor_value_info(
"W", data_type, [num_directions, 4 * hidden_size, input_size]
),
onnx.helper.make_tensor_value_info(
"R", data_type, [num_directions, 4 * hidden_size, hidden_size]
),
onnx.helper.make_tensor_value_info(
"B", data_type, [num_directions, 8 * hidden_size]
),
],
[
onnx.helper.make_tensor_value_info(
"Y_h", data_type, [num_directions, batch_size, hidden_size]
)
],
)
converted_model = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted_model.graph.node[0].op_type == "LSTM"
assert converted_model.opset_import[0].version == to_opset
assert len(converted_model.graph.node[0].attribute) == 1
# Test Pad Adapter: 10 -> 11
def test_pad_10_11(self) -> None:
pads = (0, 1, 2, 0, 2, 1)
nodes = [helper.make_node("Pad", ["X"], ["Y"], pads=pads)]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 2, 2))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (1, 5, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 10), 11)
# Assert equality of graph and converted_model
assert converted_model.graph.node[1].op_type == "Pad"
assert converted_model.opset_import[0].version == 11
def test_pad_with_value_10_11(self) -> None:
pads = (0, 1, 2, 0, 2, 1)
nodes = [helper.make_node("Pad", ["X"], ["Y"], pads=pads, value=1.0)]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 2, 2))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (1, 5, 5))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 10), 11)
# Assert equality of graph and converted_model
assert converted_model.graph.node[1].op_type == "Pad"
assert converted_model.opset_import[0].version == 11
# Test that subgraphs are converted
def test_if_subgraph_10_11(self) -> None:
from_opset = 10
to_opset = 11
data_type = TensorProto.FLOAT
data_shape = [2]
subg1_node = [
onnx.helper.make_node(
"Clip", inputs=["sub_in"], outputs=["sub_out"], min=2.0, max=3.0
)
]
subg1_input = [
onnx.helper.make_tensor_value_info("sub_in", data_type, data_shape)
]
subg1_output = [
onnx.helper.make_tensor_value_info("sub_out", data_type, data_shape)
]
subg1 = helper.make_graph(subg1_node, "then_g", subg1_input, subg1_output)
subg2_node = [
onnx.helper.make_node(
"Clip", inputs=["sub_in"], outputs=["sub_out"], min=2.0, max=3.0
)
]
subg2_input = [
onnx.helper.make_tensor_value_info("sub_in", data_type, data_shape)
]
subg2_output = [
onnx.helper.make_tensor_value_info("sub_out", data_type, data_shape)
]
subg2 = helper.make_graph(subg2_node, "then_g", subg2_input, subg2_output)
node = [
onnx.helper.make_node(
"If",
inputs=["cond"],
outputs=["out"],
then_branch=subg1,
else_branch=subg2,
)
]
input = [onnx.helper.make_tensor_value_info("cond", TensorProto.BOOL, [])]
output = [onnx.helper.make_tensor_value_info("out", data_type, data_shape)]
init = [helper.make_tensor("sub_in", data_type, data_shape, [4.0, 5.0])]
graph = helper.make_graph(node, "test_subgraphs", input, output, init)
converted = self._converted(
graph, helper.make_operatorsetid("", from_opset), to_opset
)
assert converted.graph.node[0].op_type == "If"
assert converted.opset_import[0].version == to_opset
assert converted.graph.node[0].attribute[0].g.node[2].op_type == "Clip"
assert len(converted.graph.node[0].attribute[0].g.node[2].attribute) == 0
assert converted.graph.node[0].attribute[1].g.node[2].op_type == "Clip"
assert len(converted.graph.node[0].attribute[1].g.node[2].attribute) == 0
# Use initializer as node inputs (instead of graph input)
# to test whether IR (version_converter) can handle it
def test_initializer_not_in_input_above_ir4(self): # type: () -> None
nodes = [
helper.make_node(
"BatchNormalization", ["X", "scale", "B", "mean", "var"], ["Y"]
)
]
scale_value = [0.55, 0.72]
scale_tensor = onnx.helper.make_tensor(
"scale", onnx.TensorProto.FLOAT, [2], scale_value
)
b_value = [0.60, 0.54]
b_tensor = onnx.helper.make_tensor("B", onnx.TensorProto.FLOAT, [2], b_value)
mean_value = [0.42, 0.65]
mean_tensor = onnx.helper.make_tensor(
"mean", onnx.TensorProto.FLOAT, [2], mean_value
)
var_value = [0.44, 0.89]
var_tensor = onnx.helper.make_tensor(
"var", onnx.TensorProto.FLOAT, [2], var_value
)
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 2, 2, 3))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (1, 2, 2, 3))],
[scale_tensor, b_tensor, mean_tensor, var_tensor],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 11), 12)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "BatchNormalization"
assert converted_model.opset_import[0].version == 12
def test_softmax_12_13(self) -> None:
axis = 0
nodes = [helper.make_node("Softmax", ["X"], ["Y"], axis=axis)]
graph = helper.make_graph(
nodes,
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, (1, 2, 3))],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, (1, 2, 3))],
)
converted_model = self._converted(graph, helper.make_operatorsetid("", 11), 13)
# Assert equality of graph and converted_model
assert converted_model.graph.node[0].op_type == "Shape"
assert converted_model.graph.node[1].op_type == "Flatten"
assert converted_model.graph.node[1].attribute[0].name == "axis"
assert converted_model.graph.node[1].attribute[0].i == axis
assert converted_model.graph.node[2].op_type == "Softmax"
assert converted_model.graph.node[2].attribute[0].name == "axis"
assert converted_model.graph.node[2].attribute[0].i == -1
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: Optional[int],
zero_point_dtype: Optional[int],
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()