[mir_caffe] Do not insert Transposes (#7110)
authorСергей Баранников/AI Tools Lab /SRR/Engineer/삼성전자 <s.barannikov@samsung.com>
Tue, 3 Sep 2019 17:06:46 +0000 (20:06 +0300)
committerAlexander Efimov/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Tue, 3 Sep 2019 17:06:46 +0000 (20:06 +0300)
Remove insertion of Transpose operations, set the data format on operations instead.

Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
compiler/mir-caffe-importer/caffe_op_creator.cpp
compiler/mir-caffe-importer/caffe_op_creator.h

index c0c3c34..34b1da9 100644 (file)
@@ -114,20 +114,6 @@ static mir::Shape convertBlobShape(const BlobShape &shape)
 
 using namespace mir;
 
-mir::Operation::Output *CaffeOpCreator::convertCaffeToMIR(mir::Operation::Output *arg)
-{
-  // NCHW -> NHWC
-  auto transpose = createOp<ops::TransposeOp>(arg, std::vector<std::size_t>{0, 2, 3, 1});
-  return transpose->getOutput(0);
-}
-
-mir::Operation::Output *CaffeOpCreator::convertMIRToCaffe(mir::Operation::Output *arg)
-{
-  // NHWC -> NCHW
-  auto transpose = createOp<ops::TransposeOp>(arg, std::vector<std::size_t>{0, 3, 1, 2});
-  return transpose->getOutput(0);
-}
-
 /// @brief Split arg into @p num_parts equal parts along @p axis axis.
 std::vector<mir::Operation::Output *> CaffeOpCreator::createSplit(mir::Operation::Output *arg,
                                                                   int32_t num_parts, int32_t axis)
@@ -322,8 +308,8 @@ CaffeOpCreator::convertConvolution(const caffe::LayerParameter &layer,
     // TODO handle properly kernel with layer multiplier
     auto transposed_tensor = transposeTensor<0, 1, 3, 2>(kernel_weights);
     auto kernel = createOp<ops::ConstantOp>(transposed_tensor)->getOutput(0);
-    result = createOp<ops::DepthwiseConv2DOp>(convertCaffeToMIR(inputs[0]), kernel, strides,
-                                              padding, padding)
+    result = createOp<ops::DepthwiseConv2DOp>(inputs[0], kernel, strides, padding, padding,
+                                              DataFormat::NCHW)
                  ->getOutput(0);
   }
   else
@@ -335,19 +321,19 @@ CaffeOpCreator::convertConvolution(const caffe::LayerParameter &layer,
     }
     kernel_weights = transposeTensor<3, 0, 1, 2>(kernel_weights);
     auto kernel = createOp<ops::ConstantOp>(kernel_weights)->getOutput(0);
-    result =
-        createOp<ops::Conv2DOp>(convertCaffeToMIR(inputs[0]), kernel, strides, padding, padding)
-            ->getOutput(0);
+    result = createOp<ops::Conv2DOp>(inputs[0], kernel, strides, padding, padding, DataFormat::NCHW)
+                 ->getOutput(0);
   }
 
   // Add the bias, if any.
   if (params.bias_term())
   {
     auto bias = createOp<ops::ConstantOp>(convertBlob(layer.blobs(1)))->getOutput(0);
+    bias = createOp<ops::ReshapeOp>(bias, Shape{1, bias->getShape().dim(0), 1, 1})->getOutput(0);
     result = createOp<ops::AddOp>(result, bias)->getOutput(0);
   }
 
-  return {convertMIRToCaffe(result)};
+  return {result};
 }
 
 std::vector<mir::Operation::Output *>
@@ -369,17 +355,18 @@ CaffeOpCreator::convertDeconvolution(const caffe::LayerParameter &layer,
     kernel_weights = fixGroupedKernel(opts.group(), kernel_weights);
   }
   auto kernel = createOp<ops::ConstantOp>(kernel_weights)->getOutput(0);
-  auto result = createOp<ops::DeConv2DOp>(convertCaffeToMIR(inputs[0]), kernel, strides, padding)
+  auto result = createOp<ops::DeConv2DOp>(inputs[0], kernel, strides, padding, DataFormat::NCHW)
                     ->getOutput(0);
 
   // bias_term is optional (so might not be present) and defaults to true
   if (opts.bias_term())
   {
     auto bias = createOp<ops::ConstantOp>(convertBlob(layer.blobs(1)))->getOutput(0);
+    bias = createOp<ops::ReshapeOp>(bias, Shape{1, bias->getShape().dim(0), 1, 1})->getOutput(0);
     result = createOp<ops::AddOp>(result, bias)->getOutput(0);
   }
 
-  return {convertMIRToCaffe(result)};
+  return {result};
 }
 
 std::vector<mir::Operation::Output *>
@@ -497,27 +484,24 @@ CaffeOpCreator::convertPooling(const caffe::LayerParameter &layer,
   convertPoolingParam(params, input->getShape(), window_size, strides, padding_before,
                       padding_after);
 
-  input = convertCaffeToMIR(input);
   mir::Operation::Output *result;
 
   switch (params.pool())
   {
     case PoolingParameter::AVE:
       result = createOp<ops::AvgPool2DOp>(input, window_size, strides, padding_before,
-                                          padding_after, true, mir::DataFormat::NHWC)
+                                          padding_after, true, mir::DataFormat::NCHW)
                    ->getOutput(0);
       break;
     case PoolingParameter::MAX:
       result = createOp<ops::MaxPool2DOp>(input, window_size, strides, padding_before,
-                                          padding_after, mir::DataFormat::NHWC)
+                                          padding_after, mir::DataFormat::NCHW)
                    ->getOutput(0);
       break;
     default:
       assert(false);
   }
 
-  result = convertMIRToCaffe(result);
-
   return {result};
 }
 
@@ -602,16 +586,18 @@ CaffeOpCreator::convertScale(const caffe::LayerParameter &layer,
 {
   const auto &params = layer.scale_param();
   auto scale = createOp<ops::ConstantOp>(convertBlob(layer.blobs(0)))->getOutput(0);
-  auto result = createOp<ops::MulOp>(convertCaffeToMIR(inputs[0]), scale)->getOutput(0);
+  scale = createOp<ops::ReshapeOp>(scale, Shape{1, scale->getShape().dim(0), 1, 1})->getOutput(0);
+  auto result = createOp<ops::MulOp>(inputs[0], scale)->getOutput(0);
 
   // Add the bias, if any.
   if (params.bias_term())
   {
     auto bias = createOp<ops::ConstantOp>(convertBlob(layer.blobs(1)))->getOutput(0);
+    bias = createOp<ops::ReshapeOp>(bias, Shape{1, bias->getShape().dim(0), 1, 1})->getOutput(0);
     result = createOp<ops::AddOp>(result, bias)->getOutput(0);
   }
 
-  return {convertMIRToCaffe(result)};
+  return {result};
 }
 
 void CaffeOpCreator::checkBatchNorm(const caffe::LayerParameter &layer,
@@ -655,11 +641,14 @@ CaffeOpCreator::convertBatchNorm(const caffe::LayerParameter &layer,
     var_accessor.at(idx) = 1.0f / std::sqrt(var_accessor.at(idx) * scale_factor + eps);
   auto c2 = createOp<ops::ConstantOp>(var_tensor)->getOutput(0);
 
+  c1 = createOp<ops::ReshapeOp>(c1, Shape{1, c1->getShape().dim(0), 1, 1})->getOutput(0);
+  c2 = createOp<ops::ReshapeOp>(c2, Shape{1, c2->getShape().dim(0), 1, 1})->getOutput(0);
+
   // Y = (X + C1) * C2
-  input = convertCaffeToMIR(input);
   auto result = createOp<ops::AddOp>(input, c1)->getOutput(0);
   result = createOp<ops::MulOp>(result, c2)->getOutput(0);
-  return {convertMIRToCaffe(result)};
+
+  return {result};
 }
 
 std::vector<mir::Operation::Output *>
index 98f2161..19be0c9 100644 (file)
@@ -127,10 +127,6 @@ public:
 private:
   mir::Graph *_graph = nullptr;
 
-  mir::Operation::Output *convertCaffeToMIR(mir::Operation::Output *arg);
-
-  mir::Operation::Output *convertMIRToCaffe(mir::Operation::Output *arg);
-
   std::vector<mir::Operation::Output *> createSplit(mir::Operation::Output *arg, int32_t num_parts,
                                                     int32_t axis);