[enco] Add ann backend for Sub (#2711)
author윤지영/On-Device Lab(SR)/Engineer/삼성전자 <jy910.yun@samsung.com>
Tue, 18 Dec 2018 07:11:41 +0000 (16:11 +0900)
committer박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 18 Dec 2018 07:11:41 +0000 (16:11 +0900)
This commit will add the ann backend of enco for Sub.

Signed-off-by: Jiyoung Yun <jy910.yun@samsung.com>
contrib/enco/core/src/ANN/IR/Operation.def
contrib/enco/core/src/Transforms/Split.cpp

index 693377e..8e345d9 100644 (file)
@@ -13,3 +13,4 @@ ANN_OPERATION(RELU, ANEURALNETWORKS_RELU)
 ANN_OPERATION(RELU6, ANEURALNETWORKS_RELU6)
 ANN_OPERATION(PAD, ANEURALNETWORKS_PAD)
 ANN_OPERATION(CONCAT, ANEURALNETWORKS_CONCATENATION)
+ANN_OPERATION(SUB, ANEURALNETWORKS_SUB)
index 7d55a47..53cea7f 100644 (file)
@@ -576,6 +576,32 @@ private:
   Appender _fun;
 };
 
+class ANNSubAppender 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::SUB, {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:
@@ -833,6 +859,33 @@ public:
         return std::move(app);
       }
     }
+    else if (auto op = eval->op()->asSub())
+    {
+      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(Sub(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<ANNSubAppender>();
+
+        app->left(left);
+        app->right(right);
+        app->out(out);
+
+        return std::move(app);
+      }
+    }
 
     // Return nullptr if a given Eval instruction is incompatible
     return nullptr;