[mir_caffe2] Replace BiasAdd and Scale with Elementwise equivalents (#6293)
authorСергей Баранников/AI Tools Lab /SRR/Engineer/삼성전자 <s.barannikov@samsung.com>
Tue, 6 Aug 2019 16:50:14 +0000 (19:50 +0300)
committerAlexander Efimov/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Tue, 6 Aug 2019 16:50:14 +0000 (19:50 +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/mir-caffe2-importer/caffe2_op_creator.cpp
compiler/mir-caffe2-importer/caffe2_op_creator.h

index 3b3d9ec..2170470 100644 (file)
@@ -18,7 +18,6 @@
 #include "caffe2_proto_helper.h"
 
 #include "mir/ops/BatchNormOp.h"
-#include "mir/ops/BiasAddOp.h"
 #include "mir/ops/CappedReluOp.h"
 #include "mir/ops/ConcatOp.h"
 #include "mir/ops/ConstantOp.h"
@@ -32,7 +31,6 @@
 #include "mir/ops/ReluOp.h"
 #include "mir/ops/ReshapeOp.h"
 #include "mir/ops/ResizeOp.h"
-#include "mir/ops/ScaleOp.h"
 #include "mir/ops/SigmoidOp.h"
 #include "mir/ops/SoftmaxOp.h"
 #include "mir/ops/TransposeOp.h"
@@ -233,6 +231,24 @@ mir::Operation::Output *Caffe2OpCreator::convertMIRToCaffe(mir::Operation::Outpu
   return transpose->getOutput(0);
 }
 
+mir::Operation::Output *Caffe2OpCreator::createAdd(const std::string &name,
+                                                   mir::Operation::Output *arg1,
+                                                   mir::Operation::Output *arg2)
+{
+  std::vector<mir::Operation::Output *> inputs{arg1, arg2};
+  auto op = createOp<ops::ElementwiseOp>(name, inputs, ops::ElementwiseOp::OpType::add);
+  return op->getOutput(0);
+}
+
+mir::Operation::Output *Caffe2OpCreator::createMul(const std::string &name,
+                                                   mir::Operation::Output *arg1,
+                                                   mir::Operation::Output *arg2)
+{
+  std::vector<mir::Operation::Output *> inputs{arg1, arg2};
+  auto op = createOp<ops::ElementwiseOp>(name, inputs, ops::ElementwiseOp::OpType::mul);
+  return op->getOutput(0);
+}
+
 //
 // Check functions
 //
@@ -388,14 +404,15 @@ Caffe2OpCreator::convertConv(const std::vector<mir::Operation::Output *> &inputs
   int num_groups = getSingleArgument(op, "group", 1);
   bool is_depthwise = (num_groups != 1) && (in_group_size == 1) && (out_channels == num_groups);
 
-  mir::Operation *result;
+  mir::Operation::Output *result;
   if (is_depthwise)
   {
     // TODO handle properly kernel with layer multiplier
     auto transposed_tensor = mir::transposeTensor<0, 1, 3, 2>(kernel_tensor);
     auto kernel = createOp<ops::ConstantOp>("Constant", transposed_tensor)->getOutput(0);
     result = createOp<ops::DepthwiseConv2DOp>("Depthwise_Conv2D", convertCaffeToMIR(inputs[0]),
-                                              kernel, stride_shape, pad_before, pad_after);
+                                              kernel, stride_shape, pad_before, pad_after)
+                 ->getOutput(0);
   }
   else
   {
@@ -405,15 +422,16 @@ Caffe2OpCreator::convertConv(const std::vector<mir::Operation::Output *> &inputs
     kernel_tensor = transposeTensor<3, 0, 1, 2>(kernel_tensor);
     auto kernel = createOp<ops::ConstantOp>("Constant", kernel_tensor)->getOutput(0);
     result = createOp<ops::Conv2DOp>("Conv2D", convertCaffeToMIR(inputs[0]), kernel, stride_shape,
-                                     pad_before, pad_after);
+                                     pad_before, pad_after)
+                 ->getOutput(0);
   }
 
   if (op.input_size() > 2)
   {
-    result = createOp<ops::BiasAddOp>("Bias_Add", result->getOutput(0), inputs[2]);
+    result = createAdd("Bias_Add", result, inputs[2]);
   }
 
-  return {convertMIRToCaffe(result->getOutput(0))};
+  return {convertMIRToCaffe(result)};
 }
 
 std::vector<mir::Operation::Output *>
@@ -459,12 +477,12 @@ Caffe2OpCreator::convertFC(const std::vector<mir::Operation::Output *> &inputs,
   // Transform input into 2-D tensor by flattening axes
   Shape shape{input_shape.dim(0), input_shape.numElements() / input_shape.dim(0)};
 
-  auto reshape = createOp<ops::ReshapeOp>("Reshape", inputs[0], shape);
+  auto reshape = createOp<ops::ReshapeOp>("Reshape", inputs[0], shape)->getOutput(0);
   auto weights = createOp<ops::ConstantOp>("Constant", weights_tensor)->getOutput(0);
-  auto result = createOp<ops::FullyConnectedOp>("Fully_Connected", reshape->getOutput(0), weights);
-  result = createOp<ops::BiasAddOp>("Bias_Add", result->getOutput(0), inputs[2]);
+  auto result = createOp<ops::FullyConnectedOp>("Fully_Connected", reshape, weights)->getOutput(0);
+  result = createAdd("Bias_Add", result, inputs[2]);
 
-  return {result->getOutput(0)};
+  return {result};
 }
 
 std::vector<mir::Operation::Output *>
@@ -583,20 +601,20 @@ Caffe2OpCreator::convertSpatialBN(const std::vector<mir::Operation::Output *> &i
     bias_data.at(idx) *= -1;
 
   auto mean = createOp<ops::ConstantOp>("Constant", mean_tensor)->getOutput(0);
-  auto result = createOp<ops::BiasAddOp>("Bias_Add", convertCaffeToMIR(inputs[0]), mean);
+  auto result = createAdd("Bias_Add", convertCaffeToMIR(inputs[0]), mean);
 
   // res2 = res1 * scale / (var + epsilon)
   Tensor<float> multiplier(scale_tensor);
   for (auto &idx : ShapeRange(scale_tensor.getShape()))
     multiplier.at(idx) /= std::sqrt(*reinterpret_cast<float *>(var_tensor.at(idx)) + eps);
   auto scale = createOp<ops::ConstantOp>("Constant", scale_tensor)->getOutput(0);
-  result = createOp<ops::ScaleOp>("Scale", result->getOutput(0), scale);
+  result = createMul("Scale", result, scale);
 
   // overall_res = res2 + bias
   auto bias = createOp<ops::ConstantOp>("Constant", bias_tensor)->getOutput(0);
-  result = createOp<ops::BiasAddOp>("Bias_Add", result->getOutput(0), bias);
+  result = createAdd("Bias_Add", result, bias);
 
-  return {convertMIRToCaffe(result->getOutput(0))};
+  return {convertMIRToCaffe(result)};
 }
 
 std::vector<mir::Operation::Output *>
index 41cda23..915dd83 100644 (file)
@@ -110,6 +110,12 @@ private:
 
   mir::Operation::Output *convertMIRToCaffe(mir::Operation::Output *arg);
 
+  mir::Operation::Output *createAdd(const std::string &name, mir::Operation::Output *arg1,
+                                    mir::Operation::Output *arg2);
+
+  mir::Operation::Output *createMul(const std::string &name, mir::Operation::Output *arg1,
+                                    mir::Operation::Output *arg2);
+
   template <typename OpType, typename... Types>
   mir::Operation *createOp(const std::string &name, Types &&... args);
 };