[mir2loco] Replace BiasAdd and Scale with Elementwise equivalents (#6296)
authorСергей Баранников/AI Tools Lab /SRR/Engineer/삼성전자 <s.barannikov@samsung.com>
Tue, 6 Aug 2019 17:07:39 +0000 (20:07 +0300)
committerAlexander Efimov/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Tue, 6 Aug 2019 17:07:39 +0000 (20:07 +0300)
`BiasAdd` and `Scale` are restricted versions of equivalent Elementwise ops and are going to be removed.

Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
compiler/mir2loco/include/mir2loco.h
compiler/mir2loco/src/mir2loco.cpp
compiler/mir2loco/src/mir2loco.test.cpp

index 795c424..469de9f 100644 (file)
@@ -27,7 +27,6 @@ public:
   ~Transformer() = default;
 
   void visit(mir::ops::BatchNormOp &op) override;
-  void visit(mir::ops::BiasAddOp &op) override;
   void visit(mir::ops::CappedReluOp &op) override;
   void visit(mir::ops::ConcatOp &op) override;
   void visit(mir::ops::ConstantOp &op) override;
@@ -49,7 +48,6 @@ public:
   void visit(mir::ops::ReluOp &op) override;
   void visit(mir::ops::ReshapeOp &op) override;
   void visit(mir::ops::ResizeOp &op) override;
-  void visit(mir::ops::ScaleOp &op) override;
   void visit(mir::ops::SigmoidOp &op) override;
   void visit(mir::ops::SliceOp &op) override;
   void visit(mir::ops::SoftmaxOp &op) override;
index cea9a12..57b49f5 100644 (file)
 
 #include "mir2loco.h"
 
-#include "mir/ops/BiasAddOp.h"
 #include "mir/ops/ConcatOp.h"
 #include "mir/ops/ConstantOp.h"
 #include "mir/ops/Conv2DOp.h"
+#include "mir/ops/ElementwiseOp.h"
 #include "mir/ops/PoolOp.h"
 #include "mir/ops/ReluOp.h"
 #include "mir/ops/ReshapeOp.h"
@@ -124,27 +124,6 @@ loco::DataType ConvertDataType(mir::DataType data_type)
 
 void Transformer::visit(mir::ops::BatchNormOp &op) { throw std::runtime_error("NYI"); }
 
-void Transformer::visit(mir::ops::BiasAddOp &op)
-{
-  // Set Input
-  auto input = op.getInput(0)->getProducer()->getNode();
-  auto bias = op.getInput(1)->getProducer()->getNode();
-  auto loco_input = _mir2loco_map.at(input);
-  auto loco_bias = _mir2loco_map.at(bias);
-  // Create BiasEncode
-  auto bias_encode = _loco_graph->nodes()->create<loco::BiasEncode>();
-  bias_encode->input(loco_bias);
-  // Set value and bias
-  auto bias_add_node = _loco_graph->nodes()->create<loco::TensorBiasAdd>();
-  bias_add_node->value(loco_input);
-  bias_add_node->bias(bias_encode);
-  // Set axis
-  bias_add_node->axis(3); // NHWC
-  // Not set Shape
-  // Add to map
-  _mir2loco_map.emplace(&op, bias_add_node);
-}
-
 void Transformer::visit(mir::ops::CappedReluOp &op) { throw std::runtime_error("NYI"); }
 
 void Transformer::visit(mir::ops::ConcatOp &op)
@@ -254,7 +233,35 @@ void Transformer::visit(mir::ops::DepthwiseConv2DOp &op) { throw std::runtime_er
 
 void Transformer::visit(mir::ops::DropoutOp &op) { throw std::runtime_error("NYI"); }
 
-void Transformer::visit(mir::ops::ElementwiseOp &op) { throw std::runtime_error("NYI"); }
+void Transformer::visit(mir::ops::ElementwiseOp &op)
+{
+  // TODO Currently, MIR supports arbitrary number of inputs (>= 2).
+  if (op.getNumInputs() != 2)
+    throw std::runtime_error("NYI");
+
+  // Get Input
+  auto lhs = _mir2loco_map.at(op.getInput(0)->getProducer()->getNode());
+  auto rhs = _mir2loco_map.at(op.getInput(1)->getProducer()->getNode());
+  loco::Node *result = nullptr;
+  switch (op.getOpType())
+  {
+    case mir::ops::ElementwiseOp::OpType::add:
+    {
+      auto add_node = _loco_graph->nodes()->create<loco::EltwiseAdd>();
+      add_node->lhs(lhs);
+      add_node->rhs(rhs);
+      result = add_node;
+      break;
+    }
+    default:
+    {
+      throw std::runtime_error("NYI");
+    }
+  }
+  // Not set Shape
+  // Add to map
+  _mir2loco_map.emplace(&op, result);
+}
 
 void Transformer::visit(mir::ops::EluOp &op) { throw std::runtime_error("NYI"); }
 
@@ -389,8 +396,6 @@ void Transformer::visit(mir::ops::ReshapeOp &op)
 
 void Transformer::visit(mir::ops::ResizeOp &op) { throw std::runtime_error("NYI"); }
 
-void Transformer::visit(mir::ops::ScaleOp &op) { throw std::runtime_error("NYI"); }
-
 void Transformer::visit(mir::ops::SigmoidOp &op) { throw std::runtime_error("NYI"); }
 
 void Transformer::visit(mir::ops::SliceOp &op) { throw std::runtime_error("NYI"); }
index cd732be..824299f 100644 (file)
 
 #include "mir2loco.h"
 
-#include "mir/ops/BiasAddOp.h"
 #include "mir/ops/ConcatOp.h"
 #include "mir/ops/ConstantOp.h"
 #include "mir/ops/Conv2DOp.h"
+#include "mir/ops/ElementwiseOp.h"
 #include "mir/ops/PoolOp.h"
 #include "mir/ops/ReluOp.h"
 #include "mir/ops/ReshapeOp.h"
@@ -280,38 +280,36 @@ TEST_F(TestTransformer_mir2loco, Const_Float_Test)
     ASSERT_FLOAT_EQ(const_node->at<loco::DataType::FLOAT32>(i), data[i]);
 }
 
-TEST_F(TestTransformer_mir2loco, Bias_Add_Test)
+TEST_F(TestTransformer_mir2loco, Add_Test)
 {
   mir::Graph mir_graph;
 
   mir::Shape input_shape{5, 6, 7, 3};
-  mir::Shape bias_shape{3};
-  auto *input = mir_graph.create<mir::ops::InputOp>("input", input_shape);
-  auto *bias = mir_graph.create<mir::ops::InputOp>("bias", bias_shape);
-  auto *bias_add =
-      mir_graph.create<mir::ops::BiasAddOp>("bias_add", input->getOutput(0), bias->getOutput(0));
-  auto *output = mir_graph.create<mir::ops::OutputOp>("output", bias_add->getOutput(0));
+
+  auto *input1 = mir_graph.create<mir::ops::InputOp>("input1", input_shape);
+  auto *input2 = mir_graph.create<mir::ops::InputOp>("input2", input_shape);
+  auto *add = mir_graph.create<mir::ops::ElementwiseOp>(
+      "bias_add", std::vector<mir::Operation::Output *>{input1->getOutput(0), input2->getOutput(0)},
+      mir::ops::ElementwiseOp::OpType::add);
+  auto *output = mir_graph.create<mir::ops::OutputOp>("output", add->getOutput(0));
 
   mir2loco::Transformer transformer;
   auto loco_graph = transformer.transform(&mir_graph);
 
-  loco::Pull *pull1_node = dynamic_cast<loco::Pull *>(loco_graph->nodes()->at(0));
-  loco::Pull *pull2_node = dynamic_cast<loco::Pull *>(loco_graph->nodes()->at(1));
-  loco::BiasEncode *bias_enc_node = dynamic_cast<loco::BiasEncode *>(loco_graph->nodes()->at(2));
-  loco::TensorBiasAdd *bias_add_node =
-      dynamic_cast<loco::TensorBiasAdd *>(loco_graph->nodes()->at(3));
-  loco::Push *push_node = dynamic_cast<loco::Push *>(loco_graph->nodes()->at(4));
+  auto *pull1_node = dynamic_cast<loco::Pull *>(loco_graph->nodes()->at(0));
+  auto *pull2_node = dynamic_cast<loco::Pull *>(loco_graph->nodes()->at(1));
+  auto *add_node = dynamic_cast<loco::EltwiseAdd *>(loco_graph->nodes()->at(2));
+  auto *push_node = dynamic_cast<loco::Push *>(loco_graph->nodes()->at(3));
 
   ASSERT_NE(pull1_node, nullptr);
   ASSERT_NE(pull2_node, nullptr);
-  ASSERT_NE(bias_enc_node, nullptr);
-  ASSERT_NE(bias_add_node, nullptr);
+  ASSERT_NE(add_node, nullptr);
   ASSERT_NE(push_node, nullptr);
 
-  ASSERT_EQ(bias_enc_node->input(), pull2_node);
-  ASSERT_EQ(bias_add_node->value(), pull1_node);
-  ASSERT_EQ(bias_add_node->bias(), bias_enc_node);
-  ASSERT_EQ(push_node->from(), bias_add_node);
+  ASSERT_EQ(add_node->lhs(), pull1_node);
+  ASSERT_EQ(add_node->rhs(), pull2_node);
+  ASSERT_EQ(push_node->from(), add_node);
+
   // Shape check
   ASSERT_EQ(pull1_node->rank(), 4);
   ASSERT_EQ(pull1_node->dim(0), 5);
@@ -319,10 +317,11 @@ TEST_F(TestTransformer_mir2loco, Bias_Add_Test)
   ASSERT_EQ(pull1_node->dim(2), 7);
   ASSERT_EQ(pull1_node->dim(3), 3);
 
-  ASSERT_EQ(pull2_node->rank(), 1);
-  ASSERT_EQ(pull2_node->dim(0), 3);
-
-  ASSERT_EQ(bias_add_node->axis(), 3);
+  ASSERT_EQ(pull2_node->rank(), 4);
+  ASSERT_EQ(pull2_node->dim(0), 5);
+  ASSERT_EQ(pull2_node->dim(1), 6);
+  ASSERT_EQ(pull2_node->dim(2), 7);
+  ASSERT_EQ(pull2_node->dim(3), 3);
 }
 
 TEST_F(TestTransformer_mir2loco, Conv2D_Test)