Execute add operation in interpreter (#5088)
author오형석/On-Device Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Tue, 30 Apr 2019 00:47:22 +0000 (09:47 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 30 Apr 2019 00:47:22 +0000 (09:47 +0900)
Implement naive interpreter execution module
Fix interpreter gtest's input/output value

Signed-off-by: Hyeongseok Oh <hseok82.oh@samsung.com>
runtimes/neurun/core/src/exec/interp/Interpreter.cc
runtimes/neurun/test/interp/ExecManager.cc

index c459fee..0964010 100644 (file)
@@ -31,7 +31,7 @@ namespace interp
 {
 
 // TODO more structured execution kernel implementation
-// TODO execution
+// TODO use cker for execution
 // TODO divide tensor prepare and execution
 // TODO introduce memory manager (buffer allocate and free)
 class OperationExecutor : model::OperationVisitor
@@ -97,7 +97,25 @@ private:
                          << " RHS elements: " << rhs_tensor->element_nums()
                          << " OUT elements: " << out_tensor->element_nums() << std::endl;
 
-    throw std::runtime_error("NYI: add calculation");
+    const auto lhs_buffer = lhs_tensor->bufferRO();
+    const auto rhs_buffer = rhs_tensor->bufferRO();
+    auto out_buffer = out_tensor->buffer();
+
+    const auto data_type = lhs_tensor->data_type();
+    if (data_type != model::DataType::INT32)
+    {
+      throw std::runtime_error{"NYI: Support INT32 only"};
+    }
+
+    // Calculate
+    uint64_t size = lhs_tensor->element_nums();
+    const int32_t *lhs_ptr = reinterpret_cast<const int32_t *>(lhs_buffer);
+    const int32_t *rhs_ptr = reinterpret_cast<const int32_t *>(rhs_buffer);
+    int32_t *out_ptr = reinterpret_cast<int32_t *>(out_buffer);
+    for (uint64_t index = 0; index < size; index++)
+    {
+      *(out_ptr++) = *(lhs_ptr++) + *(rhs_ptr++);
+    }
   }
 
 private:
index 7de1809..76b74bf 100644 (file)
@@ -230,7 +230,7 @@ TEST_F(InterpExecManagerTest, execute)
   auto input2_idx = _graph->getInputs().at(input2);
 
   const int32_t input1_buffer[4] = {1, 0, -1, -2};
-  const int32_t input2_buffer[4] = {1, 3, 2, 4};
+  const int32_t input2_buffer[4] = {1, -3, 2, -4};
 
   auto output = IOIndex{0};
   auto output_idx = _graph->getOutputs().at(output);
@@ -240,7 +240,11 @@ TEST_F(InterpExecManagerTest, execute)
   EXPECT_NO_THROW(_executor->setInput(input1, reinterpret_cast<const void *>(input1_buffer), 16));
   EXPECT_NO_THROW(_executor->setInput(input2, reinterpret_cast<const void *>(input2_buffer), 16));
   EXPECT_NO_THROW(_executor->setOutput(output, reinterpret_cast<void *>(output_buffer), 16));
-  EXPECT_THROW(_executor->execute(), std::runtime_error);
+  EXPECT_NO_THROW(_executor->execute());
+  EXPECT_EQ(output_buffer[0], 2);
+  EXPECT_EQ(output_buffer[1], -3);
+  EXPECT_EQ(output_buffer[2], 1);
+  EXPECT_EQ(output_buffer[3], -6);
 }
 
 } // namespace