Kano001's picture
Upload 2707 files
dc2106c verified
raw
history blame
47.3 kB
# Copyright (c) ONNX Project Contributors
# SPDX-License-Identifier: Apache-2.0
import os
import tempfile
import unittest
from typing import Sequence
import numpy as np
import onnx.defs
import onnx.parser
from onnx import (
GraphProto,
SparseTensorProto,
TensorProto,
checker,
helper,
numpy_helper,
shape_inference,
)
class TestChecker(unittest.TestCase):
@property
def _sample_float_tensor(self) -> TensorProto:
np_array = np.random.randn(2, 3).astype(np.float32)
return helper.make_tensor(
name="test",
data_type=TensorProto.FLOAT,
dims=(2, 3),
vals=np_array.reshape(6).tolist(),
)
def make_sparse(
self,
shape: Sequence[int],
values: Sequence[int],
indices_shape: Sequence[int],
indices: Sequence[int],
name: str = "spval",
) -> SparseTensorProto:
sparse = SparseTensorProto()
sparse.dims.extend(shape)
nnz = len(values)
sparse.values.CopyFrom(
helper.make_tensor(name, TensorProto.INT64, (nnz,), values)
)
sparse.indices.CopyFrom(
helper.make_tensor("spind", TensorProto.INT64, indices_shape, indices)
)
return sparse
def test_check_node(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
checker.check_node(node)
def test_check_node_input_marked_optional(self) -> None:
# GivenTensorFill's input is marked optional, hence it is used in this test.
node = helper.make_node("GivenTensorFill", [], ["Y"], name="test")
checker.check_node(node)
# Explicitly pass the empty string as optional
node = helper.make_node("GivenTensorFill", [""], ["Y"], name="test")
checker.check_node(node)
# Input of RELU is not optional
node = helper.make_node("Relu", [""], ["Y"], name="test")
self.assertRaises(checker.ValidationError, checker.check_node, node)
def test_check_function_nested(self) -> None:
func_domain = "local"
func_nested_opset_imports = [
helper.make_opsetid("", 14),
helper.make_opsetid(func_domain, 1),
]
# nested identity/add function
func_nested_identity_add_name = "func_nested_identity_add"
func_nested_identity_add_inputs = ["a", "b"]
func_nested_identity_add_outputs = ["c"]
func_nested_identity_add_nodes = [
helper.make_node("func_identity", ["a"], ["a1"], domain=func_domain),
helper.make_node("func_identity", ["b"], ["b1"], domain=func_domain),
helper.make_node("func_add", ["a1", "b1"], ["c"], domain=func_domain),
]
func_nested_identity_add = helper.make_function(
func_domain,
func_nested_identity_add_name,
func_nested_identity_add_inputs,
func_nested_identity_add_outputs,
func_nested_identity_add_nodes,
func_nested_opset_imports,
)
checker.check_function(func_nested_identity_add)
def test_check_graph_ir_version_3(self) -> None:
ctx = checker.C.CheckerContext()
ctx.ir_version = 3
ctx.opset_imports = {"": onnx.defs.onnx_opset_version()}
lex_ctx = checker.C.LexicalScopeContext()
def check_ir_version_3(g: GraphProto) -> None:
checker.check_graph(g, ctx, lex_ctx)
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
check_ir_version_3(graph)
graph.initializer.extend([self._sample_float_tensor])
graph.initializer[0].name = "no-exist"
self.assertRaises(checker.ValidationError, check_ir_version_3, graph)
graph.initializer[0].name = "X"
check_ir_version_3(graph)
def test_check_graph(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
graph.initializer.extend([self._sample_float_tensor])
graph.initializer[0].name = "no-exist"
checker.check_graph(graph)
graph.initializer[0].name = "X"
checker.check_graph(graph)
def test_check_graph_types(self) -> None:
# This is for https://github.com/onnx/onnx/issues/3849.
# It confirms that type checking is performed
# when checker.check_model is called with full_check=True
node_div = helper.make_node("Div", ["X", "Y"], ["Z"], name="test_div")
node_identity = helper.make_node("Identity", ["Z"], ["W"], name="test_identity")
graph = helper.make_graph(
[node_div, node_identity],
"test",
[
helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2]),
# intentionally use a BOOL type which is not supported by the Div op.
helper.make_tensor_value_info("Y", TensorProto.BOOL, [1, 2]),
],
[helper.make_tensor_value_info("W", TensorProto.FLOAT, [1, 2])],
)
model = helper.make_model(graph, producer_name="test")
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
checker.check_graph(graph)
graph = helper.make_graph(
[node_div, node_identity],
"test",
[
helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2]),
# intentionally use a Int32 type which is in conflict with Div's other input X.
helper.make_tensor_value_info("Y", TensorProto.INT32, [1, 2]),
],
[helper.make_tensor_value_info("W", TensorProto.FLOAT, [1, 2])],
)
model = helper.make_model(graph, producer_name="test")
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
checker.check_graph(graph)
def test_check_graph_empty_initializer_name(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
# Supply no name for the initializer
graph.initializer.extend([self._sample_float_tensor])
graph.initializer[0].name = ""
self.assertRaises(checker.ValidationError, checker.check_graph, graph)
def test_check_graph_empty_sparse_initializer_name(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
# Supply no name for the sparse_initializer
sparse = self.make_sparse([100], [13, 17, 19], [3], [9, 27, 81], "")
graph.sparse_initializer.extend([sparse])
self.assertRaises(checker.ValidationError, checker.check_graph, graph)
def test_check_graph_duplicate_init_names(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
graph.initializer.extend([self._sample_float_tensor])
graph.initializer[0].name = "X"
# Add sparse initializer with the same name as above
sparse = self.make_sparse([100], [13, 17, 19], [3], [9, 27, 81], "X")
graph.sparse_initializer.extend([sparse])
self.assertRaises(checker.ValidationError, checker.check_graph, graph)
def test_check_graph_optional_input(self) -> None:
# GivenTensorFill's input is marked optional, hence it is used in this test.
node = helper.make_node("GivenTensorFill", [""], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
def test_check_graph_ssa(self) -> None:
relu1 = helper.make_node("Relu", ["X"], ["Z"], name="relu1")
relu2 = helper.make_node("Relu", ["Y"], ["Z"], name="relu2")
graph = helper.make_graph(
[relu1, relu2],
"test",
inputs=[
helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2]),
helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2]),
],
outputs=[helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])],
)
self.assertRaises(checker.ValidationError, checker.check_graph, graph)
def test_check_graph_topologically_sorted(self) -> None:
n1 = helper.make_node("Scale", ["X"], ["Y"], scale=2.0, name="n1")
n2 = helper.make_node("Scale", ["Y"], ["Z"], scale=3.0, name="n2")
graph = helper.make_graph(
[n2, n1],
"test",
inputs=[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
outputs=[helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])],
)
self.assertRaises(checker.ValidationError, checker.check_graph, graph)
def test_check_model(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
model = helper.make_model(graph, producer_name="test")
checker.check_model(model)
def test_check_serialized_model(self) -> None:
node = helper.make_node("Relu", ["X"], ["Y"], name="test")
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
model = helper.make_model(graph, producer_name="test")
checker.check_model(model.SerializeToString())
def test_check_old_model(self) -> None:
node = helper.make_node("Pad", ["X"], ["Y"], paddings=(0, 0, 0, 0))
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
onnx_id = helper.make_opsetid("", 1)
model = helper.make_model(graph, producer_name="test", opset_imports=[onnx_id])
checker.check_model(model)
def test_check_tensor(self) -> None:
tensor = self._sample_float_tensor
checker.check_tensor(tensor)
tensor.raw_data = np.random.randn(2, 3).astype(np.float32).tobytes()
self.assertRaises(checker.ValidationError, checker.check_tensor, tensor)
def test_check_string_tensor(self) -> None:
tensor = TensorProto()
tensor.data_type = TensorProto.STRING
tensor.dims.append(1)
tensor.string_data.append(b"Test")
checker.check_tensor(tensor)
del tensor.string_data[:]
tensor.raw_data = b"Test"
# string data should not be stored in raw_data field
self.assertRaises(checker.ValidationError, checker.check_tensor, tensor)
def test_check_tensor_mismatched_field(self) -> None:
tensor = self._sample_float_tensor
tensor.data_type = TensorProto.INT32
self.assertRaises(checker.ValidationError, checker.check_tensor, tensor)
def test_nested_graph(self) -> None:
n1 = helper.make_node("Scale", ["X"], ["Y"], scale=2.0, name="n1")
n2 = helper.make_node("Scale", ["Y"], ["Z"], scale=3.0, name="n2")
graph = helper.make_graph(
[n1, n2],
"nested",
inputs=[],
outputs=[helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])],
)
i1 = helper.make_node(
"If", ["cond"], ["Z"], then_branch=graph, else_branch=graph
)
graph = helper.make_graph(
[i1],
"test",
inputs=[
helper.make_tensor_value_info("cond", TensorProto.BOOL, [1]),
helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2]),
],
outputs=[helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
def test_nested_graph_without_subgraph_input_shape(self) -> None:
n1 = helper.make_node("Scale", ["X"], ["Y"], scale=2.0, name="n1")
n2 = helper.make_node("Scale", ["Y"], ["Z"], scale=3.0, name="n2")
input_x = onnx.ValueInfoProto()
input_x.name = "X"
graph = helper.make_graph(
[n1, n2],
"nested",
inputs=[],
outputs=[helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])],
)
i1 = helper.make_node(
"If", ["cond"], ["Z"], then_branch=graph, else_branch=graph
)
graph = helper.make_graph(
[i1],
"test",
inputs=[
helper.make_tensor_value_info("cond", TensorProto.BOOL, [1]),
helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2]),
],
outputs=[helper.make_tensor_value_info("Z", TensorProto.FLOAT, [1, 2])],
)
checker.check_graph(graph)
@property
def _sample_0_elem_tensor(self) -> TensorProto:
np_array = np.random.randn(0, 3).astype(np.float32)
return helper.make_tensor(
name="test",
data_type=TensorProto.FLOAT,
dims=(0, 3),
vals=np_array.reshape(0).tolist(),
)
def test_check_tensor_zero_elem(self) -> None:
tensor = self._sample_0_elem_tensor
checker.check_tensor(tensor)
def test_check_removed_experimental_op(self) -> None:
node = helper.make_node("ConstantFill", [], ["Y"], name="test", shape=[1, 2])
checker.check_node(node)
def test_skip_schema_check_on_non_standard_domain(self) -> None:
node = helper.make_node(
"NonExistOp", ["X"], ["Y"], name="test", domain="test.domain"
)
graph = helper.make_graph(
[node],
"test",
[helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2])],
[helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2])],
)
onnx_id = helper.make_opsetid("test.domain", 1)
model = helper.make_model(graph, producer_name="test", opset_imports=[onnx_id])
checker.check_model(model)
def test_check_sparse_tensor(self) -> None:
sparse = self.make_sparse([100], [13, 17, 19], [3], [9, 27, 81])
checker.check_sparse_tensor(sparse)
def test_check_sparse_tensor_invalid_index(self) -> None:
# index value 181 is out-of-range
sparse = self.make_sparse([100], [13, 17, 19], [3], [9, 27, 181])
self.assertRaises(checker.ValidationError, checker.check_sparse_tensor, sparse)
def test_check_sparse_tensor_unordered(self) -> None:
# index values are not in sorted order
sparse = self.make_sparse([100], [13, 17, 19], [3], [27, 9, 81])
self.assertRaises(checker.ValidationError, checker.check_sparse_tensor, sparse)
def test_check_sparse_tensor_coo_format(self) -> None:
sparse = self.make_sparse([10, 10], [13, 17, 19], [3, 2], [0, 9, 2, 7, 8, 1])
checker.check_sparse_tensor(sparse)
def test_check_sparse_tensor_coo_format_invalid_index(self) -> None:
sparse = self.make_sparse([10, 10], [13, 17, 19], [3, 2], [0, 9, 0, 27, 8, 1])
self.assertRaises(checker.ValidationError, checker.check_sparse_tensor, sparse)
def test_check_sparse_tensor_coo_format_invalid_shape(self) -> None:
sparse = self.make_sparse([10, 10], [13, 17, 19], [2, 3], [0, 9, 2, 7, 8, 1])
self.assertRaises(checker.ValidationError, checker.check_sparse_tensor, sparse)
def test_check_sparse_tensor_coo_format_invalid_dim2(self) -> None:
sparse = self.make_sparse([10, 10], [13, 17, 19], [3, 1], [0, 1, 2])
self.assertRaises(checker.ValidationError, checker.check_sparse_tensor, sparse)
def test_check_sparse_matmul(self) -> None:
M = 5
N = 10
# Create ValueInfoProto for input X of shape [N]
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [N])
# Create a [M,N] sparse-matrix constant C
sparse_tensor = self.make_sparse([M, N], [2, 3, 1], [3], [3, 11, 37])
node1 = helper.make_node("Constant", [], ["C"], sparse_value=sparse_tensor)
# Create ValueInfoProto for output Y of shape [M]
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [M])
# Compute Y = C X
node2 = helper.make_node("MatMul", ["C", "X"], ["Y"])
# create graph
graph = helper.make_graph([node1, node2], "sparse_matmul", [X], [Y])
# check graph
checker.check_graph(graph)
def test_check_model_unsupported_input_type(self) -> None:
N = 10
X = helper.make_tensor_value_info("X", TensorProto.BOOL, [N])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [N])
Z = helper.make_tensor_value_info("Z", TensorProto.FLOAT, [N])
onnx_id = helper.make_opsetid("", 6)
node = helper.make_node("Add", ["X", "Y"], ["Z"])
graph = helper.make_graph([node], "test_add_input", [X, Y], [Z])
model = helper.make_model(graph, producer_name="test", opset_imports=[onnx_id])
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
def test_check_model_inconsistent_type(self) -> None:
N = 10
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [N])
Y = helper.make_tensor_value_info("Y", TensorProto.INT32, [N])
Z = helper.make_tensor_value_info("Z", TensorProto.FLOAT, [N])
onnx_id = helper.make_opsetid("", 6)
node = helper.make_node("Add", ["X", "Y"], ["Z"])
graph = helper.make_graph([node], "test_add_input", [X, Y], [Z])
model = helper.make_model(graph, producer_name="test", opset_imports=[onnx_id])
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
def test_check_model_unsupported_output_type(self) -> None:
N = 10
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [N])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [N])
Z = helper.make_tensor_value_info("Z", TensorProto.BOOL, [N])
onnx_id = helper.make_opsetid("", 6)
node = helper.make_node("Add", ["X", "Y"], ["Z"])
graph = helper.make_graph([node], "test_add_input", [X, Y], [Z])
model = helper.make_model(graph, producer_name="test", opset_imports=[onnx_id])
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
def test_loop_with_same_initializer_input_below_ir4(self) -> None:
# This is for testing IR<4: tensors must exist both in initializer and input
# shape_inference should allow different number of graph input and node input for Loop
# Comes from a tf2onnx model
model = helper.make_model(
opset_imports=[helper.make_operatorsetid("", 8)],
ir_version=3,
graph=helper.make_graph(
name="test-loop",
inputs=[
helper.make_tensor_value_info(
"input_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_maximum_iterations_0", TensorProto.INT64, shape=[]
),
helper.make_tensor_value_info(
"const_fold_opt__18", TensorProto.INT64, shape=[1]
),
helper.make_tensor_value_info(
"const_fold_opt__17", TensorProto.FLOAT, shape=[]
),
helper.make_tensor_value_info(
"Const_0", TensorProto.INT32, shape=[1]
),
],
outputs=[
helper.make_tensor_value_info(
"output_0", TensorProto.INT32, shape=[1]
)
],
initializer=[
numpy_helper.from_array(
np.array(9223372036854775807, dtype=np.int64),
name="while_maximum_iterations_0",
),
numpy_helper.from_array(
np.array([-1], dtype=np.int64), name="const_fold_opt__18"
),
numpy_helper.from_array(
np.array(10.0, dtype=np.float32), name="const_fold_opt__17"
),
numpy_helper.from_array(
np.array([1], dtype=np.int32), name="Const_0"
),
],
nodes=[
helper.make_node(
"Cast",
inputs=["input_0"],
outputs=["while_cond_158_while_Less__13_0"],
name="while_cond_158_while_Less__13",
domain="",
to=TensorProto.FLOAT,
),
helper.make_node(
"Less",
inputs=[
"while_cond_158_while_Less__13_0",
"const_fold_opt__17",
],
outputs=["while_cond_158_while_Less_0"],
name="while_cond_158_while_Less",
domain="",
),
helper.make_node(
"Squeeze",
inputs=["while_cond_158_while_Less_0"],
outputs=["while_cond_158_while_Squeeze_0"],
name="while_cond_158_while_Squeeze",
domain="",
),
helper.make_node(
"Loop",
inputs=[
"while_maximum_iterations_0",
"while_cond_158_while_Squeeze_0",
"input_0",
"Const_0",
],
outputs=["while_loop_0", "while_loop_1"],
name="while_loop",
body=helper.make_graph(
name="while_body",
inputs=[
helper.make_tensor_value_info(
"while_while_loop_counter_0",
TensorProto.INT64,
shape=[],
),
helper.make_tensor_value_info(
"cond__15_0", TensorProto.BOOL, shape=[]
),
helper.make_tensor_value_info(
"while_placeholder_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_add_const_0_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"const_fold_opt__19", TensorProto.FLOAT, shape=[]
),
],
outputs=[
helper.make_tensor_value_info(
"cond___while_Identity_graph_outputs_Identity__3_0",
TensorProto.BOOL,
shape=[],
),
helper.make_tensor_value_info(
"while_Identity_2_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_add_const_0_0", TensorProto.INT32, shape=[1]
),
],
initializer=[
numpy_helper.from_array(
np.array(10.0, dtype=np.float32),
name="const_fold_opt__19",
)
],
nodes=[
helper.make_node(
"Add",
inputs=[
"while_placeholder_0",
"while_add_const_0_0",
],
outputs=["while_Identity_2_0"],
name="while_Add",
),
helper.make_node(
"Cast",
inputs=["while_Identity_2_0"],
outputs=["cond___while_Less__13_0"],
name="cond___while_Less__13",
domain="",
to=TensorProto.FLOAT,
),
helper.make_node(
"Less",
inputs=[
"cond___while_Less__13_0",
"const_fold_opt__19",
],
outputs=["cond___while_Less_0"],
name="cond___while_Less",
domain="",
),
helper.make_node(
"Squeeze",
inputs=["cond___while_Less_0"],
outputs=[
"cond___while_Identity_graph_outputs_Identity__3_0"
],
name="cond___while_Squeeze",
domain="",
),
],
),
),
helper.make_node(
"Unsqueeze",
inputs=["while_loop_0"],
outputs=["Reshape_tensor_0"],
name="Reshape_tensor",
axes=[0],
),
helper.make_node(
"Reshape",
inputs=["Reshape_tensor_0", "const_fold_opt__18"],
outputs=["output_0"],
name="Reshape",
),
],
),
)
# Should not throw an error
checker.check_model(model, full_check=True)
def test_loop_with_different_initializer_input_below_ir4(self) -> None:
# This is for testing IR<4: tensors must exist both in initializer and input
# Testing an optional input which does not exist in initializers
# Checker should throw an error said the missing input is not in initializers
model = helper.make_model(
opset_imports=[helper.make_operatorsetid("", 8)],
ir_version=3,
graph=helper.make_graph(
name="test-loop",
inputs=[
helper.make_tensor_value_info(
"input_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_maximum_iterations_0", TensorProto.INT64, shape=[]
),
helper.make_tensor_value_info(
"const_fold_opt__18", TensorProto.INT64, shape=[1]
),
helper.make_tensor_value_info(
"const_fold_opt__17", TensorProto.FLOAT, shape=[]
),
helper.make_tensor_value_info(
"Const_0", TensorProto.INT32, shape=[1]
),
],
outputs=[
helper.make_tensor_value_info(
"output_0", TensorProto.INT32, shape=[1]
)
],
initializer=[
numpy_helper.from_array(
np.array(9223372036854775807, dtype=np.int64),
name="while_maximum_iterations_0",
),
numpy_helper.from_array(
np.array([-1], dtype=np.int64), name="const_fold_opt__18"
),
numpy_helper.from_array(
np.array(10.0, dtype=np.float32), name="const_fold_opt__17"
),
numpy_helper.from_array(
np.array([1], dtype=np.int32), name="Const_0"
),
],
nodes=[
helper.make_node(
"Cast",
inputs=["input_0"],
outputs=["while_cond_158_while_Less__13_0"],
name="while_cond_158_while_Less__13",
domain="",
to=TensorProto.FLOAT,
),
helper.make_node(
"Less",
inputs=[
"while_cond_158_while_Less__13_0",
"const_fold_opt__17",
],
outputs=["while_cond_158_while_Less_0"],
name="while_cond_158_while_Less",
domain="",
),
helper.make_node(
"Squeeze",
inputs=["while_cond_158_while_Less_0"],
outputs=["while_cond_158_while_Squeeze_0"],
name="while_cond_158_while_Squeeze",
domain="",
),
helper.make_node(
"Loop",
inputs=[
"while_maximum_iterations_0",
"while_cond_158_while_Squeeze_0",
"input_0",
"Const_0",
],
outputs=["while_loop_0", "while_loop_1"],
name="while_loop",
body=helper.make_graph(
name="while_body",
inputs=[
helper.make_tensor_value_info(
"while_while_loop_counter_0",
TensorProto.INT64,
shape=[],
),
helper.make_tensor_value_info(
"cond__15_0", TensorProto.BOOL, shape=[]
),
helper.make_tensor_value_info(
"while_placeholder_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_add_const_0_0", TensorProto.INT32, shape=[1]
),
# The following input cannot be found in initializer and checker should throw an error
helper.make_tensor_value_info(
"const_fold_opt__18", TensorProto.FLOAT, shape=[]
),
],
outputs=[
helper.make_tensor_value_info(
"cond___while_Identity_graph_outputs_Identity__3_0",
TensorProto.BOOL,
shape=[],
),
helper.make_tensor_value_info(
"while_Identity_2_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_add_const_0_0", TensorProto.INT32, shape=[1]
),
],
initializer=[],
nodes=[
helper.make_node(
"Add",
inputs=[
"while_placeholder_0",
"while_add_const_0_0",
],
outputs=["while_Identity_2_0"],
name="while_Add",
),
helper.make_node(
"Cast",
inputs=["while_Identity_2_0"],
outputs=["cond___while_Less__13_0"],
name="cond___while_Less__13",
domain="",
to=TensorProto.FLOAT,
),
],
),
),
helper.make_node(
"Unsqueeze",
inputs=["while_loop_0"],
outputs=["Reshape_tensor_0"],
name="Reshape_tensor",
axes=[0],
),
helper.make_node(
"Reshape",
inputs=["Reshape_tensor_0", "const_fold_opt__18"],
outputs=["output_0"],
name="Reshape",
),
],
),
)
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
def test_loop_with_same_initializer_input_above_ir4(self) -> None:
# This is for testing IR>=4:
# Cannot use the same name as both a subgraph initializer and subgraph input
model = helper.make_model(
opset_imports=[helper.make_operatorsetid("", 11)],
ir_version=6,
graph=helper.make_graph(
name="test-loop",
inputs=[
helper.make_tensor_value_info(
"input_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_maximum_iterations_0", TensorProto.INT64, shape=[]
),
helper.make_tensor_value_info(
"const_fold_opt__18", TensorProto.INT64, shape=[1]
),
helper.make_tensor_value_info(
"const_fold_opt__17", TensorProto.FLOAT, shape=[]
),
helper.make_tensor_value_info(
"Const_0", TensorProto.INT32, shape=[1]
),
],
outputs=[
helper.make_tensor_value_info(
"output_0", TensorProto.INT32, shape=[1]
)
],
initializer=[
numpy_helper.from_array(
np.array(9223372036854775807, dtype=np.int64),
name="while_maximum_iterations_0",
),
numpy_helper.from_array(
np.array([-1], dtype=np.int64), name="const_fold_opt__18"
),
numpy_helper.from_array(
np.array(10.0, dtype=np.float32), name="const_fold_opt__17"
),
numpy_helper.from_array(
np.array([1], dtype=np.int32), name="Const_0"
),
],
nodes=[
helper.make_node(
"Cast",
inputs=["input_0"],
outputs=["while_cond_158_while_Less__13_0"],
name="while_cond_158_while_Less__13",
domain="",
to=TensorProto.FLOAT,
),
helper.make_node(
"Less",
inputs=[
"while_cond_158_while_Less__13_0",
"const_fold_opt__17",
],
outputs=["while_cond_158_while_Less_0"],
name="while_cond_158_while_Less",
domain="",
),
helper.make_node(
"Squeeze",
inputs=["while_cond_158_while_Less_0"],
outputs=["while_cond_158_while_Squeeze_0"],
name="while_cond_158_while_Squeeze",
domain="",
),
helper.make_node(
"Loop",
inputs=[
"while_maximum_iterations_0",
"while_cond_158_while_Squeeze_0",
"input_0",
"Const_0",
],
outputs=["while_loop_0", "while_loop_1"],
name="while_loop",
body=helper.make_graph(
name="while_body",
inputs=[
helper.make_tensor_value_info(
"while_while_loop_counter_0",
TensorProto.INT64,
shape=[],
),
helper.make_tensor_value_info(
"cond__15_0", TensorProto.BOOL, shape=[]
),
helper.make_tensor_value_info(
"while_placeholder_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_add_const_0_0", TensorProto.INT32, shape=[1]
),
],
outputs=[
helper.make_tensor_value_info(
"cond___while_Identity_graph_outputs_Identity__3_0",
TensorProto.BOOL,
shape=[],
),
helper.make_tensor_value_info(
"while_Identity_2_0", TensorProto.INT32, shape=[1]
),
helper.make_tensor_value_info(
"while_add_const_0_0", TensorProto.INT32, shape=[1]
),
],
# Cannot use the same name as both a subgraph initializer and subgraph input: while_while_loop_counter_0
initializer=[
numpy_helper.from_array(
np.array(10, dtype=np.int64),
name="while_while_loop_counter_0",
)
],
nodes=[
helper.make_node(
"Add",
inputs=[
"while_placeholder_0",
"while_add_const_0_0",
],
outputs=["while_Identity_2_0"],
name="while_Add",
),
helper.make_node(
"Cast",
inputs=["while_Identity_2_0"],
outputs=["cond___while_Less__13_0"],
name="cond___while_Less__13",
domain="",
to=TensorProto.FLOAT,
),
helper.make_node(
"Less",
inputs=[
"cond___while_Less__13_0",
"while_while_loop_counter_0",
],
outputs=["cond___while_Less_0"],
name="cond___while_Less",
domain="",
),
helper.make_node(
"Squeeze",
inputs=["cond___while_Less_0"],
outputs=[
"cond___while_Identity_graph_outputs_Identity__3_0"
],
name="cond___while_Squeeze",
domain="",
),
],
),
),
helper.make_node(
"Unsqueeze",
inputs=["while_loop_0"],
outputs=["Reshape_tensor_0"],
name="Reshape_tensor",
axes=[0],
),
helper.make_node(
"Reshape",
inputs=["Reshape_tensor_0", "const_fold_opt__18"],
outputs=["output_0"],
name="Reshape",
),
],
),
)
self.assertRaises(
shape_inference.InferenceError, checker.check_model, model, True
)
def test_empty_list_attribute(self):
model = onnx.parser.parse_model(
"""
<
ir_version: 7,
opset_import: [ "" : 17]
>
agraph (float[N] x) => (int64[M] y)
{
y = Constant <value_ints: ints = []>()
}
"""
)
# Should not throw an error
checker.check_model(model, full_check=True)
model = onnx.parser.parse_model(
"""
<
ir_version: 7,
opset_import: [ "" : 17]
>
agraph (float[N] x) => (float[M] y)
{
y = Constant <value_floats: floats = []>()
}
"""
)
# Should not throw an error
checker.check_model(model, full_check=True)
def test_check_model_supports_unicode_path(self):
input_tensor = helper.make_tensor_value_info(
"input", onnx.TensorProto.FLOAT, [1]
)
output_tensor = helper.make_tensor_value_info(
"output", onnx.TensorProto.FLOAT, [1]
)
node = helper.make_node("Identity", ["input"], ["output"])
graph = helper.make_graph([node], "test", [input_tensor], [output_tensor])
model = helper.make_model(graph, producer_name="test")
with tempfile.TemporaryDirectory() as temp_dir:
unicode_model_path = os.path.join(temp_dir, "模型モデル모델✨.onnx")
onnx.save(model, unicode_model_path)
checker.check_model(unicode_model_path, full_check=True)
if __name__ == "__main__":
unittest.main()