[enco] Extend frontend for ReLU (#2298)
author남궁석/동작제어Lab(SR)/Engineer/삼성전자 <sk.namkoong@samsung.com>
Thu, 15 Nov 2018 02:03:40 +0000 (11:03 +0900)
committer박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Thu, 15 Nov 2018 02:03:40 +0000 (11:03 +0900)
This commit will extend the frontend of enco for ReLU

Signed-off-by: Seok NamKoong <sk.namkoong@samsung.com>
contrib/enco/frontend/tflite/src/Frontend.cpp
contrib/enco/test/tflite/ReLU_000/INFERENCE [new file with mode: 0644]
contrib/enco/test/tflite/ReLU_000/test.recipe [new file with mode: 0644]

index 4ea2e4c..a907469 100644 (file)
@@ -867,6 +867,67 @@ void ConcatenationGraphBuilder::build(const tflite::Operator *op,
 }
 
 /**
+ * @brief GraphBuilder for ReLU operator
+ */
+class ReLUGraphBuilder : public GraphBuilder
+{
+public:
+  void build(const tflite::Operator *op, GraphBuilderContext *) const override;
+};
+
+void ReLUGraphBuilder::build(const tflite::Operator *op, GraphBuilderContext *context) const
+{
+  assert(context != nullptr); // check if init(..) is called
+
+  coco::Module *m = context->m();
+  coco::Block *blk = context->block();
+  TensorContext &tensor_context = context->tensor();
+  TensorBags &bags = context->bags();
+
+  tflimport::IndexVector opinputs = tflimport::as_index_vector(op->inputs());
+  tflimport::IndexVector opoutputs = tflimport::as_index_vector(op->outputs());
+
+  // these are fixed in tflite
+  // input index 0 : input feature
+  // ouout index 0 : output feature
+  assert(opinputs.size() == 1);
+  assert(opoutputs.size() == 1);
+
+  auto ifm_idx = opinputs.at(0);
+  auto ofm_idx = opoutputs.at(0);
+
+  const tensor::Shape &ifm_shape = tensor_context.shape(ifm_idx);
+  const tensor::Shape &ofm_shape = tensor_context.shape(ofm_idx);
+
+  // Create an object for an input feature map
+  coco::FeatureObject *ifm_obj = m->entity()->object()->create<coco::FeatureObject>();
+  coco::Bag *ifm_bag = bags.bag(ifm_idx);
+  ifm_obj->bag(ifm_bag);
+  ifm_obj->layout(coco::FeatureLayouts::BHWC::create(as_feature_shape(ifm_shape)));
+
+  // Create an object for an output feature map
+  coco::FeatureObject *ofm_obj = m->entity()->object()->create<coco::FeatureObject>();
+  coco::Bag *ofm_bag = bags.bag(ofm_idx);
+  ofm_obj->bag(ofm_bag);
+  ofm_obj->layout(coco::FeatureLayouts::BHWC::create(as_feature_shape(ofm_shape)));
+
+  // Create a Load op
+  auto coco_load = op_builder(m).load(ifm_obj).pop();
+
+  // Create a ReLU
+  auto coco_relu = m->entity()->op()->create<coco::ReLU>();
+
+  // Link ops
+  coco_relu->arg(coco_load);
+
+  // Create an Eval instruction
+  auto eval_ins = instr_builder(m).eval(ofm_obj, coco_relu);
+
+  // Append the instruction to the block
+  blk->instr()->append(eval_ins);
+}
+
+/**
  * @brief GraphBuilder for ReLU6 operator
  */
 class ReLU6GraphBuilder : public GraphBuilder
@@ -1020,6 +1081,7 @@ private:
     _builder_map[tflite::BuiltinOperator_AVERAGE_POOL_2D] = make_unique<AvgPool2DGraphBuilder>();
     _builder_map[tflite::BuiltinOperator_MAX_POOL_2D] = make_unique<MaxPool2DGraphBuilder>();
     _builder_map[tflite::BuiltinOperator_CONCATENATION] = make_unique<ConcatenationGraphBuilder>();
+    _builder_map[tflite::BuiltinOperator_RELU] = make_unique<ReLUGraphBuilder>();
     _builder_map[tflite::BuiltinOperator_RELU6] = make_unique<ReLU6GraphBuilder>();
     _builder_map[tflite::BuiltinOperator_RESHAPE] = make_unique<ReshapeGraphBuilder>();
   }
diff --git a/contrib/enco/test/tflite/ReLU_000/INFERENCE b/contrib/enco/test/tflite/ReLU_000/INFERENCE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/contrib/enco/test/tflite/ReLU_000/test.recipe b/contrib/enco/test/tflite/ReLU_000/test.recipe
new file mode 100644 (file)
index 0000000..8eaa360
--- /dev/null
@@ -0,0 +1,17 @@
+operand {
+  name: "ifm"
+  type: FLOAT32
+  shape { dim: 1 dim: 3 dim: 3 dim: 2 }
+}
+operand {
+  name: "ofm"
+  type: FLOAT32
+  shape { dim: 1 dim: 3 dim: 3 dim: 2 }
+}
+operation {
+  type: "ReLU"
+  input: "ifm"
+  output: "ofm"
+}
+input: "ifm"
+output: "ofm"