From 96eb9810ba5c3523e4fd640981be2d68c74355b0 Mon Sep 17 00:00:00 2001 From: Ashwini Khade Date: Thu, 5 Aug 2021 09:21:44 -0700 Subject: [PATCH] Update onnx (#8458) * updates for picking pnnx commit * add tests filter to c# tests * plus test fixes * fix versioning for contrib ops * fix tests * test filter for optional ops * more versioning related updates * fix test * fix layernorm spec * more updates * update docs * add more test filters * more filters * update binary size threshold * update docs * plus more fixes * updates per review * update to release commit * add filters for optional type tests * plus updates --- cgmanifests/submodules/cgmanifest.json | 2 +- cmake/external/onnx | 2 +- .../InferenceTest.cs | 40 ++++++++++++-- docs/OperatorKernels.md | 4 +- js/web/docs/operators.md | 8 ++- .../core/graph/contrib_ops/contrib_defs.cc | 18 ++++--- .../graph/contrib_ops/nhwc_schema_defs.cc | 3 ++ .../graph/contrib_ops/onnx_function_util.cc | 27 ---------- .../graph/contrib_ops/onnx_function_util.h | 8 --- onnxruntime/core/graph/function.cc | 52 ++++++++++++------- onnxruntime/core/graph/graph.cc | 41 +++++++++------ onnxruntime/test/ir/graph_test.cc | 14 ++++- onnxruntime/test/onnx/main.cc | 31 ++++++++++- .../test/providers/cpu/math/softmax_test.cc | 2 +- .../cpu/tensor/shape_inference_test_helper.h | 2 +- .../onnx_backend_test_series_filters.jsonc | 13 +++-- .../core/graph/training_op_defs.cc | 8 +-- .../docker/scripts/manylinux/requirements.txt | 2 +- .../linux/docker/scripts/requirements.txt | 2 +- ...rt_android_baseline_and_report_bin_size.sh | 2 +- 20 files changed, 180 insertions(+), 101 deletions(-) diff --git a/cgmanifests/submodules/cgmanifest.json b/cgmanifests/submodules/cgmanifest.json index fbb69be84d..85b437b99e 100644 --- a/cgmanifests/submodules/cgmanifest.json +++ b/cgmanifests/submodules/cgmanifest.json @@ -305,7 +305,7 @@ "component": { "type": "git", "git": { - "commitHash": "d75fb0502c9d8fef817d82c15223b4aaae8e8b6e", + "commitHash": "a57bc99daa6ddeef2ad535f8f78d1847f57216f0", "repositoryUrl": "https://github.com/onnx/onnx" }, "comments": "git submodule at cmake/external/onnx" diff --git a/cmake/external/onnx b/cmake/external/onnx index d75fb0502c..1f63dcb7fc 160000 --- a/cmake/external/onnx +++ b/cmake/external/onnx @@ -1 +1 @@ -Subproject commit d75fb0502c9d8fef817d82c15223b4aaae8e8b6e +Subproject commit 1f63dcb7fcc3a8bf5c3c8e326867ecd6f5c43f35 diff --git a/csharp/test/Microsoft.ML.OnnxRuntime.Tests/InferenceTest.cs b/csharp/test/Microsoft.ML.OnnxRuntime.Tests/InferenceTest.cs index 47e45ad3da..964be5cd03 100644 --- a/csharp/test/Microsoft.ML.OnnxRuntime.Tests/InferenceTest.cs +++ b/csharp/test/Microsoft.ML.OnnxRuntime.Tests/InferenceTest.cs @@ -837,9 +837,7 @@ namespace Microsoft.ML.OnnxRuntime.Tests { "test_max_uint16", "node test error"}, { "test_resize_downsample_scales_linear_align_corners", "node test error"}, { "test_strnormalizer_nostopwords_nochangecase", "node test error"}, - { "test_cast_STRING_to_FLOAT", "node test error"}, { "test_cumsum_2d_negative_axis", "node test error"}, - { "test_cast_FLOAT16_to_DOUBLE", "node test error"}, { "test_adagrad_multiple", "node test error"}, { "test_einsum_inner_prod", "node test error"}, { "test_clip_default_int8_min", "node test error"}, @@ -852,7 +850,6 @@ namespace Microsoft.ML.OnnxRuntime.Tests { "test_clip_default_int8_max", "node test error"}, { "test_einsum_sum", "node test error"}, { "test_min_int16", "node test error"}, - { "test_cast_FLOAT_to_DOUBLE", "node test error"}, { "test_adagrad", "node test error"}, { "test_min_float64", "node test error"}, { "test_max_int16", "node test error"}, @@ -860,7 +857,6 @@ namespace Microsoft.ML.OnnxRuntime.Tests { "test_sequence_insert_at_front", "node test error"}, { "test_cumsum_1d_exclusive", "node test error"}, { "test_training_dropout_default", "node test error"}, - { "test_cast_BFLOAT16_to_FLOAT", "node test error"}, { "test_training_dropout", "node test error"}, { "test_adam", "node test error"}, { "test_training_dropout_mask", "node test error"}, @@ -869,7 +865,24 @@ namespace Microsoft.ML.OnnxRuntime.Tests { "test_cumsum_1d", "node test error"}, { "test_conv_with_autopad_same", "node test error"}, { "test_cumsum_1d_reverse_exclusive", "node test error"}, + { "test_cast_STRING_to_FLOAT", "node test error"}, + { "test_cast_FLOAT16_to_DOUBLE", "node test error"}, + { "test_cast_FLOAT_to_DOUBLE", "node test error"}, + { "test_cast_BFLOAT16_to_FLOAT", "node test error"}, { "test_cast_FLOAT_to_BFLOAT16", "node test error"}, + { "test_cast_FLOAT_to_STRING", "node test error"}, + { "test_castlike_STRING_to_FLOAT", "node test error"}, + { "test_castlike_STRING_to_FLOAT_expanded", "node test error"}, + { "test_castlike_FLOAT16_to_DOUBLE", "node test error"}, + { "test_castlike_FLOAT16_to_DOUBLE_expanded", "node test error"}, + { "test_castlike_FLOAT_to_DOUBLE", "node test error"}, + { "test_castlike_FLOAT_to_DOUBLE_expanded", "node test error"}, + { "test_castlike_BFLOAT16_to_FLOAT", "node test error"}, + { "test_castlike_BFLOAT16_to_FLOAT_expanded", "node test error"}, + { "test_castlike_FLOAT_to_BFLOAT16", "node test error"}, + { "test_castlike_FLOAT_to_BFLOAT16_expanded", "node test error"}, + { "test_castlike_FLOAT_to_STRING", "node test error"}, + { "test_castlike_FLOAT_to_STRING_expanded", "node test error"}, { "test_bitshift_right_uint16", "node test error"}, { "test_bitshift_left_uint16", "node test error"}, { "test_pow_types_float32_uint64", "node test error"}, @@ -891,7 +904,6 @@ namespace Microsoft.ML.OnnxRuntime.Tests { "test_convtranspose_autopad_same", "node test error"}, { "test_training_dropout_default_mask", "node test error"}, { "test_min_int8", "node test error"}, - { "test_cast_FLOAT_to_STRING", "node test error"}, { "test_identity_sequence", "data type not supported"}, { "test_gru_batchwise", "batchwise operations not supported"}, { "test_lstm_batchwise", "batchwise operations not supported"}, @@ -907,6 +919,24 @@ namespace Microsoft.ML.OnnxRuntime.Tests { "test_bernoulli", "random generator"}, { "test_bernoulli_seed", "random generator"}, { "test_bernoulli_double", "random generator"}, + { "test_bernoulli_expanded", "random generator"}, + { "test_bernoulli_seed_expanded", "random generator"}, + { "test_bernoulli_double_expanded", "random generator"}, + { "test_shape", "opset15 version not implemented yet"}, + { "test_shape_clip_end", "opset15 version not implemented yet"}, + { "test_shape_clip_start", "opset15 version not implemented yet"}, + { "test_shape_end_1", "opset15 version not implemented yet"}, + { "test_shape_end_negative", "opset15 version not implemented yet"}, + { "test_shape_example", "opset15 version not implemented yet"}, + { "test_shape_start_1", "opset15 version not implemented yet"}, + { "test_shape_start_negative_1", "opset15 version not implemented yet"}, + { "test_shape_start_1_end_2", "opset15 version not implemented yet"}, + { "test_shape_start_1_end_negative_1", "opset15 version not implemented yet"}, + { "test_shape_end_negative_1", "opset15 version not implemented yet"}, + { "test_optional_get_element", "not implemented yet"}, + { "test_optional_get_element_sequence", "not implemented yet"}, + { "test_optional_has_element", "not implemented yet"}, + { "test_optional_has_element_empty", "not implemented yet"}, }; // The following models fails on nocontribops win CI diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md index e5d4ff1e1e..20e0fcada0 100644 --- a/docs/OperatorKernels.md +++ b/docs/OperatorKernels.md @@ -38,7 +38,7 @@ Do not modify directly.* |AveragePool|*in* X:**T**
*out* Y:**T**|11+|**T** = tensor(float)| |||10|**T** = tensor(float)| |||[7, 9]|**T** = tensor(float)| -|BatchNormalization|*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* input_mean:**U**
*in* input_var:**U**
*out* Y:**T**
*out* running_mean:**U**
*out* running_var:**U**

or

*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* mean:**T**
*in* var:**T**
*out* Y:**T**
*out* mean:**T**
*out* var:**T**
*out* saved_mean:**T**
*out* saved_var:**T**|14+|**T** = tensor(double), tensor(float)| +|BatchNormalization|*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* input_mean:**U**
*in* input_var:**U**
*out* Y:**T**
*out* running_mean:**U**
*out* running_var:**U**

or

*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* mean:**T**
*in* var:**T**
*out* Y:**T**
*out* mean:**T**
*out* var:**T**
*out* saved_mean:**T**
*out* saved_var:**T**

or

*in* X:**T**
*in* scale:**T1**
*in* B:**T1**
*in* input_mean:**T2**
*in* input_var:**T2**
*out* Y:**T**
*out* running_mean:**T2**
*out* running_var:**T2**|14+|**T** = tensor(double), tensor(float)| |||[9, 13]|**T** = tensor(double), tensor(float)| |||[7, 8]|**T** = tensor(double), tensor(float)| |BitShift|*in* X:**T**
*in* Y:**T**
*out* Z:**T**|11+|**T** = tensor(uint32), tensor(uint64), tensor(uint8)| @@ -445,7 +445,7 @@ Do not modify directly.* |AveragePool|*in* X:**T**
*out* Y:**T**|11+|**T** = tensor(double), tensor(float), tensor(float16)| |||10|**I** = tensor(int64)
**T** = tensor(double), tensor(float), tensor(float16)| |||[7, 9]|**I** = tensor(int64)
**T** = tensor(double), tensor(float), tensor(float16)| -|BatchNormalization|*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* input_mean:**U**
*in* input_var:**U**
*out* Y:**T**
*out* running_mean:**U**
*out* running_var:**U**

or

*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* mean:**T**
*in* var:**T**
*out* Y:**T**
*out* mean:**T**
*out* var:**T**
*out* saved_mean:**T**
*out* saved_var:**T**|14+|**T** = tensor(double), tensor(float), tensor(float16)| +|BatchNormalization|*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* input_mean:**U**
*in* input_var:**U**
*out* Y:**T**
*out* running_mean:**U**
*out* running_var:**U**

or

*in* X:**T**
*in* scale:**T**
*in* B:**T**
*in* mean:**T**
*in* var:**T**
*out* Y:**T**
*out* mean:**T**
*out* var:**T**
*out* saved_mean:**T**
*out* saved_var:**T**

or

*in* X:**T**
*in* scale:**T1**
*in* B:**T1**
*in* input_mean:**T2**
*in* input_var:**T2**
*out* Y:**T**
*out* running_mean:**T2**
*out* running_var:**T2**|14+|**T** = tensor(double), tensor(float), tensor(float16)| |||[9, 13]|**T** = tensor(double), tensor(float), tensor(float16)| |||[7, 8]|**T** = tensor(double), tensor(float), tensor(float16)| |Cast|*in* input:**T1**
*out* output:**T2**|13+|**T1** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**T2** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)| diff --git a/js/web/docs/operators.md b/js/web/docs/operators.md index e7b251fa77..1187a6c1b1 100644 --- a/js/web/docs/operators.md +++ b/js/web/docs/operators.md @@ -20,10 +20,11 @@ See [Compatibility](../README.md#Compatibility) for a list of the supported plat | [Atan](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Atan) | [7+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Atan-7) | | [Atanh](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Atanh) | | | [AveragePool](https://github.com/onnx/onnx/blob/master/docs/Operators.md#AveragePool) | [7-9](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#AveragePool-7), [10](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#AveragePool-10) | -| [BatchNormalization](https://github.com/onnx/onnx/blob/master/docs/Operators.md#BatchNormalization) | [7-8](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-7), [9-13](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-9), [14+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-14) | +| [BatchNormalization](https://github.com/onnx/onnx/blob/master/docs/Operators.md#BatchNormalization) | [7-8](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-7), [9-13](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-9), [14](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-14), [15+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#BatchNormalization-15) | | [Bernoulli](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Bernoulli) | | | [BitShift](https://github.com/onnx/onnx/blob/master/docs/Operators.md#BitShift) | | | [Cast](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Cast) | | +| [CastLike](https://github.com/onnx/onnx/blob/master/docs/Operators.md#CastLike) | | | [Ceil](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Ceil) | [6-12](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Ceil-6), [13+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Ceil-13) | | [Celu](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Celu) | | | [Clip](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Clip) | [6-10](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Clip-6) | @@ -99,6 +100,9 @@ See [Compatibility](../README.md#Compatibility) for a list of the supported plat | [NonZero](https://github.com/onnx/onnx/blob/master/docs/Operators.md#NonZero) | | | [Not](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Not) | [1+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Not-1) | | [OneHot](https://github.com/onnx/onnx/blob/master/docs/Operators.md#OneHot) | | +| [Optional](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Optional) | | +| [OptionalGetElement](https://github.com/onnx/onnx/blob/master/docs/Operators.md#OptionalGetElement) | | +| [OptionalHasElement](https://github.com/onnx/onnx/blob/master/docs/Operators.md#OptionalHasElement) | | | [Or](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Or) | [7+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Or-7) | | [PRelu](https://github.com/onnx/onnx/blob/master/docs/Operators.md#PRelu) | [7-8](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#PRelu-7), [9+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#PRelu-9) | | [Pad](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Pad) | [2-10](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Pad-2) | @@ -140,7 +144,7 @@ See [Compatibility](../README.md#Compatibility) for a list of the supported plat | [SequenceErase](https://github.com/onnx/onnx/blob/master/docs/Operators.md#SequenceErase) | | | [SequenceInsert](https://github.com/onnx/onnx/blob/master/docs/Operators.md#SequenceInsert) | | | [SequenceLength](https://github.com/onnx/onnx/blob/master/docs/Operators.md#SequenceLength) | | -| [Shape](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Shape) | [1-12](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Shape-1), [13+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Shape-13) | +| [Shape](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Shape) | [1-12](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Shape-1), [13-14](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Shape-13), [15+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Shape-15) | | [Shrink](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Shrink) | | | [Sigmoid](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Sigmoid) | [6-12](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Sigmoid-6), [13+](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Sigmoid-13) | | [Sign](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Sign) | | diff --git a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc index 3b00a69627..4e5eb5ea20 100644 --- a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc +++ b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc @@ -790,7 +790,7 @@ GELU (Gaussian Error Linear Unit) approximation: Y=0.5*X*(1+tanh(0.797885*X+0.03 onnx_opset_13.set_domain(""); onnx_opset_13.set_version(13); - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); }); ONNX_CONTRIB_OPERATOR_SCHEMA(SkipLayerNormalization) @@ -2507,10 +2507,14 @@ Example 4: {{"Deviation"}, "Sub", {"XU", "Mean2D"}}, {{"Normalized"}, "Div", {"Deviation", "StdDev"}}, {{"NormalizedT"}, "Cast", {"Normalized"}, {{"to", T}}}, - {{"Scaled"}, "Mul", {"NormalizedT", "Scale"}}, - {{"Biased"}, "Add", {"Scaled", "B"}}, - {{"Y"}, "Reshape", {"Biased", "XShape"}}, - {{"InvStdDev2D"}, "Reciprocal", {"StdDev"}}}; + {{"Scaled"}, "Mul", {"NormalizedT", "Scale"}}}; + if (ctx.hasInput(2)) { + body.push_back({{"Biased"}, "Add", {"Scaled", "B"}}); + } else { + body.push_back({{"Biased"}, "Identity", {"Scaled"}}); + } + body.push_back({{"Y"}, "Reshape", {"Biased", "XShape"}}); + body.push_back({{"InvStdDev2D"}, "Reciprocal", {"StdDev"}}); if (ctx.hasOutput(1)) body.push_back({{"Mean"}, "Reshape", {"Mean2D", "ReducedShape"}}); if (ctx.hasOutput(2)) @@ -2520,7 +2524,7 @@ Example 4: onnx_opset_13.set_domain(""); onnx_opset_13.set_version(13); - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); }); ONNX_CONTRIB_OPERATOR_SCHEMA(SimplifiedLayerNormalization) @@ -2613,7 +2617,7 @@ inputs by their magnitude, rather than gates inputs by their sign as in ReLUs.)D onnx_opset_13.set_domain(""); onnx_opset_13.set_version(13); - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); }); static const char* BiasGelu_ver1_doc = diff --git a/onnxruntime/core/graph/contrib_ops/nhwc_schema_defs.cc b/onnxruntime/core/graph/contrib_ops/nhwc_schema_defs.cc index 9ac42e7835..1398ace332 100644 --- a/onnxruntime/core/graph/contrib_ops/nhwc_schema_defs.cc +++ b/onnxruntime/core/graph/contrib_ops/nhwc_schema_defs.cc @@ -94,6 +94,9 @@ class NhwcInferenceContext : public InferenceContext { return nullptr; } + const TensorShapeProto* getSymbolicInput(size_t) const override { + return nullptr; + } private: InferenceContext& ctx_; diff --git a/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc b/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc index df569b159a..929fde218a 100644 --- a/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc +++ b/onnxruntime/core/graph/contrib_ops/onnx_function_util.cc @@ -79,31 +79,4 @@ TensorProto ToTensor(double value, TensorProto_DataType elem_type) { return t; } - -void BuildNodes(FunctionProto& functionProto, const std::vector& node_defs) { - for (size_t i = 0; i < node_defs.size(); i++) { - const FunctionBodyHelper::NodeDef& node = node_defs[i]; - auto* np = functionProto.add_node(); - - np->set_op_type(node.op_type); - for (const auto& inp : node.inputs) { - np->add_input(inp); - } - for (const auto& o : node.outputs) { - np->add_output(o); - } - for (const auto& attr : node.attributes) { - *(np->add_attribute()) = attr.proto; - } - } -} - -bool BuildFunctionProto(FunctionProto& functionProto, const OpSchema& schema, - const std::vector& node_defs, - const std::vector& relied_opsets) { - BuildNodes(functionProto, node_defs); - schema.BuildFunction(functionProto, relied_opsets); - return true; -} - } // namespace ONNX_NAMESPACE \ No newline at end of file diff --git a/onnxruntime/core/graph/contrib_ops/onnx_function_util.h b/onnxruntime/core/graph/contrib_ops/onnx_function_util.h index b57441bc6a..d5b98bdb79 100644 --- a/onnxruntime/core/graph/contrib_ops/onnx_function_util.h +++ b/onnxruntime/core/graph/contrib_ops/onnx_function_util.h @@ -20,12 +20,4 @@ inline static FunctionBodyHelper::NodeDef Const(const std::string& name, double return FunctionBodyHelper::NodeDef{ {name}, "Constant", {}, {{"value", ToTensor(value, elem_type)}}}; } - -// Utility function to construct a FunctionProto from an opschema (for the signature information), -// a sequence of NodeDefs (for the function body), and the relied opsets. -bool BuildFunctionProto(FunctionProto& functionProto, - const OpSchema& schema, - const std::vector& node_defs, - const std::vector& relied_opsets = {}); - } // namespace ONNX_NAMESPACE \ No newline at end of file diff --git a/onnxruntime/core/graph/function.cc b/onnxruntime/core/graph/function.cc index a726d01f5f..04900501e1 100644 --- a/onnxruntime/core/graph/function.cc +++ b/onnxruntime/core/graph/function.cc @@ -8,6 +8,17 @@ #include "onnx/shape_inference/implementation.h" namespace onnxruntime { + +// Utilify function to get the imported version of domain from opset imports +// Returns -1 if requested domain is not found in the opset_imports +static int GetVersionForDomain(const std::string& domain, const std::unordered_map& opset_imports) { + auto it = opset_imports.find(domain); + if (it == opset_imports.end()) { + return -1; + } + return it->second; +} + // Auto inferred and generate an opschema for stand-alone functions // TODO: revisit to see if we can eliminate typeconstraint step void IOTypeConstraintHelper(const ONNX_NAMESPACE::FunctionProto& onnx_func_proto_, @@ -19,9 +30,15 @@ void IOTypeConstraintHelper(const ONNX_NAMESPACE::FunctionProto& onnx_func_proto std::unordered_map> type_constraint_map; std::unordered_map attribute_type_map; auto schema_registry = ONNX_NAMESPACE::OpSchemaRegistry::Instance(); + std::unordered_map opset_imports; + for (auto& relied_opset : onnx_func_proto_.opset_import()) { + opset_imports[relied_opset.domain()] = static_cast(relied_opset.version()); + } for (auto& node : onnx_func_proto_.node()) { + int domain_version = GetVersionForDomain(node.domain(), opset_imports); + ORT_ENFORCE(domain_version != -1, "No opset registered for domain " + node.domain() + " in function opset imports."); const auto node_op_schema = - schema_registry->GetSchema(node.op_type(), static_cast(onnx_func_proto_.since_version()), node.domain()); + schema_registry->GetSchema(node.op_type(), domain_version, node.domain()); for (int i = 0; i < node.input_size(); ++i) { auto& in_name = node.input().Get(i); auto iter = input_name_idx_map.find(in_name); @@ -177,22 +194,14 @@ static std::unique_ptr CreateSchema(const Graph& graph return op_schema; } -// Creates domain to version map for onnx function by merging graph level opset imports with opset imports from -// funtion proto -static std::unordered_map CreateOpsetImportsForFunction(const ONNX_NAMESPACE::FunctionProto& func_proto, - const std::unordered_map& graph_opset_imports) { - // function inherits all graph level opset imports - std::unordered_map function_opset_imports{graph_opset_imports}; - // merge with opset imports in function proto +// Creates domain to version map for onnx function +static std::unordered_map GetFunctionOpsetImports(const ONNX_NAMESPACE::FunctionProto& func_proto, const std::unordered_map& graph_imports) { + std::unordered_map function_opset_imports{graph_imports}; for (const auto& opset_import : func_proto.opset_import()) { - auto opset_version = static_cast(opset_import.version()); - auto result = function_opset_imports.insert({opset_import.domain(), opset_version}); - ORT_ENFORCE((result.first->second == opset_version), - "ONNX model does not support multiple opset versions for a domain. Model imports opset version ", - result.first->second, " for domain ", result.first->first, " and function is trying to import opset version ", - opset_version, " for the same domain"); + // If graph imports does not contain opset_import then insert it otherwise the one in graph imports overrides. + // If the opset imports are not compatible then this will be caught during function body inline. + function_opset_imports.insert({opset_import.domain(), static_cast(opset_import.version())}); } - return function_opset_imports; } @@ -273,7 +282,7 @@ FunctionImpl::FunctionImpl(const onnxruntime::Graph& graph, : parent_graph_(&graph), body_(onnx_func_proto.name(), false, onnxruntime::ModelMetaData(), graph.ModelPath().ToPathString(), IOnnxRuntimeOpSchemaRegistryList(), - CreateOpsetImportsForFunction(onnx_func_proto, graph.DomainToVersionMap()), + onnx_func_proto.opset_import_size() != 0 ? GetFunctionOpsetImports(onnx_func_proto, graph.DomainToVersionMap()) : graph.DomainToVersionMap(), {}, logger), onnx_func_proto_(onnx_func_proto) { // Make a copy of the FunctionProto. @@ -282,11 +291,17 @@ FunctionImpl::FunctionImpl(const onnxruntime::Graph& graph, // as we might make some modifications to the FunctionProto along the way const auto* node_in_parent_graph = parent_graph_->GetNode(node_index); + // For schema defined functions get the version from the node in parent graph. + // For the functions which do not have schema defined (model local functions) + // get the since version from the version in opset imports using the domain. + auto since_version = node_in_parent_graph->SinceVersion() == -1 + ? GetVersionForDomain(node_in_parent_graph->Domain(), body_.MainGraph().DomainToVersionMap()) + : node_in_parent_graph->SinceVersion(); op_schema_ = std::make_unique(); op_schema_->SetName(onnx_func_proto_.name()); op_schema_->SetDomain(node_in_parent_graph->Domain()); op_schema_->SetDoc(onnx_func_proto_.doc_string()); - op_schema_->SinceVersion(static_cast(onnx_func_proto_.since_version())); + op_schema_->SinceVersion(static_cast(since_version)); std::unordered_map input_name_idx_map; std::unordered_map output_name_idx_map; for (int i = 0; i < onnx_func_proto_.input_size(); ++i) { @@ -328,7 +343,8 @@ FunctionImpl::FunctionImpl(const onnxruntime::Graph& graph, op_schema_->TypeAndShapeInferenceFunction( [this](ONNX_NAMESPACE::InferenceContext& ctx) { auto schema_registry = ONNX_NAMESPACE::OpSchemaRegistry::Instance(); - ONNX_NAMESPACE::shape_inference::InferShapeForFunctionNode(&onnx_func_proto_, body_.MainGraph().DomainToVersionMap(), schema_registry, ctx); + ONNX_NAMESPACE::ShapeInferenceOptions options {true, 1, false}; + ONNX_NAMESPACE::shape_inference::InferShapeForFunctionNode(&onnx_func_proto_, body_.MainGraph().DomainToVersionMap(), schema_registry, ctx, options); }); } else { op_schema_->TypeAndShapeInferenceFunction(cached_op_schema->GetTypeAndShapeInferenceFunction()); diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index 7c0981f611..59bca28e45 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -1902,6 +1902,11 @@ class InferenceContextImpl : public ONNX_NAMESPACE::InferenceContext { return initializer; } + // ORT does not implement partial data propagation yet so just return nullptr. + const TensorShapeProto* getSymbolicInput(size_t) const override { + return nullptr; + } + GraphInferencer* getGraphAttributeInferencer(const std::string& attribute_name) override { GraphInferencer* graph_inferencer = nullptr; @@ -2352,8 +2357,12 @@ Status Graph::VerifyNodeAndOpMatch(const ResolveOptions& options) { auto maxInclusiveVersion = DomainToVersionMap().find(domain)->second; node.op_ = schema_registry_->GetSchema(node.OpType(), maxInclusiveVersion, node.Domain()); - if (node.op_ && node.op_->Deprecated()) { - node.op_ = nullptr; + if (node.op_) { + node.since_version_ = node.op_->since_version(); + + if (node.op_->Deprecated()) { + node.op_ = nullptr; + } } InitFunctionBodyForNode(node); @@ -2362,7 +2371,11 @@ Status Graph::VerifyNodeAndOpMatch(const ResolveOptions& options) { return Status(ONNXRUNTIME, FAIL, "Fatal error: " + node.OpType() + " is not a registered function/op"); } - node.since_version_ = node.op_->since_version(); + // For ops without schema (like model local functions set the since version after constructing the schema. + // schema construction will happen during function body initialization. + if (node.since_version_ == -1) { + node.since_version_ = node.op_->since_version(); + } } ORT_RETURN_IF_ERROR(node.UpdateInputArgCount()); @@ -2429,19 +2442,17 @@ void Graph::InitFunctionBodyForNode(Node& node) { onnx_function_proto = *(node.op_->GetFunction()); } - // Check function's opset requirements are compatible with model's opset. - auto& graphImports = DomainToVersionMap(); - for (const auto& fn_import : onnx_function_proto.opset_import()) { - auto it = graphImports.find(fn_import.domain()); - if ((it != graphImports.end()) && (it->second != fn_import.version())) - return; // Incompatible. Do not use this function expansion. + ORT_TRY { + auto func_ptr = std::make_unique(*this, node.Index(), onnx_function_proto, + logger_); + function_container_.emplace_back(std::move(func_ptr)); + node.SetFunctionBody(*function_container_.back()); + } + ORT_CATCH(const std::exception& ) { + // Return without using this function op's expansion. No need to fail just yet. + // If ORT has a specialized kernel for this op then execution will proceed + return; } - - auto func_ptr = std::make_unique(*this, node.Index(), onnx_function_proto, - logger_); - - function_container_.emplace_back(std::move(func_ptr)); - node.SetFunctionBody(*function_container_.back()); } } diff --git a/onnxruntime/test/ir/graph_test.cc b/onnxruntime/test/ir/graph_test.cc index 75f5933505..558beed2e3 100644 --- a/onnxruntime/test/ir/graph_test.cc +++ b/onnxruntime/test/ir/graph_test.cc @@ -145,7 +145,19 @@ static bool RegisterCustomSchemas() { } } return nodes; - }()); + }(), + []() { + std::vector operator_sets(2); + auto& onnx_opset = operator_sets[0]; + onnx_opset.set_domain(""); + onnx_opset.set_version(11); + + auto& test_opset = operator_sets[1]; + test_opset.set_domain(kMSNchwcDomain); + test_opset.set_version(1); + + return operator_sets; + }()); return true; } diff --git a/onnxruntime/test/onnx/main.cc b/onnxruntime/test/onnx/main.cc index c1e6ab9576..f8dc8ee9e4 100644 --- a/onnxruntime/test/onnx/main.cc +++ b/onnxruntime/test/onnx/main.cc @@ -583,11 +583,38 @@ int real_main(int argc, char* argv[], Ort::Env& env) { {"momentum", "not a registered function/op", {}}, // Op not registered. {"momentum_multiple", "not a registered function/op", {}}, // Op not registered. {"nesterov_momentum", "not a registered function/op", {}}, // Op not registered. - {"cast_FLOAT_to_BFLOAT16", "onnx generate bfloat tensor as uint16 type", {}}, - {"cast_BFLOAT16_to_FLOAT", "onnx generate bfloat tensor as uint16 type", {}}, {"sequence_insert_at_back", "onnx currently not supporting loading segment", {}}, {"sequence_insert_at_front", "onnx currently not supporting loading segment", {}}, {"loop13_seq", "ORT api does not currently support creating empty sequences (needed for this test)", {}}, + {"cast_FLOAT_to_BFLOAT16", "onnx generate bfloat tensor as uint16 type", {}}, + {"cast_BFLOAT16_to_FLOAT", "onnx generate bfloat tensor as uint16 type", {}}, + {"castlike_FLOAT_to_BFLOAT16", "Depends on cast.", {}}, + {"castlike_BFLOAT16_to_FLOAT", "Depends on cast", {}}, + {"castlike_FLOAT_to_BFLOAT16_expanded", "Depends on cast.", {}}, + {"castlike_BFLOAT16_to_FLOAT_expanded", "Depends on cast", {}}, + {"castlike_FLOAT_to_STRING", "Numpy float to string has unexpected rounding for some results.", {}}, + {"castlike_FLOAT_to_STRING_expanded", "Numpy float to string has unexpected rounding for some results.", {}}, + {"bernoulli", "By design. Test data is for informational purpose because the generator is non deterministic."}, + {"bernoulli_double", "By design. Test data is for informational purpose because the generator is non deterministic."}, + {"bernoulli_double_expanded", "By design. Test data is for informational purpose because the generator is non deterministic."}, + {"bernoulli_seed", "By design. Test data is for informational purpose because the generator is non deterministic."}, + {"bernoulli_seed_expanded", "By design. Test data is for informational purpose because the generator is non deterministic."}, + {"bernoulli_expanded", "By design. Test data is for informational purpose because the generator is non deterministic."}, + {"shape", "opset15 updates not supported yet."}, + {"shape_clip_end", "opset15 updates not supported yet."}, + {"shape_clip_start", "opset15 updates not supported yet."}, + {"shape_end_1", "opset15 updates not supported yet."}, + {"shape_end_negative_1", "opset15 updates not supported yet."}, + {"shape_example", "opset15 updates not supported yet."}, + {"shape_start_1", "opset15 updates not supported yet."}, + {"shape_start_1_end_2", "opset15 updates not supported yet."}, + {"shape_start_1_end_negative_1", "opset15 updates not supported yet."}, + {"shape_start_negative_1", "opset15 updates not supported yet."}, + {"test_optional_get_element", "opset15 updates not supported yet."}, + {"test_optional_get_element_sequence", "opset15 updates not supported yet."}, + {"test_optional_has_element", "opset15 updates not supported yet."}, + {"test_optional_has_element_empty", "opset15 updates not supported yet."}, + }; #ifdef DISABLE_ML_OPS diff --git a/onnxruntime/test/providers/cpu/math/softmax_test.cc b/onnxruntime/test/providers/cpu/math/softmax_test.cc index 0adecc0a48..197dead786 100644 --- a/onnxruntime/test/providers/cpu/math/softmax_test.cc +++ b/onnxruntime/test/providers/cpu/math/softmax_test.cc @@ -275,7 +275,7 @@ TEST(SoftmaxOperator, InvalidAxis_opset13) { // In opset-13, Softmax is composed as afunction of several other ops, // and hence it breaks differently to the test above but the most important thing // is that it breaks and this is the right behavior - "[ShapeInferenceError] axis must be in [-rank, rank-1]. input rank was 2"); + "[ShapeInferenceError]"); } TEST(SoftmaxOperator, DimWithZero) { std::vector x_vals = {}; diff --git a/onnxruntime/test/providers/cpu/tensor/shape_inference_test_helper.h b/onnxruntime/test/providers/cpu/tensor/shape_inference_test_helper.h index bee27fa0a5..6e59673adf 100644 --- a/onnxruntime/test/providers/cpu/tensor/shape_inference_test_helper.h +++ b/onnxruntime/test/providers/cpu/tensor/shape_inference_test_helper.h @@ -89,7 +89,7 @@ inline void TestShapeInference(const std::string& op_type, node->add_output("Output"); - ONNX_NAMESPACE::shape_inference::InferShapes(model, true, schema_registry); + ONNX_NAMESPACE::shape_inference::InferShapes(model, schema_registry); ONNX_NAMESPACE::checker::check_model(model); auto inferredGraph = model.graph(); diff --git a/onnxruntime/test/testdata/onnx_backend_test_series_filters.jsonc b/onnxruntime/test/testdata/onnx_backend_test_series_filters.jsonc index a8bad5609c..e1218394dd 100644 --- a/onnxruntime/test/testdata/onnx_backend_test_series_filters.jsonc +++ b/onnxruntime/test/testdata/onnx_backend_test_series_filters.jsonc @@ -66,8 +66,9 @@ "^test_mul_uint8_cpu", "^test_add_uint8_cpu", "^test_div_uint8_cpu", - "^test_batchnorm_*", - "^test_bernoulli_*", + // Following tests are for opset 15 ops and are not yet implemented in ORT + "^test_shape_*", + "^test_optional_*", //GPU failures "^test_batchnorm_epsilon_training_mode_cuda", "^test_batchnorm_example_training_mode_cuda", @@ -311,7 +312,13 @@ // Numpy float to string has unexpected rounding for some results given numpy default precision is meant to be 8. // e.g. 0.296140194 -> "0.2961402" not "0.29614019". ORT produces the latter with precision set to 8, which // doesn"t match the expected output that was generated with numpy. - "^test_cast_FLOAT_to_STRING" + "^test_cast_FLOAT_to_STRING", + "^test_castlike_FLOAT_to_STRING", + "^test_castlike_FLOAT_to_STRING_expanded", + // The test cases for Bernoulli op are for informational purpose. The generator operator is + // non-deterministic and may not produce the same values in different implementations + // even if a seed is specified. + "^test_bernoulli_*" ], "test_with_types_disabled_due_to_binary_size_concerns": [ "^test_bitshift_right_uint16", diff --git a/orttraining/orttraining/core/graph/training_op_defs.cc b/orttraining/orttraining/core/graph/training_op_defs.cc index 5c32e1b992..1f00e08432 100644 --- a/orttraining/orttraining/core/graph/training_op_defs.cc +++ b/orttraining/orttraining/core/graph/training_op_defs.cc @@ -649,7 +649,7 @@ void RegisterTrainingOpSchemas() { onnx_opset_13.set_domain(""); onnx_opset_13.set_version(13); - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); }); ONNX_CONTRIB_OPERATOR_SCHEMA(LogSoftmaxGrad) @@ -1711,7 +1711,7 @@ Example 4: {{"scaled_dy"}, "Div", {"dy", "scale"}}, {{"dx"}, "Where", {"mask", "scaled_dy", "C0"}}}; - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); } else { // ratio not specified. Use a value of 0.5 std::vector body{ @@ -1722,7 +1722,7 @@ Example 4: {{"scaled_dy"}, "Div", {"dy", "scale"}}, {{"dx"}, "Where", {"mask", "scaled_dy", "C0"}}}; - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); } }); @@ -2079,7 +2079,7 @@ Example 4: onnx_opset_13.set_domain(""); onnx_opset_13.set_version(13); - return ONNX_NAMESPACE::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); + return ONNX_NAMESPACE::FunctionBodyHelper::BuildFunctionProto(functionProto, schema, body, {onnx_opset_13}); }); ONNX_CONTRIB_OPERATOR_SCHEMA(LayerNormalizationGrad) diff --git a/tools/ci_build/github/linux/docker/scripts/manylinux/requirements.txt b/tools/ci_build/github/linux/docker/scripts/manylinux/requirements.txt index 7cd70d7738..a863e7c3c7 100644 --- a/tools/ci_build/github/linux/docker/scripts/manylinux/requirements.txt +++ b/tools/ci_build/github/linux/docker/scripts/manylinux/requirements.txt @@ -3,7 +3,7 @@ mypy pytest setuptools>=41.4.0 wheel -git+http://github.com/onnx/onnx.git@d75fb0502c9d8fef817d82c15223b4aaae8e8b6e#egg=onnx +git+http://github.com/onnx/onnx.git@1f63dcb7fcc3a8bf5c3c8e326867ecd6f5c43f35#egg=onnx protobuf sympy==1.1.1 flake8 diff --git a/tools/ci_build/github/linux/docker/scripts/requirements.txt b/tools/ci_build/github/linux/docker/scripts/requirements.txt index dc99f91897..c861ea40e2 100644 --- a/tools/ci_build/github/linux/docker/scripts/requirements.txt +++ b/tools/ci_build/github/linux/docker/scripts/requirements.txt @@ -4,7 +4,7 @@ mypy pytest setuptools>=41.4.0 wheel -git+http://github.com/onnx/onnx.git@d75fb0502c9d8fef817d82c15223b4aaae8e8b6e#egg=onnx +git+http://github.com/onnx/onnx.git@1f63dcb7fcc3a8bf5c3c8e326867ecd6f5c43f35#egg=onnx argparse sympy==1.1.1 flake8 diff --git a/tools/ci_build/github/linux/ort_minimal/build_minimal_ort_android_baseline_and_report_bin_size.sh b/tools/ci_build/github/linux/ort_minimal/build_minimal_ort_android_baseline_and_report_bin_size.sh index 2edaa49bc7..13a0c79144 100644 --- a/tools/ci_build/github/linux/ort_minimal/build_minimal_ort_android_baseline_and_report_bin_size.sh +++ b/tools/ci_build/github/linux/ort_minimal/build_minimal_ort_android_baseline_and_report_bin_size.sh @@ -29,7 +29,7 @@ python3 /onnxruntime_src/tools/ci_build/build.py \ --include_ops_by_config /home/onnxruntimedev/.test_data/include_no_operators.config # set current size limit to BINARY_SIZE_LIMIT_IN_BYTES. -BINARY_SIZE_LIMIT_IN_BYTES=1220000 +BINARY_SIZE_LIMIT_IN_BYTES=1235000 echo "The current preset binary size limit is $BINARY_SIZE_LIMIT_IN_BYTES" python3 /onnxruntime_src/tools/ci_build/github/linux/ort_minimal/check_build_binary_size.py \ --threshold=$BINARY_SIZE_LIMIT_IN_BYTES \