Spaces:
Sleeping
Sleeping
# 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 | |
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) | |
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() | |