import onnx
from onnx import helper, TensorProto
def save(model, name):
onnx.checker.check_model(model)
path = f"../fixtures/{name}"
onnx.save(model, path)
print(f" {path}")
def constant_fold_cascade():
graph = helper.make_graph(
name="main_graph",
nodes=[
helper.make_node("Shape", ["x"], ["shape1"]),
helper.make_node("Shape", ["x"], ["shape2"]),
helper.make_node(
"Constant", [], ["idx1"],
value=helper.make_tensor("v", TensorProto.INT64, [], [1]),
),
helper.make_node(
"Constant", [], ["idx2"],
value=helper.make_tensor("v", TensorProto.INT64, [], [2]),
),
helper.make_node("Gather", ["shape1", "idx1"], ["dim1"], axis=0),
helper.make_node("Gather", ["shape2", "idx2"], ["dim2"], axis=0),
helper.make_node("Mul", ["dim1", "dim2"], ["product"]),
],
inputs=[
helper.make_value_info(
"x",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[2, 3, 4]),
),
],
outputs=[
helper.make_value_info(
"product",
helper.make_tensor_type_proto(TensorProto.INT64, shape=[]),
),
],
)
save(
helper.make_model(graph, opset_imports=[helper.make_operatorsetid("", 16)]),
"constant_fold_cascade.onnx",
)
def constant_fold_chain():
graph = helper.make_graph(
name="main_graph",
nodes=[
helper.make_node("Add", ["a", "b"], ["sum"]),
helper.make_node("Sub", ["sum", "c"], ["result"]),
],
inputs=[],
outputs=[
helper.make_value_info(
"result",
helper.make_tensor_type_proto(TensorProto.INT64, shape=[]),
),
],
initializer=[
helper.make_tensor("a", TensorProto.INT64, [], [2]),
helper.make_tensor("b", TensorProto.INT64, [], [3]),
helper.make_tensor("c", TensorProto.INT64, [], [1]),
],
)
save(
helper.make_model(graph, opset_imports=[helper.make_operatorsetid("", 16)]),
"constant_fold_chain.onnx",
)
def constant_fold_blocked():
graph = helper.make_graph(
name="main_graph",
nodes=[
helper.make_node("Neg", ["offset"], ["neg_offset"]),
helper.make_node("Add", ["x", "neg_offset"], ["result"]),
],
inputs=[
helper.make_value_info(
"x",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[2, 3]),
),
],
outputs=[
helper.make_value_info(
"result",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[2, 3]),
),
],
initializer=[
helper.make_tensor("offset", TensorProto.FLOAT, [], [-5.0]),
],
)
save(
helper.make_model(graph, opset_imports=[helper.make_operatorsetid("", 16)]),
"constant_fold_blocked.onnx",
)
def constant_fold_concat():
graph = helper.make_graph(
name="main_graph",
nodes=[
helper.make_node("Shape", ["x"], ["shape_x"]),
helper.make_node("Shape", ["y"], ["shape_y"]),
helper.make_node(
"Constant", [], ["starts_a"],
value=helper.make_tensor("v", TensorProto.INT64, [1], [0]),
),
helper.make_node(
"Constant", [], ["ends_a"],
value=helper.make_tensor("v", TensorProto.INT64, [1], [2]),
),
helper.make_node(
"Constant", [], ["starts_b"],
value=helper.make_tensor("v", TensorProto.INT64, [1], [0]),
),
helper.make_node(
"Constant", [], ["ends_b"],
value=helper.make_tensor("v", TensorProto.INT64, [1], [1]),
),
helper.make_node("Slice", ["shape_x", "starts_a", "ends_a"], ["slice_x"]),
helper.make_node("Slice", ["shape_y", "starts_b", "ends_b"], ["slice_y"]),
helper.make_node("Concat", ["slice_x", "slice_y"], ["result"], axis=0),
],
inputs=[
helper.make_value_info(
"x",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[2, 3, 4]),
),
helper.make_value_info(
"y",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[5, 6]),
),
],
outputs=[
helper.make_value_info(
"result",
helper.make_tensor_type_proto(TensorProto.INT64, shape=[3]),
),
],
)
save(
helper.make_model(graph, opset_imports=[helper.make_operatorsetid("", 16)]),
"constant_fold_concat.onnx",
)
def constant_fold_cast():
graph = helper.make_graph(
name="main_graph",
nodes=[
helper.make_node("Shape", ["x"], ["shape1"]),
helper.make_node(
"Constant", [], ["idx"],
value=helper.make_tensor("v", TensorProto.INT64, [], [1]),
),
helper.make_node("Gather", ["shape1", "idx"], ["dim"], axis=0),
helper.make_node("Cast", ["dim"], ["float_dim"], to=TensorProto.FLOAT),
],
inputs=[
helper.make_value_info(
"x",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[2, 3, 4]),
),
],
outputs=[
helper.make_value_info(
"float_dim",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[]),
),
],
)
save(
helper.make_model(graph, opset_imports=[helper.make_operatorsetid("", 16)]),
"constant_fold_cast.onnx",
)
def constant_fold_sqrt():
graph = helper.make_graph(
name="main_graph",
nodes=[
helper.make_node("Shape", ["x"], ["shape1"]),
helper.make_node(
"Constant", [], ["idx"],
value=helper.make_tensor("v", TensorProto.INT64, [], [2]),
),
helper.make_node("Gather", ["shape1", "idx"], ["dim"], axis=0),
helper.make_node("Cast", ["dim"], ["float_dim"], to=TensorProto.FLOAT),
helper.make_node("Sqrt", ["float_dim"], ["scale"]),
],
inputs=[
helper.make_value_info(
"x",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[2, 3, 64]),
),
],
outputs=[
helper.make_value_info(
"scale",
helper.make_tensor_type_proto(TensorProto.FLOAT, shape=[]),
),
],
)
save(
helper.make_model(graph, opset_imports=[helper.make_operatorsetid("", 16)]),
"constant_fold_sqrt.onnx",
)
if __name__ == "__main__":
print("Generating constant fold test models:")
constant_fold_cascade()
constant_fold_chain()
constant_fold_blocked()
constant_fold_concat()
constant_fold_cast()
constant_fold_sqrt()
print("Done.")