This commit is contained in:
@@ -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.")
|
||||
|
||||
Reference in New Issue
Block a user