[exo] Add fusedActivationFunction to TFLAdd and TFLMul (#8161)
author윤현식/On-Device Lab(SR)/Principal Engineer/삼성전자 <hyunsik.yoon@samsung.com>
Tue, 15 Oct 2019 07:42:59 +0000 (16:42 +0900)
committer박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 15 Oct 2019 07:42:59 +0000 (16:42 +0900)
* [exo] Add fusedActivationFunction to TFLAdd and TFLMul

TFLAdd and TFLMul now has an attribute for fusedActivationFunction.

Signed-off-by: Hyun Sik Yoon <hyunsik.yoon@samsung.com>
* Modify circle exporter

* remove unused param

* defined and used init_fused_act_func

* remove constructor. init member vars directly

compiler/exo/src/Circle/CircleOperationExporter.cpp
compiler/exo/src/Conversion/EltwiseBinaryConverter.h
compiler/exo/src/Conversion/FeatureBiasAddConverter.cpp
compiler/exo/src/Dialect/IR/TFLNodes.h
compiler/exo/src/TFLFormattedGraph.cpp
compiler/exo/src/TFLite/TFLOperationExporter.cpp

index 97aebf9..f116443 100644 (file)
@@ -122,7 +122,7 @@ void OperationExporter::visit(locoex::TFLAdd *node)
   std::vector<int32_t> outputs_vec{get_tensor_index(static_cast<loco::Node *>(node))};
   auto inputs = builder.CreateVector(inputs_vec);
   auto outputs = builder.CreateVector(outputs_vec);
-  auto options = CreateAddOptions(builder); // dummy option
+  auto options = CreateAddOptions(builder, to_circle_actfunc(node->fusedActivationFunction()));
   auto op_offset = CreateOperator(builder, op_idx, inputs, outputs,
                                   circle::BuiltinOptions_AddOptions, options.Union());
   gd._operators.push_back(op_offset);
@@ -182,7 +182,7 @@ void OperationExporter::visit(locoex::TFLMul *node)
   std::vector<int32_t> outputs_vec{get_tensor_index(static_cast<loco::Node *>(node))};
   auto inputs = builder.CreateVector(inputs_vec);
   auto outputs = builder.CreateVector(outputs_vec);
-  auto options = CreateMulOptions(builder); // dummy option
+  auto options = CreateMulOptions(builder, to_circle_actfunc(node->fusedActivationFunction()));
   auto op_offset = CreateOperator(builder, op_idx, inputs, outputs,
                                   circle::BuiltinOptions_MulOptions, options.Union());
   gd._operators.push_back(op_offset);
index aea564d..71447de 100644 (file)
 
 #include <loco/Service/ShapeInference.h>
 
+namespace
+{
+
+template <class TFLBIN> void init_fused_act_func(TFLBIN *);
+
+template <> inline void init_fused_act_func(locoex::TFLAdd *node)
+{
+  node->fusedActivationFunction(locoex::FusedActFunc::NONE);
+}
+
+template <> inline void init_fused_act_func(locoex::TFLMul *node)
+{
+  node->fusedActivationFunction(locoex::FusedActFunc::NONE);
+}
+
+template <> inline void init_fused_act_func(locoex::TFLSub *)
+{
+  /* TFLSub does not have fused activation function. Thus, nothing to do */
+}
+
+template <> inline void init_fused_act_func(locoex::TFLDiv *)
+{
+  /* TFLDic does not have fused activation function. Thus, nothing to do */
+}
+
+} // namespace
+
 namespace exo
 {
 
@@ -46,6 +73,8 @@ template <class ELTWISEBIN, class TFLBIN> bool EltwiseBinaryConvert(ELTWISEBIN *
     origin->lhs(nullptr);
     origin->rhs(nullptr);
 
+    init_fused_act_func(tfl_bin);
+
     return true;
   }
   else if (loco::shape_get(origin).domain() == loco::Domain::Feature)
@@ -76,6 +105,8 @@ template <class ELTWISEBIN, class TFLBIN> bool EltwiseBinaryConvert(ELTWISEBIN *
     origin->lhs(nullptr);
     origin->rhs(nullptr);
 
+    init_fused_act_func(tfl_new);
+
     return true;
   }
   else
index 07d93ed..b9aaf14 100644 (file)
 
 #include <cassert>
 
+namespace
+{
+
+inline void init_fused_act_func(locoex::TFLAdd *node)
+{
+  node->fusedActivationFunction(locoex::FusedActFunc::NONE);
+}
+
+} // namespace
+
 namespace exo
 {
 
@@ -66,6 +76,9 @@ bool FeatureBiasAddConverter::convert(loco::FeatureBiasAdd *origin)
 
   tfl_add->y(bias_dec);
 
+  // fused activation function
+  init_fused_act_func(tfl_add);
+
   // handling output
   auto fea_enc = make_feature_encode<FeatureLayout::NHWC>(tfl_add);
 
index 1796418..3a57e57 100644 (file)
@@ -119,14 +119,17 @@ private:
 class TFLAdd final : public FixedArityNode<2, TFLNodeImpl<TFLOpcode::ADD>>
 {
 public:
-  TFLAdd() = default;
-
-public:
   loco::Node *x(void) const { return at(0)->node(); }
   void x(loco::Node *node) { at(0)->node(node); }
 
   loco::Node *y(void) const { return at(1)->node(); }
   void y(loco::Node *node) { at(1)->node(node); }
+
+  FusedActFunc fusedActivationFunction() const { return _fused_act_fun; }
+  void fusedActivationFunction(FusedActFunc fused_act_fun) { _fused_act_fun = fused_act_fun; }
+
+private:
+  FusedActFunc _fused_act_fun = FusedActFunc::UNDEFINED;
 };
 
 /**
@@ -271,14 +274,17 @@ private:
 class TFLMul final : public FixedArityNode<2, TFLNodeImpl<TFLOpcode::MUL>>
 {
 public:
-  TFLMul() = default;
-
-public:
   loco::Node *x(void) const { return at(0)->node(); }
   void x(loco::Node *node) { at(0)->node(node); }
 
   loco::Node *y(void) const { return at(1)->node(); }
   void y(loco::Node *node) { at(1)->node(node); }
+
+  FusedActFunc fusedActivationFunction() const { return _fused_act_fun; }
+  void fusedActivationFunction(FusedActFunc fused_act_fun) { _fused_act_fun = fused_act_fun; }
+
+private:
+  FusedActFunc _fused_act_fun = FusedActFunc::UNDEFINED;
 };
 
 class TFLRelu final : public FixedArityNode<1, TFLNodeImpl<TFLOpcode::RELU>>
index b1241de..012c137 100644 (file)
@@ -151,8 +151,12 @@ bool TFLNodeSummaryBuilderBase::build(const loco::Node *node, locop::NodeSummary
 
 bool TFLNodeSummaryBuilder::summary(const locoex::TFLAdd *node, locop::NodeSummary &s) const
 {
+  auto fused = node->fusedActivationFunction();
+  assert(fused != locoex::FusedActFunc::UNDEFINED);
+
   s.args().append("x", tbl()->lookup(node->x()));
   s.args().append("y", tbl()->lookup(node->y()));
+  s.args().append("fused_activation_function", to_str(node->fusedActivationFunction()));
   s.state(locop::NodeSummary::State::Complete);
   return true;
 }
@@ -229,8 +233,12 @@ bool TFLNodeSummaryBuilder::summary(const locoex::TFLMaxPool2D *node, locop::Nod
 
 bool TFLNodeSummaryBuilder::summary(const locoex::TFLMul *node, locop::NodeSummary &s) const
 {
+  auto fused = node->fusedActivationFunction();
+  assert(fused != locoex::FusedActFunc::UNDEFINED);
+
   s.args().append("x", tbl()->lookup(node->x()));
   s.args().append("y", tbl()->lookup(node->y()));
+  s.args().append("fused_activation_function", to_str(node->fusedActivationFunction()));
   s.state(locop::NodeSummary::State::Complete);
   return true;
 }
index bed14bf..bc4b564 100644 (file)
@@ -122,7 +122,7 @@ void OperationExporter::visit(locoex::TFLAdd *node)
   std::vector<int32_t> outputs_vec{get_tensor_index(static_cast<loco::Node *>(node))};
   auto inputs = builder.CreateVector(inputs_vec);
   auto outputs = builder.CreateVector(outputs_vec);
-  auto options = CreateAddOptions(builder); // dummy option
+  auto options = CreateAddOptions(builder, to_tflite_actfunc(node->fusedActivationFunction()));
   auto op_offset = CreateOperator(builder, op_idx, inputs, outputs,
                                   tflite::BuiltinOptions_AddOptions, options.Union());
   gd._operators.push_back(op_offset);
@@ -182,7 +182,7 @@ void OperationExporter::visit(locoex::TFLMul *node)
   std::vector<int32_t> outputs_vec{get_tensor_index(static_cast<loco::Node *>(node))};
   auto inputs = builder.CreateVector(inputs_vec);
   auto outputs = builder.CreateVector(outputs_vec);
-  auto options = CreateMulOptions(builder); // dummy option
+  auto options = CreateMulOptions(builder, to_tflite_actfunc(node->fusedActivationFunction()));
   auto op_offset = CreateOperator(builder, op_idx, inputs, outputs,
                                   tflite::BuiltinOptions_MulOptions, options.Union());
   gd._operators.push_back(op_offset);