From 5475964f0c5d6b25c9fa857060693328801e5b5b Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9C=A4=ED=98=84=EC=8B=9D/On-Device=20Lab=28SR=29/Princip?= =?utf8?q?al=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 16 Oct 2019 16:48:10 +0900 Subject: [PATCH] [exo] Introducing FuseReluPass (#8176) * [exo] Introducing FuseReluPass This introduces FuseReluPass, which fuse relu/relu6 into 10 TensorFlow Lite ops. This commit adds code that finds candidate subgraph. Signed-off-by: Hyun Sik Yoon * remove unused var (to avoid CI error) * Update compiler/exo/src/Pass/FuseReluPass.h Co-Authored-By: hyunsik-yoon --- compiler/exo/src/Pass/FuseReluPass.cpp | 91 ++++++++++++++++++++++++++++++++++ compiler/exo/src/Pass/FuseReluPass.h | 40 +++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 compiler/exo/src/Pass/FuseReluPass.cpp create mode 100644 compiler/exo/src/Pass/FuseReluPass.h diff --git a/compiler/exo/src/Pass/FuseReluPass.cpp b/compiler/exo/src/Pass/FuseReluPass.cpp new file mode 100644 index 0000000..b07e962 --- /dev/null +++ b/compiler/exo/src/Pass/FuseReluPass.cpp @@ -0,0 +1,91 @@ +/* + * 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 "FuseReluPass.h" + +#include "Dialect/IR/TFLNodes.h" +#include "Dialect/IR/TFLDialect.h" +#include "Dialect/IR/TFLNodeVisitor.h" + +#include + +#include + +namespace +{ + +bool is_pred_fusable(loco::Node *node) +{ + using namespace locoex; + + auto add = dynamic_cast(node); + auto avgpool = dynamic_cast(node); + auto conv = dynamic_cast(node); + auto maxpool = dynamic_cast(node); + auto mul = dynamic_cast(node); + + return (add and add->fusedActivationFunction() == FusedActFunc::NONE) or + (avgpool and avgpool->fusedActivationFunction() == FusedActFunc::NONE) or + (conv and conv->fusedActivationFunction() == FusedActFunc::NONE) or + (maxpool and maxpool->fusedActivationFunction() == FusedActFunc::NONE) or + (mul and mul->fusedActivationFunction() == FusedActFunc::NONE); + // TODO Consider adding CONCATENATION, DEPTHWISE_CONV_2D, FULLY_CONNECTED, + // TODO L2_NORMALIZATION, TODO L2_POOL_2D +}; + +struct Collector final : public locoex::TFLNodeMutableVisitor +{ + void visit(locoex::TFLRelu *node) final + { + if (is_pred_fusable(node->features())) + candidates.insert(node); + } + + void visit(locoex::TFLRelu6 *node) final + { + if (is_pred_fusable(node->features())) + candidates.insert(node); + } + + void visit(locoex::TFLNode *) final { return; } + + std::set candidates; +}; + +} // namespace + +namespace exo +{ + +bool FuseReluPass::run(loco::Graph *g) +{ + Collector collector; + + for (auto node : loco::active_nodes(loco::output_nodes(g))) + { + if (node->dialect() == locoex::TFLDialect::get()) + { + auto tfl_node = dynamic_cast(node); + tfl_node->accept(&collector); + } + } + + // TODO write code for fusing + + return false; +} + +} // namespace exo diff --git a/compiler/exo/src/Pass/FuseReluPass.h b/compiler/exo/src/Pass/FuseReluPass.h new file mode 100644 index 0000000..1cd276b --- /dev/null +++ b/compiler/exo/src/Pass/FuseReluPass.h @@ -0,0 +1,40 @@ +/* + * 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 __PASS_FUSE_RELU_PASS_H__ +#define __PASS_FUSE_RELU_PASS_H__ + +#include + +namespace exo +{ + +/** + * @brief Class to fuse TFLRelu or TFLRelu6 into the TensorFlow Lite ops below: + * + * ADD, AVERAGE_POOL_2D, CONCATENATION, CONV_2D, DEPTHWISE_CONV_2D, + * FULLY_CONNECTED, L2_NORMALIZATION, L2_POOL_2D, MAX_POOL_2D, MUL + */ +struct FuseReluPass final : public logo::Pass +{ + const char *name(void) const final { return "exo::FuseReluPass"; } + + bool run(loco::Graph *g) final; +}; + +} // namespace exo + +#endif // __PASS_FUSE_RELU_PASS_H__ -- 2.7.4