New corner case test
Validate Operations / validate-operations (push) Has been cancelled

This commit is contained in:
ilgeco
2026-06-04 16:00:48 +02:00
parent cbc9808229
commit 27410207c4
67 changed files with 831 additions and 1 deletions
Binary file not shown.
+831 -1
View File
@@ -98,7 +98,7 @@ def conv_same_padding_3x3():
def conv_explicit_padding():
"""Conv 3x3 with explicit asymmetric padding."""
"""Conv 3x3 with explicit symmetric padding."""
# Input: [1, 1, 4, 4], Kernel: [1, 1, 3, 3], pads=[1,1,1,1] -> Output: [1, 1, 4, 4]
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 4, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 4, 4])
@@ -193,6 +193,199 @@ def conv_dynamic():
save_model(model, "conv/dynamic", "conv_dynamic.onnx")
def conv_huge_pointwise_1024():
"""Huge 1x1 Conv with 1024 input and output channels."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
W = numpy_helper.from_array(
np.random.default_rng(73).uniform(-1, 1, (1024, 1024, 1, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_huge_pointwise_1024", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/huge_pointwise_1024", "conv_huge_pointwise_1024.onnx")
def conv_huge_pointwise_1024_dynamic():
"""Huge 1x1 Conv with runtime weights and 1024 channels."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 1, 1])
W = helper.make_tensor_value_info("W", TensorProto.FLOAT, [1024, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_huge_pointwise_1024_dynamic", [X, W], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/huge_pointwise_1024_dynamic", "conv_huge_pointwise_1024_dynamic.onnx")
def conv_large_output_channels_1x1():
"""1x1 Conv with modest inputs and very large output channel count."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 64, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
W = numpy_helper.from_array(
np.random.default_rng(74).uniform(-1, 1, (1024, 64, 1, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_large_output_channels_1x1", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/large_output_channels_1x1", "conv_large_output_channels_1x1.onnx")
def conv_large_input_channels_1x1():
"""1x1 Conv with very large input channel count and modest outputs."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 64, 1, 1])
W = numpy_helper.from_array(
np.random.default_rng(75).uniform(-1, 1, (64, 1024, 1, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_large_input_channels_1x1", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/large_input_channels_1x1", "conv_large_input_channels_1x1.onnx")
def conv_depthwise_1024_channels():
"""Depthwise 1x1 Conv with 1024 groups and preserved spatial shape."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 4, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 4, 4])
W = numpy_helper.from_array(
np.random.default_rng(76).uniform(-1, 1, (1024, 1, 1, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0], group=1024)
graph = helper.make_graph([node], "conv_depthwise_1024_channels", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/depthwise_1024_channels", "conv_depthwise_1024_channels.onnx")
def conv_grouped_many_groups():
"""Grouped 1x1 Conv with many groups and high channel counts."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 2, 2])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 2, 2])
W = numpy_helper.from_array(
np.random.default_rng(77).uniform(-1, 1, (1024, 64, 1, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0], group=64)
graph = helper.make_graph([node], "conv_grouped_many_groups", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/grouped_many_groups", "conv_grouped_many_groups.onnx")
def conv_non_square_kernel_1x3():
"""Conv with a non-square 1x3 kernel."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 5, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 5, 3])
W = numpy_helper.from_array(
np.random.default_rng(78).uniform(-1, 1, (4, 3, 1, 3)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 3], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_non_square_kernel_1x3", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/non_square_kernel_1x3", "conv_non_square_kernel_1x3.onnx")
def conv_non_square_kernel_3x1():
"""Conv with a non-square 3x1 kernel."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 5, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 3, 5])
W = numpy_helper.from_array(
np.random.default_rng(79).uniform(-1, 1, (4, 3, 3, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[3, 1], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_non_square_kernel_3x1", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/non_square_kernel_3x1", "conv_non_square_kernel_3x1.onnx")
def conv_non_uniform_stride():
"""Conv with non-uniform stride across spatial dimensions."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 6, 7])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 4, 3])
W = numpy_helper.from_array(
np.random.default_rng(80).uniform(-1, 1, (4, 3, 3, 3)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[3, 3], strides=[1, 2], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_non_uniform_stride", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/non_uniform_stride", "conv_non_uniform_stride.onnx")
def conv_dilated_3x3():
"""Conv with a dilated 3x3 kernel."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 7, 7])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 3, 3])
W = numpy_helper.from_array(
np.random.default_rng(81).uniform(-1, 1, (1, 1, 3, 3)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[3, 3], strides=[1, 1], pads=[0, 0, 0, 0], dilations=[2, 2])
graph = helper.make_graph([node], "conv_dilated_3x3", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/dilated_3x3", "conv_dilated_3x3.onnx")
def conv_real_asymmetric_padding():
"""Conv with truly asymmetric explicit padding."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 4, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2, 4, 7])
W = numpy_helper.from_array(
np.random.default_rng(82).uniform(-1, 1, (2, 1, 3, 2)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[3, 2], strides=[1, 1], pads=[0, 1, 2, 3])
graph = helper.make_graph([node], "conv_real_asymmetric_padding", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/real_asymmetric_padding", "conv_real_asymmetric_padding.onnx")
def conv_same_lower_3x3():
"""Conv 3x3 with SAME_LOWER padding, preserving spatial dimensions."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 5, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 5, 5])
W = numpy_helper.from_array(
np.random.default_rng(83).uniform(-1, 1, (1, 1, 3, 3)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[3, 3], strides=[1, 1], auto_pad="SAME_LOWER")
graph = helper.make_graph([node], "conv_same_lower_3x3", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/same_lower_3x3", "conv_same_lower_3x3.onnx")
def conv_kernel_equals_input_spatial():
"""Conv where the kernel spans the full input spatial extent."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 7, 7])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 8, 1, 1])
W = numpy_helper.from_array(
np.random.default_rng(84).uniform(-1, 1, (8, 3, 7, 7)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[7, 7], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_kernel_equals_input_spatial", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/kernel_equals_input_spatial", "conv_kernel_equals_input_spatial.onnx")
def conv_batch_4_pointwise():
"""Batched 1x1 Conv with batch size 4."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [4, 128, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [4, 64, 1, 1])
W = numpy_helper.from_array(
np.random.default_rng(85).uniform(-1, 1, (64, 128, 1, 1)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"],
kernel_shape=[1, 1], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_batch_4_pointwise", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/batch_4_pointwise", "conv_batch_4_pointwise.onnx")
def conv_without_kernel_shape_attr():
"""Conv where kernel_shape is inferred from the weight tensor."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 5, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 3, 3])
W = numpy_helper.from_array(
np.random.default_rng(86).uniform(-1, 1, (1, 1, 3, 3)).astype(np.float32), name="W")
node = helper.make_node("Conv", ["X", "W"], ["Y"], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "conv_without_kernel_shape_attr", [X], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "conv/without_kernel_shape_attr", "conv_without_kernel_shape_attr.onnx")
# ---------------------------------------------------------------------------
# GEMM tests
# ---------------------------------------------------------------------------
@@ -372,6 +565,90 @@ def gemm_dynamic_bias_alpha_beta():
save_model(model, "gemm/dynamic_bias_alpha_beta", "gemm_dynamic_bias_alpha_beta.onnx")
def gemm_huge_1024():
"""Huge GEMM with 1024-wide inner and output dimensions."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024])
W = numpy_helper.from_array(
np.random.default_rng(87).uniform(-1, 1, (1024, 1024)).astype(np.float32), name="W")
node = helper.make_node("Gemm", ["A", "W"], ["Y"])
graph = helper.make_graph([node], "gemm_huge_1024", [A], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/huge_1024", "gemm_huge_1024.onnx")
def gemm_large_k_small_n():
"""GEMM with large K and smaller output width."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 64])
W = numpy_helper.from_array(
np.random.default_rng(88).uniform(-1, 1, (1024, 64)).astype(np.float32), name="W")
node = helper.make_node("Gemm", ["A", "W"], ["Y"])
graph = helper.make_graph([node], "gemm_large_k_small_n", [A], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/large_k_small_n", "gemm_large_k_small_n.onnx")
def gemm_small_k_large_n():
"""GEMM with modest K and very large output width."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 64])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024])
W = numpy_helper.from_array(
np.random.default_rng(89).uniform(-1, 1, (64, 1024)).astype(np.float32), name="W")
node = helper.make_node("Gemm", ["A", "W"], ["Y"])
graph = helper.make_graph([node], "gemm_small_k_large_n", [A], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/small_k_large_n", "gemm_small_k_large_n.onnx")
def gemm_transA():
"""GEMM with transA=1: A is stored as [K, M] and used as [M, K]."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [8, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [4, 6])
W = numpy_helper.from_array(np.random.default_rng(90).uniform(-1, 1, (8, 6)).astype(np.float32), name="W")
node = helper.make_node("Gemm", ["A", "W"], ["Y"], transA=1)
graph = helper.make_graph([node], "gemm_transA", [A], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/transA", "gemm_transA.onnx")
def gemm_transA_transB():
"""GEMM with transA=1 and transB=1."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [8, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [4, 6])
W = numpy_helper.from_array(np.random.default_rng(91).uniform(-1, 1, (6, 8)).astype(np.float32), name="W")
node = helper.make_node("Gemm", ["A", "W"], ["Y"], transA=1, transB=1)
graph = helper.make_graph([node], "gemm_transA_transB", [A], [Y], initializer=[W])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/transA_transB", "gemm_transA_transB.onnx")
def gemm_bias_rank2_broadcast():
"""GEMM with rank-2 bias broadcasting across rows."""
rng = np.random.default_rng(92)
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [4, 8])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [4, 6])
W = numpy_helper.from_array(rng.uniform(-1, 1, (8, 6)).astype(np.float32), name="W")
C = numpy_helper.from_array(rng.uniform(-1, 1, (1, 6)).astype(np.float32), name="C")
node = helper.make_node("Gemm", ["A", "W", "C"], ["Y"])
graph = helper.make_graph([node], "gemm_bias_rank2_broadcast", [A], [Y], initializer=[W, C])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/bias_rank2_broadcast", "gemm_bias_rank2_broadcast.onnx")
def gemm_scalar_bias():
"""GEMM with scalar bias broadcasting to the full output."""
rng = np.random.default_rng(93)
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [4, 8])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [4, 6])
W = numpy_helper.from_array(rng.uniform(-1, 1, (8, 6)).astype(np.float32), name="W")
C = numpy_helper.from_array(np.asarray(0.25, dtype=np.float32), name="C")
node = helper.make_node("Gemm", ["A", "W", "C"], ["Y"])
graph = helper.make_graph([node], "gemm_scalar_bias", [A], [Y], initializer=[W, C])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gemm/scalar_bias", "gemm_scalar_bias.onnx")
# ---------------------------------------------------------------------------
# MatMul tests
# ---------------------------------------------------------------------------
@@ -468,6 +745,62 @@ def matmul_batched_lhs_broadcast():
save_model(model, "matmul/batched_lhs_broadcast", "matmul_batched_lhs_broadcast.onnx")
def matmul_huge_1024():
"""Huge MatMul with 1024-wide inner and output dimensions."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024])
B = numpy_helper.from_array(
np.random.default_rng(94).uniform(-1, 1, (1024, 1024)).astype(np.float32), name="B")
node = helper.make_node("MatMul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "matmul_huge_1024", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "matmul/huge_1024", "matmul_huge_1024.onnx")
def matmul_vector_matrix():
"""Vector-matrix MatMul producing a 1D output."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [64])
B = numpy_helper.from_array(np.random.default_rng(95).uniform(-1, 1, (1024, 64)).astype(np.float32), name="B")
node = helper.make_node("MatMul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "matmul_vector_matrix", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "matmul/vector_matrix", "matmul_vector_matrix.onnx")
def matmul_matrix_vector():
"""Matrix-vector MatMul producing a 1D output."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [64, 1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [64])
B = numpy_helper.from_array(np.random.default_rng(96).uniform(-1, 1, (1024,)).astype(np.float32), name="B")
node = helper.make_node("MatMul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "matmul_matrix_vector", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "matmul/matrix_vector", "matmul_matrix_vector.onnx")
def matmul_vector_vector_dot():
"""Vector-vector MatMul producing a scalar output."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [])
B = numpy_helper.from_array(np.random.default_rng(97).uniform(-1, 1, (1024,)).astype(np.float32), name="B")
node = helper.make_node("MatMul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "matmul_vector_vector_dot", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "matmul/vector_vector_dot", "matmul_vector_vector_dot.onnx")
def matmul_batched_4d_broadcast():
"""Batched 4D MatMul with broadcast across leading dimensions."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [2, 1, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 5, 3, 6])
B = numpy_helper.from_array(np.random.default_rng(98).uniform(-1, 1, (1, 5, 4, 6)).astype(np.float32), name="B")
node = helper.make_node("MatMul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "matmul_batched_4d_broadcast", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "matmul/batched_4d_broadcast", "matmul_batched_4d_broadcast.onnx")
# ---------------------------------------------------------------------------
# Pooling tests
# ---------------------------------------------------------------------------
@@ -547,6 +880,92 @@ def maxpool_after_conv():
save_model(model, "pool/max_after_conv", "maxpool_after_conv.onnx")
def maxpool_ceil_mode():
"""MaxPool with ceil_mode enabled."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 5, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 2, 2])
node = helper.make_node("MaxPool", ["X"], ["Y"],
kernel_shape=[2, 2], strides=[2, 2], pads=[0, 0, 0, 0], ceil_mode=1)
graph = helper.make_graph([node], "maxpool_ceil_mode", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/max_ceil_mode", "maxpool_ceil_mode.onnx")
def avgpool_ceil_mode():
"""AveragePool with ceil_mode enabled."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2, 5, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2, 2, 2])
node = helper.make_node("AveragePool", ["X"], ["Y"],
kernel_shape=[2, 2], strides=[2, 2], pads=[0, 0, 0, 0], ceil_mode=1)
graph = helper.make_graph([node], "avgpool_ceil_mode", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/avg_ceil_mode", "avgpool_ceil_mode.onnx")
def maxpool_real_asymmetric_padding():
"""MaxPool with truly asymmetric explicit padding."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 4, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 4, 3])
node = helper.make_node("MaxPool", ["X"], ["Y"],
kernel_shape=[3, 3], strides=[1, 2], pads=[0, 1, 2, 1])
graph = helper.make_graph([node], "maxpool_real_asymmetric_padding", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/max_real_asymmetric_padding", "maxpool_real_asymmetric_padding.onnx")
def avgpool_real_asymmetric_padding():
"""AveragePool with truly asymmetric explicit padding."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 2, 4, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 2, 4, 3])
node = helper.make_node("AveragePool", ["X"], ["Y"],
kernel_shape=[3, 3], strides=[1, 2], pads=[0, 1, 2, 1], count_include_pad=0)
graph = helper.make_graph([node], "avgpool_real_asymmetric_padding", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/avg_real_asymmetric_padding", "avgpool_real_asymmetric_padding.onnx")
def maxpool_non_square_kernel():
"""MaxPool with a non-square kernel."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 5, 6])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 3, 4, 2])
node = helper.make_node("MaxPool", ["X"], ["Y"],
kernel_shape=[2, 3], strides=[1, 2], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "maxpool_non_square_kernel", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/max_non_square_kernel", "maxpool_non_square_kernel.onnx")
def avgpool_non_uniform_stride():
"""AveragePool with non-uniform stride."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 5, 6])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 3, 4, 2])
node = helper.make_node("AveragePool", ["X"], ["Y"],
kernel_shape=[2, 3], strides=[1, 2], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "avgpool_non_uniform_stride", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/avg_non_uniform_stride", "avgpool_non_uniform_stride.onnx")
def maxpool_global_style_kernel_equals_input():
"""MaxPool where the kernel covers the full spatial input."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 8, 4, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 8, 1, 1])
node = helper.make_node("MaxPool", ["X"], ["Y"], kernel_shape=[4, 4], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "maxpool_global_style_kernel_equals_input", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/max_global_style_kernel_equals_input", "maxpool_global_style_kernel_equals_input.onnx")
def avgpool_large_channels():
"""AveragePool with a large channel count and small spatial dimensions."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 2, 2])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
node = helper.make_node("AveragePool", ["X"], ["Y"], kernel_shape=[2, 2], strides=[1, 1], pads=[0, 0, 0, 0])
graph = helper.make_graph([node], "avgpool_large_channels", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "pool/avg_large_channels", "avgpool_large_channels.onnx")
# ---------------------------------------------------------------------------
# ReduceMean tests
# ---------------------------------------------------------------------------
@@ -596,6 +1015,66 @@ def reducemean_after_conv():
save_model(model, "reduce_mean/after_conv", "reduce_mean_after_conv.onnx")
def reducemean_negative_axis():
"""ReduceMean using a negative axis."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 1])
node = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[-1], keepdims=1)
graph = helper.make_graph([node], "reducemean_negative_axis", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reduce_mean/negative_axis", "reduce_mean_negative_axis.onnx")
def reducemean_all_axes_keepdims_1():
"""ReduceMean across all axes while preserving rank."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 1])
node = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[0, 1, 2], keepdims=1)
graph = helper.make_graph([node], "reducemean_all_axes_keepdims_1", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reduce_mean/all_axes_keepdims_1", "reduce_mean_all_axes_keepdims_1.onnx")
def reducemean_all_axes_keepdims_0():
"""ReduceMean across all axes producing a scalar."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [])
node = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[0, 1, 2], keepdims=0)
graph = helper.make_graph([node], "reducemean_all_axes_keepdims_0", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reduce_mean/all_axes_keepdims_0", "reduce_mean_all_axes_keepdims_0.onnx")
def reducemean_4d_spatial_keepdims_0():
"""ReduceMean over H and W on an NCHW tensor, dropping reduced axes."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 4, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 3])
node = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[2, 3], keepdims=0)
graph = helper.make_graph([node], "reducemean_4d_spatial_keepdims_0", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reduce_mean/4d_spatial_keepdims_0", "reduce_mean_4d_spatial_keepdims_0.onnx")
def reducemean_channel_axis_nchw():
"""ReduceMean over the channel axis of an NCHW tensor."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024, 2, 2])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 2, 2])
node = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[1], keepdims=1)
graph = helper.make_graph([node], "reducemean_channel_axis_nchw", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reduce_mean/channel_axis_nchw", "reduce_mean_channel_axis_nchw.onnx")
def reducemean_large_dimension_1024():
"""ReduceMean over a large 1024-length dimension."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1])
node = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[1], keepdims=1)
graph = helper.make_graph([node], "reducemean_large_dimension_1024", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reduce_mean/large_dimension_1024", "reduce_mean_large_dimension_1024.onnx")
# ---------------------------------------------------------------------------
# Relu tests
# ---------------------------------------------------------------------------
@@ -723,6 +1202,26 @@ def softmax_channel_axis():
save_model(model, "softmax/channel_axis", "softmax_channel_axis.onnx")
def softmax_negative_axis():
"""Softmax using a negative axis."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 4])
node = helper.make_node("Softmax", ["X"], ["Y"], axis=-1)
graph = helper.make_graph([node], "softmax_negative_axis", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "softmax/negative_axis", "softmax_negative_axis.onnx")
def softmax_large_dimension_1024():
"""Softmax across a large last dimension."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1024])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024])
node = helper.make_node("Softmax", ["X"], ["Y"], axis=1)
graph = helper.make_graph([node], "softmax_large_dimension_1024", [X], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "softmax/large_dimension_1024", "softmax_large_dimension_1024.onnx")
# ---------------------------------------------------------------------------
# Resize tests
# ---------------------------------------------------------------------------
@@ -769,6 +1268,48 @@ def resize_with_sizes():
save_model(model, "resize/with_sizes", "resize_with_sizes.onnx")
def resize_nearest_downsample():
"""Resize an NCHW tensor with nearest-neighbor downsampling."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 4, 6])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 2, 3])
roi = numpy_helper.from_array(np.asarray([], dtype=np.float32), name="roi")
scales = numpy_helper.from_array(np.asarray([1.0, 1.0, 0.5, 0.5], dtype=np.float32), name="scales")
node = helper.make_node(
"Resize", ["X", "roi", "scales"], ["Y"],
mode="nearest", coordinate_transformation_mode="asymmetric", nearest_mode="floor")
graph = helper.make_graph([node], "resize_nearest_downsample", [X], [Y], initializer=[roi, scales])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "resize/nearest_downsample", "resize_nearest_downsample.onnx")
def resize_height_only():
"""Resize only the height dimension of an NCHW tensor."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 2, 3])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 4, 3])
roi = numpy_helper.from_array(np.asarray([], dtype=np.float32), name="roi")
scales = numpy_helper.from_array(np.asarray([1.0, 1.0, 2.0, 1.0], dtype=np.float32), name="scales")
node = helper.make_node(
"Resize", ["X", "roi", "scales"], ["Y"],
mode="nearest", coordinate_transformation_mode="asymmetric", nearest_mode="floor")
graph = helper.make_graph([node], "resize_height_only", [X], [Y], initializer=[roi, scales])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "resize/height_only", "resize_height_only.onnx")
def resize_width_only():
"""Resize only the width dimension of an NCHW tensor."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 1, 2, 3])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1, 2, 6])
roi = numpy_helper.from_array(np.asarray([], dtype=np.float32), name="roi")
scales = numpy_helper.from_array(np.asarray([1.0, 1.0, 1.0, 2.0], dtype=np.float32), name="scales")
node = helper.make_node(
"Resize", ["X", "roi", "scales"], ["Y"],
mode="nearest", coordinate_transformation_mode="asymmetric", nearest_mode="floor")
graph = helper.make_graph([node], "resize_width_only", [X], [Y], initializer=[roi, scales])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "resize/width_only", "resize_width_only.onnx")
# ---------------------------------------------------------------------------
# Split tests
# ---------------------------------------------------------------------------
@@ -797,6 +1338,30 @@ def split_equal_three_way():
save_model(model, "split/equal_three_way", "split_equal_three_way.onnx")
def split_negative_axis():
"""Split a tensor using a negative axis."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 6])
Y0 = helper.make_tensor_value_info("Y0", TensorProto.FLOAT, [2, 3, 2])
Y1 = helper.make_tensor_value_info("Y1", TensorProto.FLOAT, [2, 3, 4])
split = make_int64_initializer("split", [2, 4])
node = helper.make_node("Split", ["X", "split"], ["Y0", "Y1"], axis=-1)
graph = helper.make_graph([node], "split_negative_axis", [X], [Y0, Y1], initializer=[split])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "split/negative_axis", "split_negative_axis.onnx")
def split_uneven_channel_axis_4d():
"""Split an NCHW tensor unevenly along the channel axis."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 7, 2, 2])
Y0 = helper.make_tensor_value_info("Y0", TensorProto.FLOAT, [1, 2, 2, 2])
Y1 = helper.make_tensor_value_info("Y1", TensorProto.FLOAT, [1, 5, 2, 2])
split = make_int64_initializer("split", [2, 5])
node = helper.make_node("Split", ["X", "split"], ["Y0", "Y1"], axis=1)
graph = helper.make_graph([node], "split_uneven_channel_axis_4d", [X], [Y0, Y1], initializer=[split])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "split/uneven_channel_axis_4d", "split_uneven_channel_axis_4d.onnx")
# ---------------------------------------------------------------------------
# Gather tests
# ---------------------------------------------------------------------------
@@ -823,6 +1388,39 @@ def gather_axis0_matrix_indices():
save_model(model, "gather/axis0_matrix_indices", "gather_axis0_matrix_indices.onnx")
def gather_negative_indices():
"""Gather with negative indices along axis 0."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [4, 3])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3])
indices = make_int64_initializer("indices", [-1, -3])
node = helper.make_node("Gather", ["X", "indices"], ["Y"], axis=0)
graph = helper.make_graph([node], "gather_negative_indices", [X], [Y], initializer=[indices])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gather/negative_indices", "gather_negative_indices.onnx")
def gather_negative_axis():
"""Gather using a negative axis."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 2])
indices = make_int64_initializer("indices", [0, 2])
node = helper.make_node("Gather", ["X", "indices"], ["Y"], axis=-1)
graph = helper.make_graph([node], "gather_negative_axis", [X], [Y], initializer=[indices])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gather/negative_axis", "gather_negative_axis.onnx")
def gather_3d_input_axis1():
"""Gather along axis 1 of a 3D input tensor."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 4, 3])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 2, 3])
indices = make_int64_initializer("indices", [1, 3])
node = helper.make_node("Gather", ["X", "indices"], ["Y"], axis=1)
graph = helper.make_graph([node], "gather_3d_input_axis1", [X], [Y], initializer=[indices])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "gather/3d_input_axis1", "gather_3d_input_axis1.onnx")
# ---------------------------------------------------------------------------
# Concat tests
# ---------------------------------------------------------------------------
@@ -838,6 +1436,29 @@ def concat_channel_axis():
save_model(model, "concat/channel_axis", "concat_channel_axis.onnx")
def concat_negative_axis():
"""Concat along a negative axis."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [2, 3, 2])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 6])
node = helper.make_node("Concat", ["A", "B"], ["Y"], axis=-1)
graph = helper.make_graph([node], "concat_negative_axis", [A, B], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "concat/negative_axis", "concat_negative_axis.onnx")
def concat_three_inputs_channel_axis():
"""Concat three runtime NCHW tensors along the channel axis."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1, 2, 2])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 2, 2, 2])
C = helper.make_tensor_value_info("C", TensorProto.FLOAT, [1, 3, 2, 2])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 6, 2, 2])
node = helper.make_node("Concat", ["A", "B", "C"], ["Y"], axis=1)
graph = helper.make_graph([node], "concat_three_inputs_channel_axis", [A, B, C], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "concat/three_inputs_channel_axis", "concat_three_inputs_channel_axis.onnx")
# ---------------------------------------------------------------------------
# Reshape tests
# ---------------------------------------------------------------------------
@@ -853,6 +1474,39 @@ def reshape_same_rank():
save_model(model, "reshape/same_rank", "reshape_same_rank.onnx")
def reshape_infer_dim_minus_one():
"""Reshape using -1 to infer one output dimension."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 12])
shape = make_int64_initializer("shape", [2, -1])
node = helper.make_node("Reshape", ["X", "shape"], ["Y"])
graph = helper.make_graph([node], "reshape_infer_dim_minus_one", [X], [Y], initializer=[shape])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reshape/infer_dim_minus_one", "reshape_infer_dim_minus_one.onnx")
def reshape_zero_copies_input_dim():
"""Reshape using 0 to copy an input dimension."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 12])
shape = make_int64_initializer("shape", [0, -1])
node = helper.make_node("Reshape", ["X", "shape"], ["Y"])
graph = helper.make_graph([node], "reshape_zero_copies_input_dim", [X], [Y], initializer=[shape])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reshape/zero_copies_input_dim", "reshape_zero_copies_input_dim.onnx")
def reshape_4d_to_2d_flatten():
"""Reshape a 4D tensor to a 2D flattened view."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 3, 4, 5])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 60])
shape = make_int64_initializer("shape", [1, 60])
node = helper.make_node("Reshape", ["X", "shape"], ["Y"])
graph = helper.make_graph([node], "reshape_4d_to_2d_flatten", [X], [Y], initializer=[shape])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "reshape/4d_to_2d_flatten", "reshape_4d_to_2d_flatten.onnx")
# ---------------------------------------------------------------------------
# Add tests
# ---------------------------------------------------------------------------
@@ -895,6 +1549,39 @@ def add_after_gemm():
save_model(model, "add/after_gemm", "add_after_gemm.onnx")
def add_channel_broadcast_1024():
"""Elementwise Add with NCHW per-channel broadcasting over 1024 channels."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024, 1, 1])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
node = helper.make_node("Add", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "add_channel_broadcast_1024", [A, B], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "add/channel_broadcast_1024", "add_channel_broadcast_1024.onnx")
def add_scalar_runtime():
"""Elementwise Add with a runtime scalar RHS."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024, 1, 1])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 1, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
node = helper.make_node("Add", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "add_scalar_runtime", [A, B], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "add/scalar_runtime", "add_scalar_runtime.onnx")
def add_leading_dimension_broadcast():
"""Elementwise Add with trailing-dimension broadcasting."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 4])
B = numpy_helper.from_array(np.random.default_rng(99).uniform(-1, 1, (4,)).astype(np.float32), name="B")
node = helper.make_node("Add", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "add_leading_dimension_broadcast", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "add/leading_dimension_broadcast", "add_leading_dimension_broadcast.onnx")
# ---------------------------------------------------------------------------
# Mul tests
# ---------------------------------------------------------------------------
@@ -937,6 +1624,39 @@ def mul_after_conv():
save_model(model, "mul/after_conv", "mul_after_conv.onnx")
def mul_channel_broadcast_1024():
"""Elementwise Mul with NCHW per-channel broadcasting over 1024 channels."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024, 1, 1])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
node = helper.make_node("Mul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "mul_channel_broadcast_1024", [A, B], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "mul/channel_broadcast_1024", "mul_channel_broadcast_1024.onnx")
def mul_scalar_runtime():
"""Elementwise Mul with a runtime scalar RHS."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024, 1, 1])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 1, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
node = helper.make_node("Mul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "mul_scalar_runtime", [A, B], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "mul/scalar_runtime", "mul_scalar_runtime.onnx")
def mul_leading_dimension_broadcast():
"""Elementwise Mul with trailing-dimension broadcasting."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 4])
B = numpy_helper.from_array(np.random.default_rng(100).uniform(-1, 1, (4,)).astype(np.float32), name="B")
node = helper.make_node("Mul", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "mul_leading_dimension_broadcast", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "mul/leading_dimension_broadcast", "mul_leading_dimension_broadcast.onnx")
# ---------------------------------------------------------------------------
# Div tests
# ---------------------------------------------------------------------------
@@ -979,6 +1699,50 @@ def div_after_gemm():
save_model(model, "div/after_gemm", "div_after_gemm.onnx")
def div_channel_broadcast_1024():
"""Elementwise Div with NCHW per-channel broadcasting over 1024 channels."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
B = numpy_helper.from_array(np.random.default_rng(102).uniform(0.5, 2.0, (1, 1024, 1, 1)).astype(np.float32), name="B")
node = helper.make_node("Div", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "div_channel_broadcast_1024", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "div/channel_broadcast_1024", "div_channel_broadcast_1024.onnx")
def div_runtime_scalar_rhs():
"""Elementwise Div by a scalar constant."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
B = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="B")
node = helper.make_node("Div", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "div_runtime_scalar_rhs", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "div/runtime_scalar_rhs", "div_runtime_scalar_rhs.onnx")
def div_runtime_scalar_lhs():
"""Elementwise Div with a scalar constant numerator."""
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 1024, 1, 1])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 1024, 1, 1])
A = numpy_helper.from_array(np.asarray([[[[2.0]]]], dtype=np.float32), name="A")
node = helper.make_node("Div", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "div_runtime_scalar_lhs", [B], [Y], initializer=[A])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "div/runtime_scalar_lhs", "div_runtime_scalar_lhs.onnx")
def div_leading_dimension_broadcast():
"""Elementwise Div with trailing-dimension broadcasting."""
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [2, 3, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [2, 3, 4])
B = numpy_helper.from_array(np.random.default_rng(101).uniform(0.5, 2.0, (4,)).astype(np.float32), name="B")
node = helper.make_node("Div", ["A", "B"], ["Y"])
graph = helper.make_graph([node], "div_leading_dimension_broadcast", [A], [Y], initializer=[B])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "div/leading_dimension_broadcast", "div_leading_dimension_broadcast.onnx")
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
@@ -999,6 +1763,13 @@ if __name__ == "__main__":
gemm_dynamic_alpha()
gemm_dynamic_beta()
gemm_dynamic_bias_alpha_beta()
gemm_huge_1024()
gemm_large_k_small_n()
gemm_small_k_large_n()
gemm_transA()
gemm_transA_transB()
gemm_bias_rank2_broadcast()
gemm_scalar_bias()
print("\nGenerating Conv tests:")
conv_3x3_kernel()
@@ -1013,6 +1784,21 @@ if __name__ == "__main__":
conv_grouped_two_groups()
conv_depthwise_grouped()
conv_dynamic()
conv_huge_pointwise_1024()
conv_huge_pointwise_1024_dynamic()
conv_large_output_channels_1x1()
conv_large_input_channels_1x1()
conv_depthwise_1024_channels()
conv_grouped_many_groups()
conv_non_square_kernel_1x3()
conv_non_square_kernel_3x1()
conv_non_uniform_stride()
conv_dilated_3x3()
conv_real_asymmetric_padding()
conv_same_lower_3x3()
conv_kernel_equals_input_spatial()
conv_batch_4_pointwise()
conv_without_kernel_shape_attr()
print("\nGenerating MatMul tests:")
matmul_basic()
@@ -1023,6 +1809,11 @@ if __name__ == "__main__":
matmul_batched_left_constant()
matmul_batched_rhs_broadcast()
matmul_batched_lhs_broadcast()
matmul_huge_1024()
matmul_vector_matrix()
matmul_matrix_vector()
matmul_vector_vector_dot()
matmul_batched_4d_broadcast()
print("\nGenerating Pooling tests:")
maxpool_basic()
@@ -1032,12 +1823,26 @@ if __name__ == "__main__":
avgpool_explicit_padding()
avgpool_include_pad()
maxpool_after_conv()
maxpool_ceil_mode()
avgpool_ceil_mode()
maxpool_real_asymmetric_padding()
avgpool_real_asymmetric_padding()
maxpool_non_square_kernel()
avgpool_non_uniform_stride()
maxpool_global_style_kernel_equals_input()
avgpool_large_channels()
print("\nGenerating ReduceMean tests:")
reducemean_basic()
reducemean_keepdims_0()
reducemean_4d_spatial()
reducemean_after_conv()
reducemean_negative_axis()
reducemean_all_axes_keepdims_1()
reducemean_all_axes_keepdims_0()
reducemean_4d_spatial_keepdims_0()
reducemean_channel_axis_nchw()
reducemean_large_dimension_1024()
print("\nGenerating Relu tests:")
relu_basic()
@@ -1053,40 +1858,65 @@ if __name__ == "__main__":
print("\nGenerating Split tests:")
split_basic()
split_equal_three_way()
split_negative_axis()
split_uneven_channel_axis_4d()
print("\nGenerating Softmax tests:")
softmax_basic()
softmax_3d_last_axis()
softmax_channel_axis()
softmax_negative_axis()
softmax_large_dimension_1024()
print("\nGenerating Resize tests:")
resize_nearest_2x()
resize_nearest_non_uniform()
resize_with_sizes()
resize_nearest_downsample()
resize_height_only()
resize_width_only()
print("\nGenerating Gather tests:")
gather_axis1()
gather_axis0_matrix_indices()
gather_negative_indices()
gather_negative_axis()
gather_3d_input_axis1()
print("\nGenerating Concat tests:")
concat_channel_axis()
concat_negative_axis()
concat_three_inputs_channel_axis()
print("\nGenerating Reshape tests:")
reshape_same_rank()
reshape_infer_dim_minus_one()
reshape_zero_copies_input_dim()
reshape_4d_to_2d_flatten()
print("\nGenerating Add tests:")
add_basic()
add_broadcast_row()
add_after_gemm()
add_channel_broadcast_1024()
add_scalar_runtime()
add_leading_dimension_broadcast()
print("\nGenerating Mul tests:")
mul_basic()
mul_scalar_constant()
mul_after_conv()
mul_channel_broadcast_1024()
mul_scalar_runtime()
mul_leading_dimension_broadcast()
print("\nGenerating Div tests:")
div_basic()
div_scalar_constant()
div_after_gemm()
div_channel_broadcast_1024()
div_runtime_scalar_rhs()
div_runtime_scalar_lhs()
div_leading_dimension_broadcast()
print("\nDone.")