[enco] Support Div for ANN backend (#2792)
author박천교/On-Device Lab(SR)/Engineer/삼성전자 <ch.bahk@samsung.com>
Wed, 9 Jan 2019 08:42:12 +0000 (17:42 +0900)
committer박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Wed, 9 Jan 2019 08:42:12 +0000 (17:42 +0900)
* [enco] Support Div for ANN backend

This commit enables ANN backend generation for Div operation

Signed-off-by: Cheongyo Bahk <ch.bahk@samsung.com>
* Remove irrelavant modification in 'Debugging.cpp'

contrib/enco/core/src/ANN/IR/Operation.def
contrib/enco/core/src/Transforms/Split.cpp

index 8e345d9..68fd394 100644 (file)
@@ -14,3 +14,4 @@ ANN_OPERATION(RELU6, ANEURALNETWORKS_RELU6)
 ANN_OPERATION(PAD, ANEURALNETWORKS_PAD)
 ANN_OPERATION(CONCAT, ANEURALNETWORKS_CONCATENATION)
 ANN_OPERATION(SUB, ANEURALNETWORKS_SUB)
+ANN_OPERATION(DIV, ANEURALNETWORKS_DIV)
index 53cea7f..6f9b297 100644 (file)
@@ -602,6 +602,32 @@ private:
   coco::FeatureObject *_out = nullptr;
 };
 
+class ANNDivAppender final : public ANNOpAppender
+{
+public:
+  void left(coco::FeatureObject *o) { _left = o; }
+  void right(coco::FeatureObject *o) { _right = o; }
+  void out(coco::FeatureObject *o) { _out = o; }
+
+public:
+  void append(ANNBinder *binder) const override
+  {
+    auto left = binder->addOperand<float>(_left);
+    auto right = binder->addOperand<float>(_right);
+    auto fuse = binder->addOperand<int32_t>();
+    binder->setOperand(fuse, 0);
+
+    auto out = binder->addOperand<float>(_out);
+
+    binder->addOperation(ann::Operation::Code::DIV, {left, right, fuse}, {out});
+  }
+
+private:
+  coco::FeatureObject *_left = nullptr;
+  coco::FeatureObject *_right = nullptr;
+  coco::FeatureObject *_out = nullptr;
+};
+
 class ANNOpBuilder : public coco::Instr::Visitor<std::unique_ptr<ANNOpAppender>>
 {
 public:
@@ -886,6 +912,33 @@ public:
         return std::move(app);
       }
     }
+    else if (auto op = eval->op()->asDiv())
+    {
+      auto left_load = op->left()->asLoad();
+      auto right_load = op->right()->asLoad();
+
+      if (left_load && right_load)
+      {
+        // Let's compile the following code fragment:
+        //
+        //   %out = eval(Div(Load(%left), Load(%right)))
+        //
+        auto left = left_load->object()->asFeature();
+        auto right = right_load->object()->asFeature();
+        assert(left != nullptr && right != nullptr);
+
+        auto out = eval->out()->asFeature();
+        assert(out != nullptr);
+
+        auto app = make_unique<ANNDivAppender>();
+
+        app->left(left);
+        app->right(right);
+        app->out(out);
+
+        return std::move(app);
+      }
+    }
 
     // Return nullptr if a given Eval instruction is incompatible
     return nullptr;