{
// 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
<< " 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:
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);
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