Introduce ADD broadcast for inputs without initialized data (#1780)
author최성진/동작제어Lab(SR)/Principal Engineer/삼성전자 <lotieye.choi@samsung.com>
Thu, 26 Jul 2018 01:59:25 +0000 (10:59 +0900)
committer이춘석/동작제어Lab(SR)/Staff Engineer/삼성전자 <chunseok.lee@samsung.com>
Thu, 26 Jul 2018 01:59:25 +0000 (10:59 +0900)
This commit introduces ADD broadcast for inputs without initialized data

-In case input data is not initialized.
-related with #1765 (inputs with initialized data)

Signed-off-by: SungJin Choi <lotieye.choi@samsung.com>
runtimes/pure_arm_compute/src/compilation.cc
runtimes/pure_arm_compute/src/compilation.h
runtimes/pure_arm_compute/src/execution.cc
runtimes/pure_arm_compute/src/execution.h

index d697757..4bd219f 100644 (file)
@@ -2691,6 +2691,12 @@ public:
 public:
   void finalize(void) const;
 
+public:
+  std::map<int, ::internal::tflite::operand::Shape> &shapeForBroadcast(void)
+  {
+    return _broadcasting_tensor_shape;
+  }
+
 private:
   ::internal::arm_compute::Plan &_plan;
 
@@ -3092,6 +3098,8 @@ int ANeuralNetworksCompilation_finish(ANeuralNetworksCompilation *compilation)
 
   plan_builder.finalize();
 
+  compilation->setShapeForBroadcast(plan_builder.shapeForBroadcast());
+
   return ANEURALNETWORKS_NO_ERROR;
 }
 
index bcbaa59..c523a7d 100644 (file)
@@ -18,9 +18,23 @@ public:
 
 public:
   void publish(std::shared_ptr<const internal::arm_compute::Plan> &plan) { plan = _plan; }
+  void publish(std::shared_ptr<const std::map<int, ::internal::tflite::operand::Shape>>
+                   &broadcasting_tensor_shape)
+  {
+    broadcasting_tensor_shape = _broadcasting_tensor_shape;
+  }
+  void
+  setShapeForBroadcast(std::map<int, ::internal::tflite::operand::Shape> &broadcasting_tensor_shape)
+  {
+    _broadcasting_tensor_shape =
+        std::make_shared<const std::map<int, ::internal::tflite::operand::Shape>>(
+            broadcasting_tensor_shape);
+  }
 
 private:
   std::shared_ptr<internal::arm_compute::Plan> _plan;
+  std::shared_ptr<const std::map<int, ::internal::tflite::operand::Shape>>
+      _broadcasting_tensor_shape;
 };
 
 #endif
index a297da5..fabf700 100644 (file)
@@ -287,11 +287,14 @@ int ANeuralNetworksExecution_create(ANeuralNetworksCompilation *compilation,
                                     ANeuralNetworksExecution **execution)
 {
   std::shared_ptr<const ::internal::arm_compute::Plan> plan;
-
   compilation->publish(plan);
-
   *execution = new ANeuralNetworksExecution{plan};
 
+  std::shared_ptr<const std::map<int, ::internal::tflite::operand::Shape>>
+      broadcasting_tensor_shape;
+  compilation->publish(broadcasting_tensor_shape);
+  (*execution)->setShapeForBroadcast(broadcasting_tensor_shape);
+
   return ANEURALNETWORKS_NO_ERROR;
 }
 
@@ -314,27 +317,40 @@ int ANeuralNetworksExecution_setInput(ANeuralNetworksExecution *execution, int32
     input_type = type->type;
   }
 
-  if (operands.at(operand_index).shape().rank() == 1)
+  auto shape = operands.at(operand_index).shape();
+  auto rank = shape.rank();
+
+  if (execution->shapeForBroadcast() != nullptr)
+  {
+    auto it = execution->shapeForBroadcast()->find(operand_index.asInt());
+    if (it != execution->shapeForBroadcast()->end())
+    {
+      rank = 4;
+      shape = it->second;
+    }
+  }
+
+  if (rank == 1)
   {
-    const auto len = operands.at(operand_index).shape().dim(0);
+    const auto len = shape.dim(0);
 
     asVectorSource(execution, input_type, index, len, buffer, length);
   }
-  else if (operands.at(operand_index).shape().rank() == 2)
+  else if (rank == 2)
   {
-    const auto &operand_shape = operands.at(operand_index).shape().asMatrix();
+    const auto &operand_shape = shape.asMatrix();
 
     asMatrixSource(execution, input_type, index, operand_shape, buffer, length);
   }
-  else if (operands.at(operand_index).shape().rank() == 3)
+  else if (rank == 3)
   {
-    const auto &operand_shape = operands.at(operand_index).shape().asTensor();
+    const auto &operand_shape = shape.asTensor();
 
     asTensorSource(execution, input_type, index, operand_shape, buffer, length);
   }
-  else if (operands.at(operand_index).shape().rank() == 4)
+  else if (rank == 4)
   {
-    const auto &operand_shape = operands.at(operand_index).shape().asFeature();
+    const auto &operand_shape = shape.asFeature();
 
     asFeatureSource(execution, input_type, index, operand_shape, buffer, length);
   }
index 4a43378..015b3cd 100644 (file)
@@ -17,9 +17,21 @@ public:
 
 public:
   const internal::arm_compute::Plan &plan(void) const { return *_plan; }
+  std::shared_ptr<const std::map<int, ::internal::tflite::operand::Shape>> shapeForBroadcast(void)
+  {
+    return _broadcasting_tensor_shape;
+  }
+  void setShapeForBroadcast(
+      const std::shared_ptr<const std::map<int, ::internal::tflite::operand::Shape>>
+          &broadcasting_tensor_shape)
+  {
+    _broadcasting_tensor_shape = broadcasting_tensor_shape;
+  }
 
 private:
   std::shared_ptr<const internal::arm_compute::Plan> _plan;
+  std::shared_ptr<const std::map<int, ::internal::tflite::operand::Shape>>
+      _broadcasting_tensor_shape = nullptr;
 
 public:
   // TODO Use InputIndex instead of int