diff --git a/validation/operations/add/channel_broadcast_1024/add_channel_broadcast_1024.onnx b/validation/operations/add/channel_broadcast_1024/add_channel_broadcast_1024.onnx new file mode 100644 index 0000000..8b563ec Binary files /dev/null and b/validation/operations/add/channel_broadcast_1024/add_channel_broadcast_1024.onnx differ diff --git a/validation/operations/add/leading_dimension_broadcast/add_leading_dimension_broadcast.onnx b/validation/operations/add/leading_dimension_broadcast/add_leading_dimension_broadcast.onnx new file mode 100644 index 0000000..46c7b83 Binary files /dev/null and b/validation/operations/add/leading_dimension_broadcast/add_leading_dimension_broadcast.onnx differ diff --git a/validation/operations/add/scalar_runtime/add_scalar_runtime.onnx b/validation/operations/add/scalar_runtime/add_scalar_runtime.onnx new file mode 100644 index 0000000..4d138c1 Binary files /dev/null and b/validation/operations/add/scalar_runtime/add_scalar_runtime.onnx differ diff --git a/validation/operations/concat/negative_axis/concat_negative_axis.onnx b/validation/operations/concat/negative_axis/concat_negative_axis.onnx new file mode 100644 index 0000000..f2ceaa0 Binary files /dev/null and b/validation/operations/concat/negative_axis/concat_negative_axis.onnx differ diff --git a/validation/operations/concat/three_inputs_channel_axis/concat_three_inputs_channel_axis.onnx b/validation/operations/concat/three_inputs_channel_axis/concat_three_inputs_channel_axis.onnx new file mode 100644 index 0000000..5178101 Binary files /dev/null and b/validation/operations/concat/three_inputs_channel_axis/concat_three_inputs_channel_axis.onnx differ diff --git a/validation/operations/conv/batch_4_pointwise/conv_batch_4_pointwise.onnx b/validation/operations/conv/batch_4_pointwise/conv_batch_4_pointwise.onnx new file mode 100644 index 0000000..52feeec Binary files /dev/null and b/validation/operations/conv/batch_4_pointwise/conv_batch_4_pointwise.onnx differ diff --git a/validation/operations/conv/depthwise_1024_channels/conv_depthwise_1024_channels.onnx b/validation/operations/conv/depthwise_1024_channels/conv_depthwise_1024_channels.onnx new file mode 100644 index 0000000..fe2b99e Binary files /dev/null and b/validation/operations/conv/depthwise_1024_channels/conv_depthwise_1024_channels.onnx differ diff --git a/validation/operations/conv/dilated_3x3/conv_dilated_3x3.onnx b/validation/operations/conv/dilated_3x3/conv_dilated_3x3.onnx new file mode 100644 index 0000000..7602a5a Binary files /dev/null and b/validation/operations/conv/dilated_3x3/conv_dilated_3x3.onnx differ diff --git a/validation/operations/conv/grouped_many_groups/conv_grouped_many_groups.onnx b/validation/operations/conv/grouped_many_groups/conv_grouped_many_groups.onnx new file mode 100644 index 0000000..7df7a8e Binary files /dev/null and b/validation/operations/conv/grouped_many_groups/conv_grouped_many_groups.onnx differ diff --git a/validation/operations/conv/huge_pointwise_1024/conv_huge_pointwise_1024.onnx b/validation/operations/conv/huge_pointwise_1024/conv_huge_pointwise_1024.onnx new file mode 100644 index 0000000..517d3c8 Binary files /dev/null and b/validation/operations/conv/huge_pointwise_1024/conv_huge_pointwise_1024.onnx differ diff --git a/validation/operations/conv/huge_pointwise_1024_dynamic/conv_huge_pointwise_1024_dynamic.onnx b/validation/operations/conv/huge_pointwise_1024_dynamic/conv_huge_pointwise_1024_dynamic.onnx new file mode 100644 index 0000000..f5ce95d Binary files /dev/null and b/validation/operations/conv/huge_pointwise_1024_dynamic/conv_huge_pointwise_1024_dynamic.onnx differ diff --git a/validation/operations/conv/kernel_equals_input_spatial/conv_kernel_equals_input_spatial.onnx b/validation/operations/conv/kernel_equals_input_spatial/conv_kernel_equals_input_spatial.onnx new file mode 100644 index 0000000..ecad81a Binary files /dev/null and b/validation/operations/conv/kernel_equals_input_spatial/conv_kernel_equals_input_spatial.onnx differ diff --git a/validation/operations/conv/large_input_channels_1x1/conv_large_input_channels_1x1.onnx b/validation/operations/conv/large_input_channels_1x1/conv_large_input_channels_1x1.onnx new file mode 100644 index 0000000..858b451 Binary files /dev/null and b/validation/operations/conv/large_input_channels_1x1/conv_large_input_channels_1x1.onnx differ diff --git a/validation/operations/conv/large_output_channels_1x1/conv_large_output_channels_1x1.onnx b/validation/operations/conv/large_output_channels_1x1/conv_large_output_channels_1x1.onnx new file mode 100644 index 0000000..2c3b410 Binary files /dev/null and b/validation/operations/conv/large_output_channels_1x1/conv_large_output_channels_1x1.onnx differ diff --git a/validation/operations/conv/non_square_kernel_1x3/conv_non_square_kernel_1x3.onnx b/validation/operations/conv/non_square_kernel_1x3/conv_non_square_kernel_1x3.onnx new file mode 100644 index 0000000..118ed6b Binary files /dev/null and b/validation/operations/conv/non_square_kernel_1x3/conv_non_square_kernel_1x3.onnx differ diff --git a/validation/operations/conv/non_square_kernel_3x1/conv_non_square_kernel_3x1.onnx b/validation/operations/conv/non_square_kernel_3x1/conv_non_square_kernel_3x1.onnx new file mode 100644 index 0000000..b60dfa2 Binary files /dev/null and b/validation/operations/conv/non_square_kernel_3x1/conv_non_square_kernel_3x1.onnx differ diff --git a/validation/operations/conv/non_uniform_stride/conv_non_uniform_stride.onnx b/validation/operations/conv/non_uniform_stride/conv_non_uniform_stride.onnx new file mode 100644 index 0000000..9f2a692 Binary files /dev/null and b/validation/operations/conv/non_uniform_stride/conv_non_uniform_stride.onnx differ diff --git a/validation/operations/conv/real_asymmetric_padding/conv_real_asymmetric_padding.onnx b/validation/operations/conv/real_asymmetric_padding/conv_real_asymmetric_padding.onnx new file mode 100644 index 0000000..481f0ec Binary files /dev/null and b/validation/operations/conv/real_asymmetric_padding/conv_real_asymmetric_padding.onnx differ diff --git a/validation/operations/conv/same_lower_3x3/conv_same_lower_3x3.onnx b/validation/operations/conv/same_lower_3x3/conv_same_lower_3x3.onnx new file mode 100644 index 0000000..9044d8d Binary files /dev/null and b/validation/operations/conv/same_lower_3x3/conv_same_lower_3x3.onnx differ diff --git a/validation/operations/conv/without_kernel_shape_attr/conv_without_kernel_shape_attr.onnx b/validation/operations/conv/without_kernel_shape_attr/conv_without_kernel_shape_attr.onnx new file mode 100644 index 0000000..b784f99 Binary files /dev/null and b/validation/operations/conv/without_kernel_shape_attr/conv_without_kernel_shape_attr.onnx differ diff --git a/validation/operations/div/channel_broadcast_1024/div_channel_broadcast_1024.onnx b/validation/operations/div/channel_broadcast_1024/div_channel_broadcast_1024.onnx new file mode 100644 index 0000000..0664097 Binary files /dev/null and b/validation/operations/div/channel_broadcast_1024/div_channel_broadcast_1024.onnx differ diff --git a/validation/operations/div/leading_dimension_broadcast/div_leading_dimension_broadcast.onnx b/validation/operations/div/leading_dimension_broadcast/div_leading_dimension_broadcast.onnx new file mode 100644 index 0000000..68ce49b Binary files /dev/null and b/validation/operations/div/leading_dimension_broadcast/div_leading_dimension_broadcast.onnx differ diff --git a/validation/operations/div/runtime_scalar_lhs/div_runtime_scalar_lhs.onnx b/validation/operations/div/runtime_scalar_lhs/div_runtime_scalar_lhs.onnx new file mode 100644 index 0000000..3401328 Binary files /dev/null and b/validation/operations/div/runtime_scalar_lhs/div_runtime_scalar_lhs.onnx differ diff --git a/validation/operations/div/runtime_scalar_rhs/div_runtime_scalar_rhs.onnx b/validation/operations/div/runtime_scalar_rhs/div_runtime_scalar_rhs.onnx new file mode 100644 index 0000000..5885133 Binary files /dev/null and b/validation/operations/div/runtime_scalar_rhs/div_runtime_scalar_rhs.onnx differ diff --git a/validation/operations/gather/3d_input_axis1/gather_3d_input_axis1.onnx b/validation/operations/gather/3d_input_axis1/gather_3d_input_axis1.onnx new file mode 100644 index 0000000..d46b548 Binary files /dev/null and b/validation/operations/gather/3d_input_axis1/gather_3d_input_axis1.onnx differ diff --git a/validation/operations/gather/negative_axis/gather_negative_axis.onnx b/validation/operations/gather/negative_axis/gather_negative_axis.onnx new file mode 100644 index 0000000..b9a3cc8 Binary files /dev/null and b/validation/operations/gather/negative_axis/gather_negative_axis.onnx differ diff --git a/validation/operations/gather/negative_indices/gather_negative_indices.onnx b/validation/operations/gather/negative_indices/gather_negative_indices.onnx new file mode 100644 index 0000000..ea7403c Binary files /dev/null and b/validation/operations/gather/negative_indices/gather_negative_indices.onnx differ diff --git a/validation/operations/gemm/bias_rank2_broadcast/gemm_bias_rank2_broadcast.onnx b/validation/operations/gemm/bias_rank2_broadcast/gemm_bias_rank2_broadcast.onnx new file mode 100644 index 0000000..596be43 Binary files /dev/null and b/validation/operations/gemm/bias_rank2_broadcast/gemm_bias_rank2_broadcast.onnx differ diff --git a/validation/operations/gemm/huge_1024/gemm_huge_1024.onnx b/validation/operations/gemm/huge_1024/gemm_huge_1024.onnx new file mode 100644 index 0000000..6e6031d Binary files /dev/null and b/validation/operations/gemm/huge_1024/gemm_huge_1024.onnx differ diff --git a/validation/operations/gemm/large_k_small_n/gemm_large_k_small_n.onnx b/validation/operations/gemm/large_k_small_n/gemm_large_k_small_n.onnx new file mode 100644 index 0000000..da27754 Binary files /dev/null and b/validation/operations/gemm/large_k_small_n/gemm_large_k_small_n.onnx differ diff --git a/validation/operations/gemm/scalar_bias/gemm_scalar_bias.onnx b/validation/operations/gemm/scalar_bias/gemm_scalar_bias.onnx new file mode 100644 index 0000000..8114542 Binary files /dev/null and b/validation/operations/gemm/scalar_bias/gemm_scalar_bias.onnx differ diff --git a/validation/operations/gemm/small_k_large_n/gemm_small_k_large_n.onnx b/validation/operations/gemm/small_k_large_n/gemm_small_k_large_n.onnx new file mode 100644 index 0000000..d101ff5 Binary files /dev/null and b/validation/operations/gemm/small_k_large_n/gemm_small_k_large_n.onnx differ diff --git a/validation/operations/gemm/transA/gemm_transA.onnx b/validation/operations/gemm/transA/gemm_transA.onnx new file mode 100644 index 0000000..fc36591 Binary files /dev/null and b/validation/operations/gemm/transA/gemm_transA.onnx differ diff --git a/validation/operations/gemm/transA_transB/gemm_transA_transB.onnx b/validation/operations/gemm/transA_transB/gemm_transA_transB.onnx new file mode 100644 index 0000000..9ee8835 Binary files /dev/null and b/validation/operations/gemm/transA_transB/gemm_transA_transB.onnx differ diff --git a/validation/operations/gen_tests.py b/validation/operations/gen_tests.py index 9714652..49f491b 100644 --- a/validation/operations/gen_tests.py +++ b/validation/operations/gen_tests.py @@ -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.") diff --git a/validation/operations/matmul/batched_4d_broadcast/matmul_batched_4d_broadcast.onnx b/validation/operations/matmul/batched_4d_broadcast/matmul_batched_4d_broadcast.onnx new file mode 100644 index 0000000..25382b8 Binary files /dev/null and b/validation/operations/matmul/batched_4d_broadcast/matmul_batched_4d_broadcast.onnx differ diff --git a/validation/operations/matmul/huge_1024/matmul_huge_1024.onnx b/validation/operations/matmul/huge_1024/matmul_huge_1024.onnx new file mode 100644 index 0000000..bfc613b Binary files /dev/null and b/validation/operations/matmul/huge_1024/matmul_huge_1024.onnx differ diff --git a/validation/operations/matmul/matrix_vector/matmul_matrix_vector.onnx b/validation/operations/matmul/matrix_vector/matmul_matrix_vector.onnx new file mode 100644 index 0000000..d6a08a9 Binary files /dev/null and b/validation/operations/matmul/matrix_vector/matmul_matrix_vector.onnx differ diff --git a/validation/operations/matmul/vector_matrix/matmul_vector_matrix.onnx b/validation/operations/matmul/vector_matrix/matmul_vector_matrix.onnx new file mode 100644 index 0000000..2b4b88e Binary files /dev/null and b/validation/operations/matmul/vector_matrix/matmul_vector_matrix.onnx differ diff --git a/validation/operations/matmul/vector_vector_dot/matmul_vector_vector_dot.onnx b/validation/operations/matmul/vector_vector_dot/matmul_vector_vector_dot.onnx new file mode 100644 index 0000000..cf96880 Binary files /dev/null and b/validation/operations/matmul/vector_vector_dot/matmul_vector_vector_dot.onnx differ diff --git a/validation/operations/mul/channel_broadcast_1024/mul_channel_broadcast_1024.onnx b/validation/operations/mul/channel_broadcast_1024/mul_channel_broadcast_1024.onnx new file mode 100644 index 0000000..e971205 Binary files /dev/null and b/validation/operations/mul/channel_broadcast_1024/mul_channel_broadcast_1024.onnx differ diff --git a/validation/operations/mul/leading_dimension_broadcast/mul_leading_dimension_broadcast.onnx b/validation/operations/mul/leading_dimension_broadcast/mul_leading_dimension_broadcast.onnx new file mode 100644 index 0000000..55addb9 Binary files /dev/null and b/validation/operations/mul/leading_dimension_broadcast/mul_leading_dimension_broadcast.onnx differ diff --git a/validation/operations/mul/scalar_runtime/mul_scalar_runtime.onnx b/validation/operations/mul/scalar_runtime/mul_scalar_runtime.onnx new file mode 100644 index 0000000..55e63e0 Binary files /dev/null and b/validation/operations/mul/scalar_runtime/mul_scalar_runtime.onnx differ diff --git a/validation/operations/pool/avg_ceil_mode/avgpool_ceil_mode.onnx b/validation/operations/pool/avg_ceil_mode/avgpool_ceil_mode.onnx new file mode 100644 index 0000000..723e8ec Binary files /dev/null and b/validation/operations/pool/avg_ceil_mode/avgpool_ceil_mode.onnx differ diff --git a/validation/operations/pool/avg_large_channels/avgpool_large_channels.onnx b/validation/operations/pool/avg_large_channels/avgpool_large_channels.onnx new file mode 100644 index 0000000..254c3c6 Binary files /dev/null and b/validation/operations/pool/avg_large_channels/avgpool_large_channels.onnx differ diff --git a/validation/operations/pool/avg_non_uniform_stride/avgpool_non_uniform_stride.onnx b/validation/operations/pool/avg_non_uniform_stride/avgpool_non_uniform_stride.onnx new file mode 100644 index 0000000..e3c0116 Binary files /dev/null and b/validation/operations/pool/avg_non_uniform_stride/avgpool_non_uniform_stride.onnx differ diff --git a/validation/operations/pool/avg_real_asymmetric_padding/avgpool_real_asymmetric_padding.onnx b/validation/operations/pool/avg_real_asymmetric_padding/avgpool_real_asymmetric_padding.onnx new file mode 100644 index 0000000..5933547 Binary files /dev/null and b/validation/operations/pool/avg_real_asymmetric_padding/avgpool_real_asymmetric_padding.onnx differ diff --git a/validation/operations/pool/max_ceil_mode/maxpool_ceil_mode.onnx b/validation/operations/pool/max_ceil_mode/maxpool_ceil_mode.onnx new file mode 100644 index 0000000..fc4b590 Binary files /dev/null and b/validation/operations/pool/max_ceil_mode/maxpool_ceil_mode.onnx differ diff --git a/validation/operations/pool/max_global_style_kernel_equals_input/maxpool_global_style_kernel_equals_input.onnx b/validation/operations/pool/max_global_style_kernel_equals_input/maxpool_global_style_kernel_equals_input.onnx new file mode 100644 index 0000000..1d83961 Binary files /dev/null and b/validation/operations/pool/max_global_style_kernel_equals_input/maxpool_global_style_kernel_equals_input.onnx differ diff --git a/validation/operations/pool/max_non_square_kernel/maxpool_non_square_kernel.onnx b/validation/operations/pool/max_non_square_kernel/maxpool_non_square_kernel.onnx new file mode 100644 index 0000000..4feb046 Binary files /dev/null and b/validation/operations/pool/max_non_square_kernel/maxpool_non_square_kernel.onnx differ diff --git a/validation/operations/pool/max_real_asymmetric_padding/maxpool_real_asymmetric_padding.onnx b/validation/operations/pool/max_real_asymmetric_padding/maxpool_real_asymmetric_padding.onnx new file mode 100644 index 0000000..10255ae Binary files /dev/null and b/validation/operations/pool/max_real_asymmetric_padding/maxpool_real_asymmetric_padding.onnx differ diff --git a/validation/operations/reduce_mean/4d_spatial_keepdims_0/reduce_mean_4d_spatial_keepdims_0.onnx b/validation/operations/reduce_mean/4d_spatial_keepdims_0/reduce_mean_4d_spatial_keepdims_0.onnx new file mode 100644 index 0000000..c642f07 Binary files /dev/null and b/validation/operations/reduce_mean/4d_spatial_keepdims_0/reduce_mean_4d_spatial_keepdims_0.onnx differ diff --git a/validation/operations/reduce_mean/all_axes_keepdims_0/reduce_mean_all_axes_keepdims_0.onnx b/validation/operations/reduce_mean/all_axes_keepdims_0/reduce_mean_all_axes_keepdims_0.onnx new file mode 100644 index 0000000..2bfada4 Binary files /dev/null and b/validation/operations/reduce_mean/all_axes_keepdims_0/reduce_mean_all_axes_keepdims_0.onnx differ diff --git a/validation/operations/reduce_mean/all_axes_keepdims_1/reduce_mean_all_axes_keepdims_1.onnx b/validation/operations/reduce_mean/all_axes_keepdims_1/reduce_mean_all_axes_keepdims_1.onnx new file mode 100644 index 0000000..9e5a3c7 Binary files /dev/null and b/validation/operations/reduce_mean/all_axes_keepdims_1/reduce_mean_all_axes_keepdims_1.onnx differ diff --git a/validation/operations/reduce_mean/channel_axis_nchw/reduce_mean_channel_axis_nchw.onnx b/validation/operations/reduce_mean/channel_axis_nchw/reduce_mean_channel_axis_nchw.onnx new file mode 100644 index 0000000..7cb7a98 Binary files /dev/null and b/validation/operations/reduce_mean/channel_axis_nchw/reduce_mean_channel_axis_nchw.onnx differ diff --git a/validation/operations/reduce_mean/large_dimension_1024/reduce_mean_large_dimension_1024.onnx b/validation/operations/reduce_mean/large_dimension_1024/reduce_mean_large_dimension_1024.onnx new file mode 100644 index 0000000..77b3b09 Binary files /dev/null and b/validation/operations/reduce_mean/large_dimension_1024/reduce_mean_large_dimension_1024.onnx differ diff --git a/validation/operations/reduce_mean/negative_axis/reduce_mean_negative_axis.onnx b/validation/operations/reduce_mean/negative_axis/reduce_mean_negative_axis.onnx new file mode 100644 index 0000000..839e320 Binary files /dev/null and b/validation/operations/reduce_mean/negative_axis/reduce_mean_negative_axis.onnx differ diff --git a/validation/operations/reshape/4d_to_2d_flatten/reshape_4d_to_2d_flatten.onnx b/validation/operations/reshape/4d_to_2d_flatten/reshape_4d_to_2d_flatten.onnx new file mode 100644 index 0000000..41b9c7a Binary files /dev/null and b/validation/operations/reshape/4d_to_2d_flatten/reshape_4d_to_2d_flatten.onnx differ diff --git a/validation/operations/reshape/infer_dim_minus_one/reshape_infer_dim_minus_one.onnx b/validation/operations/reshape/infer_dim_minus_one/reshape_infer_dim_minus_one.onnx new file mode 100644 index 0000000..3afcedb Binary files /dev/null and b/validation/operations/reshape/infer_dim_minus_one/reshape_infer_dim_minus_one.onnx differ diff --git a/validation/operations/reshape/zero_copies_input_dim/reshape_zero_copies_input_dim.onnx b/validation/operations/reshape/zero_copies_input_dim/reshape_zero_copies_input_dim.onnx new file mode 100644 index 0000000..45e09dd Binary files /dev/null and b/validation/operations/reshape/zero_copies_input_dim/reshape_zero_copies_input_dim.onnx differ diff --git a/validation/operations/resize/height_only/resize_height_only.onnx b/validation/operations/resize/height_only/resize_height_only.onnx new file mode 100644 index 0000000..53bad98 Binary files /dev/null and b/validation/operations/resize/height_only/resize_height_only.onnx differ diff --git a/validation/operations/resize/nearest_downsample/resize_nearest_downsample.onnx b/validation/operations/resize/nearest_downsample/resize_nearest_downsample.onnx new file mode 100644 index 0000000..6c2a952 Binary files /dev/null and b/validation/operations/resize/nearest_downsample/resize_nearest_downsample.onnx differ diff --git a/validation/operations/resize/width_only/resize_width_only.onnx b/validation/operations/resize/width_only/resize_width_only.onnx new file mode 100644 index 0000000..cf6844d Binary files /dev/null and b/validation/operations/resize/width_only/resize_width_only.onnx differ diff --git a/validation/operations/softmax/large_dimension_1024/softmax_large_dimension_1024.onnx b/validation/operations/softmax/large_dimension_1024/softmax_large_dimension_1024.onnx new file mode 100644 index 0000000..1e0be18 Binary files /dev/null and b/validation/operations/softmax/large_dimension_1024/softmax_large_dimension_1024.onnx differ diff --git a/validation/operations/softmax/negative_axis/softmax_negative_axis.onnx b/validation/operations/softmax/negative_axis/softmax_negative_axis.onnx new file mode 100644 index 0000000..77a07d8 Binary files /dev/null and b/validation/operations/softmax/negative_axis/softmax_negative_axis.onnx differ diff --git a/validation/operations/split/negative_axis/split_negative_axis.onnx b/validation/operations/split/negative_axis/split_negative_axis.onnx new file mode 100644 index 0000000..5770ada Binary files /dev/null and b/validation/operations/split/negative_axis/split_negative_axis.onnx differ diff --git a/validation/operations/split/uneven_channel_axis_4d/split_uneven_channel_axis_4d.onnx b/validation/operations/split/uneven_channel_axis_4d/split_uneven_channel_axis_4d.onnx new file mode 100644 index 0000000..9a6ac8c Binary files /dev/null and b/validation/operations/split/uneven_channel_axis_4d/split_uneven_channel_axis_4d.onnx differ