From aef49d1f2200a44ba2290c453c052ea9090b5679 Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Tue, 1 Oct 2019 08:11:15 +1000 Subject: [PATCH] Update ops that had strides/dilations documentation updates to default to 1 (#1913) * Update ops that had strides/dilations documentation updates to default to 1. Code was already doing this. Add tests to explicilty test. * Update optimizers to add opset 11 support where possible --- .../core/optimizer/conv_activation_fusion.cc | 3 +- onnxruntime/core/optimizer/conv_add_fusion.cc | 2 +- onnxruntime/core/optimizer/conv_bn_fusion.cc | 2 +- onnxruntime/core/optimizer/conv_mul_fusion.cc | 2 +- .../core/optimizer/nchwc_transformer.cc | 6 +- .../core/optimizer/slice_elimination.cc | 4 +- .../providers/cpu/cpu_execution_provider.cc | 41 ++-- onnxruntime/core/providers/cpu/nn/Unpool.cc | 13 +- onnxruntime/core/providers/cpu/nn/conv.cc | 8 +- .../core/providers/cpu/nn/conv_attributes.h | 5 +- .../core/providers/cpu/nn/conv_transpose.cc | 8 +- onnxruntime/core/providers/cpu/nn/pool.cc | 26 +- onnxruntime/core/providers/cpu/nn/unpool.h | 1 - .../test/providers/cpu/nn/conv_op_test.cc | 40 +++- .../cpu/nn/conv_transpose_op_test.cc | 222 ++++++++++-------- .../test/providers/cpu/nn/pool_op_test.cc | 39 +++ .../test/providers/cpu/nn/unpool_op_test.cc | 20 ++ 17 files changed, 308 insertions(+), 134 deletions(-) diff --git a/onnxruntime/core/optimizer/conv_activation_fusion.cc b/onnxruntime/core/optimizer/conv_activation_fusion.cc index a3e1f40008..90d99fdeab 100644 --- a/onnxruntime/core/optimizer/conv_activation_fusion.cc +++ b/onnxruntime/core/optimizer/conv_activation_fusion.cc @@ -38,7 +38,7 @@ Status ConvActivationFusion::ApplyImpl(Graph& graph, bool& modified, int graph_l auto* node = graph.GetNode(index); ORT_RETURN_IF_ERROR(Recurse(*node, modified, graph_level)); - if (!graph_utils::IsSupportedOptypeVersionAndDomain(*node, "Conv", {1}) || + if (!graph_utils::IsSupportedOptypeVersionAndDomain(*node, "Conv", {1, 11}) || !graph_utils::IsSupportedProvider(*node, GetCompatibleExecutionProviders()) || node->GetOutputEdgesCount() != 1) { continue; @@ -84,7 +84,6 @@ Status ConvActivationFusion::ApplyImpl(Graph& graph, bool& modified, int graph_l } if (!graph.IsNodeOutputsInGraphOutputs(next_node)) { - HandleActivationNodeEdges(graph, next_node, fused_conv); // Replace the input of the node following activation node diff --git a/onnxruntime/core/optimizer/conv_add_fusion.cc b/onnxruntime/core/optimizer/conv_add_fusion.cc index 64c468e98f..6527340eef 100644 --- a/onnxruntime/core/optimizer/conv_add_fusion.cc +++ b/onnxruntime/core/optimizer/conv_add_fusion.cc @@ -105,7 +105,7 @@ Status ConvAddFusion::Apply(Graph& graph, Node& node, RewriteRuleEffect& modifie } bool ConvAddFusion::SatisfyCondition(const Graph& graph, const Node& node) const { - if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1}) || + if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1, 11}) || node.GetOutputEdgesCount() != 1) { return false; } diff --git a/onnxruntime/core/optimizer/conv_bn_fusion.cc b/onnxruntime/core/optimizer/conv_bn_fusion.cc index 9dea7bed86..0da6716fe9 100644 --- a/onnxruntime/core/optimizer/conv_bn_fusion.cc +++ b/onnxruntime/core/optimizer/conv_bn_fusion.cc @@ -141,7 +141,7 @@ Status ConvBNFusion::Apply(Graph& graph, Node& node, RewriteRuleEffect& rule_eff } bool ConvBNFusion::SatisfyCondition(const Graph& graph, const Node& node) const { - if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1}) || + if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1, 11}) || node.GetOutputEdgesCount() != 1) { return false; } diff --git a/onnxruntime/core/optimizer/conv_mul_fusion.cc b/onnxruntime/core/optimizer/conv_mul_fusion.cc index 32b4c0bbd4..16902bffb6 100644 --- a/onnxruntime/core/optimizer/conv_mul_fusion.cc +++ b/onnxruntime/core/optimizer/conv_mul_fusion.cc @@ -103,7 +103,7 @@ Status ConvMulFusion::Apply(Graph& graph, Node& node, RewriteRuleEffect& rule_ef } bool ConvMulFusion::SatisfyCondition(const Graph& graph, const Node& node) const { - if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1}) || + if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1, 11}) || node.GetOutputEdgesCount() != 1) { return false; } diff --git a/onnxruntime/core/optimizer/nchwc_transformer.cc b/onnxruntime/core/optimizer/nchwc_transformer.cc index 144a6ab798..b5fb2b961e 100644 --- a/onnxruntime/core/optimizer/nchwc_transformer.cc +++ b/onnxruntime/core/optimizer/nchwc_transformer.cc @@ -661,11 +661,11 @@ void NchwcTransformerImpl::TransformActivation(Node& node) { } void NchwcTransformerImpl::Transform(Node& node) { - if (graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1}) || + if (graph_utils::IsSupportedOptypeVersionAndDomain(node, "Conv", {1, 11}) || graph_utils::IsSupportedOptypeVersionAndDomain(node, "FusedConv", {1}, kMSDomain)) { TransformConv(node); - } else if (graph_utils::IsSupportedOptypeVersionAndDomain(node, "MaxPool", {1, 8, 10}) || - graph_utils::IsSupportedOptypeVersionAndDomain(node, "AveragePool", {1, 7, 10}) || + } else if (graph_utils::IsSupportedOptypeVersionAndDomain(node, "MaxPool", {1, 8, 10, 11}) || + graph_utils::IsSupportedOptypeVersionAndDomain(node, "AveragePool", {1, 7, 10, 11}) || graph_utils::IsSupportedOptypeVersionAndDomain(node, "GlobalMaxPool", {1}) || graph_utils::IsSupportedOptypeVersionAndDomain(node, "GlobalAveragePool", {1})) { TransformPool(node); diff --git a/onnxruntime/core/optimizer/slice_elimination.cc b/onnxruntime/core/optimizer/slice_elimination.cc index 65ebd81811..9522777497 100644 --- a/onnxruntime/core/optimizer/slice_elimination.cc +++ b/onnxruntime/core/optimizer/slice_elimination.cc @@ -19,10 +19,10 @@ Status EliminateSlice::Apply(Graph& graph, Node& node, RewriteRuleEffect& rule_e bool EliminateSlice::SatisfyCondition(const Graph& graph, const Node& node) const { // We currently support elimination for Slice operator v1. // TODO Extend to support Slice operator v10, which includes "steps" and all attributes are now given as inputs. - if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Slice", {1})) { + if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "Slice", {1, 11})) { return false; } - + if (!graph_utils::IsSingleInSingleOutNode(node) || graph.IsNodeOutputsInGraphOutputs(node)) { return false; diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index 2c5e8a9e05..3214dc9211 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -113,17 +113,16 @@ class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOn class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 10, Softmax); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 9, TopK); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, BatchNormalization); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, Conv); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, ConvTranspose); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 10, Conv); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 10, ConvTranspose); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 8, Flatten); -class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 10, Flatten); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 6, InstanceNormalization); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, LpNormalization); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, LRN); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, AveragePool); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 7, MaxPool); class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 8, 9, MaxPool); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 2, LpPool); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 2, 10, LpPool); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 2, GlobalLpPool); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, GlobalAveragePool); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, GlobalMaxPool); @@ -244,7 +243,7 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int64_t_float_int64_t, OneHot); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int32_t_float_int32_t, OneHot); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int32_t_float_float, OneHot); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, MaxUnpool); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 10, MaxUnpool); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Sinh); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Cosh); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Asinh); @@ -264,12 +263,13 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, float, Where); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int32_t, Where); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int64_t, Where); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 10, Flatten); // Opset 10 class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, StringNormalizer); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, TopK); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, MaxPool); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, AveragePool); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, MaxPool); +class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, 10, AveragePool); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, Mod); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, float, Resize); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, int32_t, Resize); @@ -347,7 +347,12 @@ class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Un class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Det); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, ScatterElements); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, NonMaxSuppression); - +class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, AveragePool); +class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, MaxPool); +class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, MaxUnpool); +class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, LpPool); +class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Conv); +class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, ConvTranspose); void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { static const BuildKernelCreateInfoFn function_table[] = { @@ -446,17 +451,16 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, @@ -577,7 +581,7 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, @@ -597,12 +601,13 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, // Opset 10 BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, @@ -680,6 +685,12 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, }; for (auto& function_table_entry : function_table) { diff --git a/onnxruntime/core/providers/cpu/nn/Unpool.cc b/onnxruntime/core/providers/cpu/nn/Unpool.cc index 853bd05cdd..b84402cc4b 100644 --- a/onnxruntime/core/providers/cpu/nn/Unpool.cc +++ b/onnxruntime/core/providers/cpu/nn/Unpool.cc @@ -14,13 +14,20 @@ using namespace ::onnxruntime::common; namespace onnxruntime { -ONNX_CPU_OPERATOR_KERNEL( +ONNX_CPU_OPERATOR_VERSIONED_KERNEL( MaxUnpool, - 9, + 9, 10, + KernelDefBuilder() + .TypeConstraint("T1", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", DataTypeImpl::GetTensorType()), + MaxUnpool); + +ONNX_CPU_OPERATOR_KERNEL( + MaxUnpool, + 11, KernelDefBuilder() .TypeConstraint("T1", DataTypeImpl::GetTensorType()) .TypeConstraint("T2", DataTypeImpl::GetTensorType()), - // .TypeConstraint("Y", DataTypeImpl::GetTensorType()), MaxUnpool); Status MaxUnpool::Compute(OpKernelContext* context) const { diff --git a/onnxruntime/core/providers/cpu/nn/conv.cc b/onnxruntime/core/providers/cpu/nn/conv.cc index 87ca17fd0c..56430eb44b 100644 --- a/onnxruntime/core/providers/cpu/nn/conv.cc +++ b/onnxruntime/core/providers/cpu/nn/conv.cc @@ -278,9 +278,15 @@ Status Conv::Compute(OpKernelContext* context) const { return Status::OK(); } +ONNX_CPU_OPERATOR_VERSIONED_KERNEL( + Conv, + 1, 10, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), + Conv); + ONNX_CPU_OPERATOR_KERNEL( Conv, - 1, + 11, KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Conv); diff --git a/onnxruntime/core/providers/cpu/nn/conv_attributes.h b/onnxruntime/core/providers/cpu/nn/conv_attributes.h index 7286bcaecf..6a238073c4 100644 --- a/onnxruntime/core/providers/cpu/nn/conv_attributes.h +++ b/onnxruntime/core/providers/cpu/nn/conv_attributes.h @@ -68,7 +68,7 @@ struct ConvAttributes { kernel_shape_specified = info.GetAttrs("kernel_shape", kernel_shape_).IsOK(); status = info.GetAttrs("strides", strides); - if (!status.IsOK()) { + if (!status.IsOK() || strides.empty()) { strides.resize(kernel_shape_.size(), 1); } @@ -78,7 +78,7 @@ struct ConvAttributes { } status = info.GetAttrs("dilations", dilations); - if (!status.IsOK()) { + if (!status.IsOK() || dilations.empty()) { dilations.resize(kernel_shape_.size(), 1); } @@ -89,6 +89,7 @@ struct ConvAttributes { #if false // TODO: Re-enable when attributes values are guaranteed to be filled. + // Make sure empty strides or dilations are defaulted to 1 if necessary std::string auto_pad_str; ORT_ENFORCE(info.GetAttr("auto_pad", &auto_pad_str).IsOK()); auto_pad = StringToAutoPadType(auto_pad_str); diff --git a/onnxruntime/core/providers/cpu/nn/conv_transpose.cc b/onnxruntime/core/providers/cpu/nn/conv_transpose.cc index 4e3c7b33ea..08b99c0d77 100644 --- a/onnxruntime/core/providers/cpu/nn/conv_transpose.cc +++ b/onnxruntime/core/providers/cpu/nn/conv_transpose.cc @@ -23,9 +23,15 @@ namespace onnxruntime { +ONNX_CPU_OPERATOR_VERSIONED_KERNEL( + ConvTranspose, + 1, 10, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), + ConvTranspose); + ONNX_CPU_OPERATOR_KERNEL( ConvTranspose, - 1, + 11, KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), ConvTranspose); diff --git a/onnxruntime/core/providers/cpu/nn/pool.cc b/onnxruntime/core/providers/cpu/nn/pool.cc index 28cb52edda..6582bd965e 100644 --- a/onnxruntime/core/providers/cpu/nn/pool.cc +++ b/onnxruntime/core/providers/cpu/nn/pool.cc @@ -415,9 +415,15 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pool); +ONNX_CPU_OPERATOR_VERSIONED_KERNEL( + AveragePool, + 10, 10, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), + Pool); + ONNX_CPU_OPERATOR_KERNEL( AveragePool, - 10, + 11, KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pool); @@ -433,15 +439,27 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()).TypeConstraint("I", DataTypeImpl::GetTensorType()), Pool>); -ONNX_CPU_OPERATOR_KERNEL( +ONNX_CPU_OPERATOR_VERSIONED_KERNEL( MaxPool, - 10, + 10, 10, KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()).TypeConstraint("I", DataTypeImpl::GetTensorType()), Pool>); ONNX_CPU_OPERATOR_KERNEL( + MaxPool, + 11, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()).TypeConstraint("I", DataTypeImpl::GetTensorType()), + Pool>); + +ONNX_CPU_OPERATOR_VERSIONED_KERNEL( LpPool, - 2, + 2, 10, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), + Pool); + +ONNX_CPU_OPERATOR_KERNEL( + LpPool, + 11, KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pool); diff --git a/onnxruntime/core/providers/cpu/nn/unpool.h b/onnxruntime/core/providers/cpu/nn/unpool.h index 66c132a03d..723ead3c26 100644 --- a/onnxruntime/core/providers/cpu/nn/unpool.h +++ b/onnxruntime/core/providers/cpu/nn/unpool.h @@ -54,7 +54,6 @@ class MaxUnpool : public OpKernel { } ~MaxUnpool() override = default; - ; Status Compute(OpKernelContext* context) const override; diff --git a/onnxruntime/test/providers/cpu/nn/conv_op_test.cc b/onnxruntime/test/providers/cpu/nn/conv_op_test.cc index 8f317a27bc..462cf604c4 100644 --- a/onnxruntime/test/providers/cpu/nn/conv_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/conv_op_test.cc @@ -29,13 +29,20 @@ void TestConvOp(const ConvOpAttributes& attributes, const std::string& err_str = "") { OpTester test("Conv"); test.AddAttribute("auto_pad", attributes.auto_pad); - test.AddAttribute("dilations", attributes.dilations); test.AddAttribute("group", attributes.group); test.AddAttribute("kernel_shape", attributes.kernel_shape); + + if (!attributes.dilations.empty()) { + test.AddAttribute("dilations", attributes.dilations); + } + if (!attributes.pads.empty()) { test.AddAttribute("pads", attributes.pads); } - test.AddAttribute("strides", attributes.strides); + + if (!attributes.strides.empty()) { + test.AddAttribute("strides", attributes.strides); + } ORT_ENFORCE(inputs.size() <= 3, "Our name array is only setup to handle 3 inputs"); const char* szNames[] = {"X", "W", "B"}; @@ -50,7 +57,7 @@ void TestConvOp(const ConvOpAttributes& attributes, if (!is_mkldnn_supported) { excluded_providers.insert(kMklDnnExecutionProvider); } - excluded_providers.insert(kTensorrtExecutionProvider);// Disable TensorRT because weight as input is not supported + excluded_providers.insert(kTensorrtExecutionProvider); // Disable TensorRT because weight as input is not supported test.Run(expect_result, err_str, excluded_providers); } @@ -78,6 +85,27 @@ TEST(ConvTest, Conv1D_1) { TestConvOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); } +TEST(ConvTest, Conv1D_1_DefaultStridesAndDilations) { + ConvOpAttributes attrs = { + "", // auto_pad + vector{}, // dilations + 1, // group + vector{1}, // kernel_shape + vector{0, 0}, // pads + vector{} // strides + }; + vector X = {-0.21559301018714905f, 0.4691687822341919f, 0.4426700472831726f, -0.4517466723918915f, + -0.05216419696807861f, 0.29067182540893555f, 0.251010000705719f}; + vector X_shape = {1, 1, 7}; + vector W = {0.24472862482070923f}; + vector W_shape = {1, 1, 1}; + vector Y_shape = {1, 1, 7}; + auto expected_vals = {-0.052761781960725784f, 0.11481902748346329f, 0.10833403468132019f, -0.11055534332990646f, + -0.012766072526574135f, 0.07113571465015411f, 0.061429332941770554f}; + + TestConvOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); +} + // Conv3 TEST(ConvTest, Conv1D_2) { ConvOpAttributes attrs = { @@ -179,7 +207,8 @@ TEST(ConvTest, Conv1D_Invalid_Input_Shape) { vector dummy_shape = {1, 1, 2}; auto dummy_vals = {0.0f, 0.0f}; TestConvOp(attrs, {X, dummy_vals}, {X_shape, dummy_shape}, dummy_vals, dummy_shape, true, true, - OpTester::ExpectResult::kExpectFailure, "Node:node1 Output:Y [ShapeInferenceError] Can't merge shape info. " + OpTester::ExpectResult::kExpectFailure, + "Node:node1 Output:Y [ShapeInferenceError] Can't merge shape info. " "Both source and target dimension have values but they differ. Source=0 Target=2 Dimension=2"); } @@ -198,7 +227,8 @@ TEST(ConvTest, Conv2D_Invalid_Input_Shape) { auto dummy_vals = {-0.0f, 0.0f, -0.0f, -0.0f, -0.0f, 0.0f, -0.0f, -0.0f}; TestConvOp(attrs, {X, dummy_vals}, {X_shape, dummy_shape}, dummy_vals, dummy_shape, true, true, - OpTester::ExpectResult::kExpectFailure, "Node:node1 Output:Y [ShapeInferenceError] Can't merge shape info. " + OpTester::ExpectResult::kExpectFailure, + "Node:node1 Output:Y [ShapeInferenceError] Can't merge shape info. " "Both source and target dimension have values but they differ. Source=1 Target=2 Dimension=0"); } diff --git a/onnxruntime/test/providers/cpu/nn/conv_transpose_op_test.cc b/onnxruntime/test/providers/cpu/nn/conv_transpose_op_test.cc index 22e6d728de..b88503bead 100644 --- a/onnxruntime/test/providers/cpu/nn/conv_transpose_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/conv_transpose_op_test.cc @@ -28,16 +28,23 @@ void TestConvTransposeOp(const ConvTransposeOpAttributes& attributes, const std::string& err_str = "") { OpTester test("ConvTranspose"); test.AddAttribute("kernel_shape", attributes.kernel_shape); + test.AddAttribute("pads", attributes.pads); + test.AddAttribute("group", attributes.group); + if (!attributes.output_padding.empty()) { test.AddAttribute("output_padding", attributes.output_padding); } if (!attributes.output_shape.empty()) { test.AddAttribute("output_shape", attributes.output_shape); } - test.AddAttribute("pads", attributes.pads); - test.AddAttribute("strides", attributes.strides); - test.AddAttribute("dilations", attributes.dilations); - test.AddAttribute("group", attributes.group); + + if (!attributes.strides.empty()) { + test.AddAttribute("strides", attributes.strides); + } + + if (!attributes.dilations.empty()) { + test.AddAttribute("dilations", attributes.dilations); + } ORT_ENFORCE(inputs.size() <= 3, "Our name array is only setup to handle 3 inputs"); const char* szNames[] = {"X", "W", "B"}; @@ -45,7 +52,7 @@ void TestConvTransposeOp(const ConvTransposeOpAttributes& attributes, test.AddInput(szNames[i], input_shapes[i], inputs[i]); } test.AddOutput("Y", expected_output_shape, expected_output); - test.Run(expect_result, err_str, {kTensorrtExecutionProvider});// Disable TensorRT because weight as input is not supported + test.Run(expect_result, err_str, {kTensorrtExecutionProvider}); // Disable TensorRT because weight as input is not supported } } // namespace @@ -350,127 +357,158 @@ TEST(ConvTransposeTest, ConvTranspose_onnx_group) { TEST(ConvTransposeTest, ConvTranspose_2D_Dilation_1) { ConvTransposeOpAttributes attrs = { - vector{2, 2}, - {}, {}, - vector{0,0,0,0}, - vector{1,1}, - {2,2}, - 1 - }; + vector{2, 2}, + {}, + {}, + vector{0, 0, 0, 0}, + vector{1, 1}, + {2, 2}, + 1}; - vector X = {11.0f,12.0f,21.0f,22.0f}; - vector X_shape = {1,1,2,2}; - vector W = {1.0f,1.0f,1.0f,1.0f}; - vector W_shape = {1,1,2,2}; - vector Y_shape = {1,1,4,4}; - auto expected_vals = {11.0f,12.0f,11.0f,12.0f, - 21.0f,22.0f,21.0f,22.0f, - 11.0f,12.0f,11.0f,12.0f, - 21.0f,22.0f,21.0f,22.0f}; + vector X = {11.0f, 12.0f, 21.0f, 22.0f}; + vector X_shape = {1, 1, 2, 2}; + vector W = {1.0f, 1.0f, 1.0f, 1.0f}; + vector W_shape = {1, 1, 2, 2}; + vector Y_shape = {1, 1, 4, 4}; + auto expected_vals = {11.0f, 12.0f, 11.0f, 12.0f, + 21.0f, 22.0f, 21.0f, 22.0f, + 11.0f, 12.0f, 11.0f, 12.0f, + 21.0f, 22.0f, 21.0f, 22.0f}; TestConvTransposeOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); } TEST(ConvTransposeTest, ConvTranspose_2D_Dilation_2) { ConvTransposeOpAttributes attrs = { - vector{2, 2}, - {}, {}, - vector{0,0,0,0}, - vector{1,1}, - {3,3}, - 1 - }; + vector{2, 2}, + {}, + {}, + vector{0, 0, 0, 0}, + vector{1, 1}, + {3, 3}, + 1}; - vector X = {11.0f,12.0f,21.0f,22.0f}; - vector X_shape = {1,1,2,2}; - vector W = {1.0f,1.0f,1.0f,1.0f}; - vector W_shape = {1,1,2,2}; - vector Y_shape = {1,1,5,5}; - auto expected_vals = {11.0f,12.0f,0.0f,11.0f,12.0f, - 21.0f,22.0f,0.0f,21.0f,22.0f, - 0.0f, 0.0f, 0.0f,0.0f, 0.0f, - 11.0f,12.0f,0.0f,11.0f,12.0f, - 21.0f,22.0f,0.0f,21.0f,22.0f}; + vector X = {11.0f, 12.0f, 21.0f, 22.0f}; + vector X_shape = {1, 1, 2, 2}; + vector W = {1.0f, 1.0f, 1.0f, 1.0f}; + vector W_shape = {1, 1, 2, 2}; + vector Y_shape = {1, 1, 5, 5}; + auto expected_vals = {11.0f, 12.0f, 0.0f, 11.0f, 12.0f, + 21.0f, 22.0f, 0.0f, 21.0f, 22.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 11.0f, 12.0f, 0.0f, 11.0f, 12.0f, + 21.0f, 22.0f, 0.0f, 21.0f, 22.0f}; TestConvTransposeOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); } TEST(ConvTransposeTest, ConvTranspose_2D_Dilation_3) { ConvTransposeOpAttributes attrs = { - vector{2, 2}, - {}, {}, - vector{0,0,0,0}, - vector{1,1}, - {2,2}, - 1 - }; + vector{2, 2}, + {}, + {}, + vector{0, 0, 0, 0}, + vector{1, 1}, + {2, 2}, + 1}; - vector X = {3.0f,8.0f,1.0f,9.0f,5.0f,7.0f,3.0f,2.0f,6.0f}; - vector X_shape = {1,1,3,3}; - vector W = {7.0f,2.0f,1.0f,9.0f}; - vector W_shape = {1,1,2,2}; - vector Y_shape = {1,1,5,5}; - auto expected_vals = {21.0f, 56.0f, 13.0f, 16.0f, 2.0f, + vector X = {3.0f, 8.0f, 1.0f, 9.0f, 5.0f, 7.0f, 3.0f, 2.0f, 6.0f}; + vector X_shape = {1, 1, 3, 3}; + vector W = {7.0f, 2.0f, 1.0f, 9.0f}; + vector W_shape = {1, 1, 2, 2}; + vector Y_shape = {1, 1, 5, 5}; + auto expected_vals = {21.0f, 56.0f, 13.0f, 16.0f, 2.0f, 63.0f, 35.0f, 67.0f, 10.0f, 14.0f, 24.0f, 22.0f, 76.0f, 76.0f, 21.0f, - 9.0f, 5.0f, 88.0f, 45.0f, 63.0f, - 3.0f, 2.0f, 33.0f, 18.0f, 54.0f}; + 9.0f, 5.0f, 88.0f, 45.0f, 63.0f, + 3.0f, 2.0f, 33.0f, 18.0f, 54.0f}; TestConvTransposeOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); } TEST(ConvTransposeTest, ConvTranspose_2D_Dilation_4) { ConvTransposeOpAttributes attrs = { - vector{2, 2}, - {}, {}, - vector{0,0,0,0}, - vector{1,1}, - {3,3}, - 1 - }; + vector{2, 2}, + {}, + {}, + vector{0, 0, 0, 0}, + vector{1, 1}, + {3, 3}, + 1}; - vector X = {3.0f,8.0f,1.0f,9.0f,5.0f,7.0f,3.0f,2.0f,6.0f}; - vector X_shape = {1,1,3,3}; - vector W = {7.0f,2.0f,1.0f,9.0f}; - vector W_shape = {1,1,2,2}; - vector Y_shape = {1,1,6,6}; - auto expected_vals = {21.0f, 56.0f, 7.0f, 6.0f, 16.0f, 2.0f, + vector X = {3.0f, 8.0f, 1.0f, 9.0f, 5.0f, 7.0f, 3.0f, 2.0f, 6.0f}; + vector X_shape = {1, 1, 3, 3}; + vector W = {7.0f, 2.0f, 1.0f, 9.0f}; + vector W_shape = {1, 1, 2, 2}; + vector Y_shape = {1, 1, 6, 6}; + auto expected_vals = {21.0f, 56.0f, 7.0f, 6.0f, 16.0f, 2.0f, 63.0f, 35.0f, 49.0f, 18.0f, 10.0f, 14.0f, - 21.0f, 14.0f, 42.0f, 6.0f, 4.0f, 12.0f, - 3.0f, 8.0f, 1.0f, 27.0f, 72.0f, 9.0f, - 9.0f, 5.0f, 7.0f, 81.0f, 45.0f, 63.0f, - 3.0f, 2.0f, 6.0f, 27.0f, 18.0f, 54.0f}; + 21.0f, 14.0f, 42.0f, 6.0f, 4.0f, 12.0f, + 3.0f, 8.0f, 1.0f, 27.0f, 72.0f, 9.0f, + 9.0f, 5.0f, 7.0f, 81.0f, 45.0f, 63.0f, + 3.0f, 2.0f, 6.0f, 27.0f, 18.0f, 54.0f}; TestConvTransposeOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); } TEST(ConvTransposeTest, ConvTranspose_2D_Dilation_Group_1) { ConvTransposeOpAttributes attrs = { - vector{2, 2}, - {}, {}, - vector{0,0,0,0}, - vector{1,1}, - {2,2}, - 2 - }; + vector{2, 2}, + {}, + {}, + vector{0, 0, 0, 0}, + vector{1, 1}, + {2, 2}, + 2}; - vector X = {3.0f,8.0f,1.0f,9.0f,5.0f,7.0f,3.0f,2.0f,3.0f,7.0f,9.0f,1.0f,5.0f,2.0f,3.0f,9.0f,0.0f,2.0f}; - vector X_shape = {1,2,3,3}; - vector W = {9.0f,3.0f,1.0f,2.0f,3.0f,7.0f,0.0f,8.0f}; - vector W_shape = {2,1,2,2}; - vector Y_shape = {1,2,5,5}; - auto expected_vals = {27.0f, 72.0f, 18.0f, 24.0f, 3.0f, - 81.0f, 45.0f, 90.0f, 15.0f, 21.0f, - 30.0f, 26.0f, 43.0f, 22.0f, 11.0f, - 9.0f, 5.0f, 25.0f, 10.0f, 14.0f, - 3.0f, 2.0f, 9.0f, 4.0f, 6.0f, - 21.0f, 27.0f, 52.0f, 63.0f, 7.0f, - 15.0f, 6.0f, 44.0f, 14.0f, 21.0f, - 27.0f, 0.0f, 125.0f, 72.0f, 22.0f, - 0.0f, 0.0f, 40.0f, 16.0f, 24.0f, - 0.0f, 0.0f, 72.0f, 0.0f, 16.0f}; + vector X = {3.0f, 8.0f, 1.0f, 9.0f, 5.0f, 7.0f, 3.0f, 2.0f, 3.0f, 7.0f, 9.0f, 1.0f, 5.0f, 2.0f, 3.0f, 9.0f, 0.0f, 2.0f}; + vector X_shape = {1, 2, 3, 3}; + vector W = {9.0f, 3.0f, 1.0f, 2.0f, 3.0f, 7.0f, 0.0f, 8.0f}; + vector W_shape = {2, 1, 2, 2}; + vector Y_shape = {1, 2, 5, 5}; + auto expected_vals = {27.0f, 72.0f, 18.0f, 24.0f, 3.0f, + 81.0f, 45.0f, 90.0f, 15.0f, 21.0f, + 30.0f, 26.0f, 43.0f, 22.0f, 11.0f, + 9.0f, 5.0f, 25.0f, 10.0f, 14.0f, + 3.0f, 2.0f, 9.0f, 4.0f, 6.0f, + 21.0f, 27.0f, 52.0f, 63.0f, 7.0f, + 15.0f, 6.0f, 44.0f, 14.0f, 21.0f, + 27.0f, 0.0f, 125.0f, 72.0f, 22.0f, + 0.0f, 0.0f, 40.0f, 16.0f, 24.0f, + 0.0f, 0.0f, 72.0f, 0.0f, 16.0f}; TestConvTransposeOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); } +TEST(ConvTransposeTest, ConvTranspose_DefaultStridesAndDilations) { + ConvTransposeOpAttributes attrs = { + vector{2, 2}, // kernel_shape + {}, // output_padding + {}, // output_shape + vector{0, 0, 0, 0}, // pads + vector{}, // strides + vector{}, // dilations + 1 // group + }; + vector X = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17.}; + vector X_shape = {1, 2, 3, 3}; + vector W = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23.}; + vector W_shape = {2, 3, 2, 2}; // this requires weight transpose + vector Y_shape = {1, 3, 4, 4}; + auto expected_vals = { + 108.f, 237.f, 263.f, 145.f, + 270.f, 592.f, 652.f, 358.f, + 354.f, 772.f, 832.f, 454.f, + 222.f, 481.f, 515.f, 279.f, + 144.f, 317.f, 359.f, 197.f, + 366.f, 800.f, 892.f, 486.f, + 498.f, 1076.f, 1168.f, 630.f, + 306.f, 657.f, 707.f, 379.f, + 180.f, 397.f, 455.f, 249.f, + 462.f, 1008.f, 1132.f, 614.f, + 642.f, 1380.f, 1504.f, 806.f, + 390.f, 833.f, 899.f, 479.f}; + + TestConvTransposeOp(attrs, {X, W}, {X_shape, W_shape}, expected_vals, Y_shape); +} } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/providers/cpu/nn/pool_op_test.cc b/onnxruntime/test/providers/cpu/nn/pool_op_test.cc index 73f0ca2eb9..5e695ac7fe 100644 --- a/onnxruntime/test/providers/cpu/nn/pool_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/pool_op_test.cc @@ -229,6 +229,26 @@ TEST(PoolTest, MaxPool_10_Dilation_1d) { test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); } +TEST(PoolTest, MaxPool_DefaultDilations) { + OpTester test("MaxPool"); + + test.AddAttribute("kernel_shape", vector{2}); + + std::vector x_dims = {1, 3, 3}; + std::vector x_vals = {0.f, 1.f, 2.f, + 3.f, 4.f, 5.f, + 6.f, 7.f, 8.f}; + + std::vector expected_dims = {1, 3, 2}; + std::vector expected_vals = {1.f, 2.f, + 4.f, 5.f, + 7.f, 8.f}; + + test.AddInput("X", x_dims, x_vals); + test.AddOutput("Y", expected_dims, expected_vals); + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); +} + TEST(PoolTest, MaxPool_10_DilationPadding_1d) { OpTester test("MaxPool", 10); @@ -638,6 +658,25 @@ TEST(PoolTest, AveragePool_IncludePadPixel) { test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); } +// test 'strides' attribute not specified +TEST(PoolTest, AveragePool_DefaultStrides) { + OpTester test("AveragePool"); + test.AddAttribute("kernel_shape", vector{2}); + std::vector x_vals = {0.f, 1.f, 2.f, + 3.f, 4.f, 5.f, + 6.f, 7.f, 8.f}; + + std::vector x_dims = {1, 3, 3}; + std::vector expected_dims = {1, 3, 2}; + std::vector expected_vals = {0.5f, 1.5f, + 3.5f, 4.5f, + 6.5f, 7.5f}; + + test.AddInput("X", x_dims, x_vals); + test.AddOutput("Y", expected_dims, expected_vals); + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); +} + TEST(PoolTest, AveragePool_10_ceil1_2d) { OpTester test("AveragePool", 10); diff --git a/onnxruntime/test/providers/cpu/nn/unpool_op_test.cc b/onnxruntime/test/providers/cpu/nn/unpool_op_test.cc index fd9b20ba9c..d971e9feb4 100644 --- a/onnxruntime/test/providers/cpu/nn/unpool_op_test.cc +++ b/onnxruntime/test/providers/cpu/nn/unpool_op_test.cc @@ -378,5 +378,25 @@ TEST(UnpoolTest, MaxUnPool3D_WithPaddedOutput) { test.Run(); } +TEST(UnpoolTest, MaxUnPool_DefaultStrides) { + OpTester test("MaxUnpool", 11); + + test.AddAttribute("kernel_shape", vector{2}); + + std::vector t_vals = {1, 2, 4, 8}; + std::vector t_dims = {1, 1, 4}; + + std::vector i_vals = {1, 2, 3, 4}; + std::vector i_dims = {1, 1, 4}; + + std::vector expected_dims = {1, 1, 5}; + std::vector expected_vals = {0, 1, 2, 4, 8}; + + test.AddInput("xT", t_dims, t_vals); + test.AddInput("xI", i_dims, i_vals); + test.AddOutput("Y", expected_dims, expected_vals); + test.Run(); +} + } // namespace test } // namespace onnxruntime