From ba0b86d5c47ab5f083b07ecb6cffdc2d547a7463 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB=20=D0=98=D0=BB=D1=8C=D1=8E?= =?utf8?q?=D1=82=D1=87=D0=B5=D0=BD=D0=BA=D0=BE/AI=20Tools=20Lab=20/SRR/Eng?= =?utf8?q?ineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Fri, 23 Aug 2019 14:48:27 +0300 Subject: [PATCH] [mir_onnx] ReduceMean operation support (#6798) * Added ReduceMeanNodeConverter * Registration and cmake for converter Signed-off-by: Pavel Iliutchenko --- compiler/mir-onnx-importer/CMakeLists.txt | 2 + compiler/mir-onnx-importer/ONNXOpRegistration.h | 2 + compiler/mir-onnx-importer/Op/ReduceMean.cpp | 71 +++++++++++++++++++++++++ compiler/mir-onnx-importer/Op/ReduceMean.h | 36 +++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 compiler/mir-onnx-importer/Op/ReduceMean.cpp create mode 100644 compiler/mir-onnx-importer/Op/ReduceMean.h diff --git a/compiler/mir-onnx-importer/CMakeLists.txt b/compiler/mir-onnx-importer/CMakeLists.txt index d7e3d05..cce8e00 100644 --- a/compiler/mir-onnx-importer/CMakeLists.txt +++ b/compiler/mir-onnx-importer/CMakeLists.txt @@ -59,6 +59,8 @@ set(MIR_ONNX_IMPORTER_SOURCES Op/Mul.h Op/Pad.cpp Op/Pad.h + Op/ReduceMean.cpp + Op/ReduceMean.h Op/Relu.cpp Op/Relu.h Op/Reshape.cpp diff --git a/compiler/mir-onnx-importer/ONNXOpRegistration.h b/compiler/mir-onnx-importer/ONNXOpRegistration.h index 6527b79..04da1b2 100644 --- a/compiler/mir-onnx-importer/ONNXOpRegistration.h +++ b/compiler/mir-onnx-importer/ONNXOpRegistration.h @@ -35,6 +35,7 @@ #include "Op/MaxPool.h" #include "Op/Mul.h" #include "Op/Pad.h" +#include "Op/ReduceMean.h" #include "Op/Relu.h" #include "Op/Reshape.h" #include "Op/Shape.h" @@ -69,6 +70,7 @@ inline void registerSupportedOps() registry.registerConverter("MaxPool", stdex::make_unique()); registry.registerConverter("Mul", stdex::make_unique()); registry.registerConverter("Pad", stdex::make_unique()); + registry.registerConverter("ReduceMean", stdex::make_unique()); registry.registerConverter("Relu", stdex::make_unique()); registry.registerConverter("Reshape", stdex::make_unique()); registry.registerConverter("Shape", stdex::make_unique()); diff --git a/compiler/mir-onnx-importer/Op/ReduceMean.cpp b/compiler/mir-onnx-importer/Op/ReduceMean.cpp new file mode 100644 index 0000000..28065ce --- /dev/null +++ b/compiler/mir-onnx-importer/Op/ReduceMean.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ReduceMean.h" + +#include "ONNXHelpers.h" +#include "AttributeHelpers.h" + +#include "mir/ops/ReduceOp.h" + +#include + +namespace mir_onnx +{ + +void ReduceMeanNodeConverter::convert(const onnx::NodeProto &onnx_node, + ConverterContext *context) const +{ + const auto opset_version = context->getOpsetVersion(onnx_node.domain()); + + if (opset_version >= 1) + convertV1(onnx_node, context); + else + throw std::runtime_error("Not supported opset version on ReduceMean operation!"); +} + +void ReduceMeanNodeConverter::convertV1(const onnx::NodeProto &onnx_node, + ConverterContext *context) const +{ + const auto inputs = context->getNodeInputs(onnx_node); + assert(inputs.size() == 1); + + const auto axes = getAttributeValue>(onnx_node, "axes"); + const auto keepdims = getAttributeValue(onnx_node, "keepdims", 1); + + std::vector reduce_dims; + if (axes.empty()) + { // reduce over all dimensions + reduce_dims.resize(inputs[0]->getShape().rank()); + std::iota(reduce_dims.begin(), reduce_dims.end(), 0); + } + else + { + reduce_dims.resize(axes.size()); + std::copy(axes.begin(), axes.end(), reduce_dims.begin()); + } + // Keep the reduced dimension or not, default 1 mean keep reduced dimension. + bool keep_dims = static_cast(keepdims); + + mir::Graph *graph = context->getGraph(); + auto result = createOp(graph, inputs[0], reduce_dims, keep_dims, + mir::ops::ReduceOp::FuncType::mean) + ->getOutput(0); + + context->setNodeOutputs(onnx_node, {result}); +} + +} // namespace mir_onnx diff --git a/compiler/mir-onnx-importer/Op/ReduceMean.h b/compiler/mir-onnx-importer/Op/ReduceMean.h new file mode 100644 index 0000000..f03903a --- /dev/null +++ b/compiler/mir-onnx-importer/Op/ReduceMean.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MIR_ONNX_OP_REDUCEMEAN_H +#define MIR_ONNX_OP_REDUCEMEAN_H + +#include "ONNXNodeConverterRegistry.h" + +namespace mir_onnx +{ + +class ReduceMeanNodeConverter : public NodeConverter +{ +public: + void convert(const onnx::NodeProto &onnx_node, ConverterContext *context) const override; + +private: + void convertV1(const onnx::NodeProto &onnx_node, ConverterContext *context) const; +}; + +} // namespace mir_onnx + +#endif // MIR_ONNX_OP_REDUCEMEAN_H -- 2.7.4