From 9de37d0665673b6b1a1a8f721297c48dcd0c0202 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=98=A4=ED=98=95=EC=84=9D/On-Device=20Lab=28SR=29/Staff?= =?utf8?q?=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 23 Apr 2019 17:31:17 +0900 Subject: [PATCH] Manage operand stack and operation stack for interpretation (#5020) - Introduce operand ready checker - Introduce operation stack to save prepared operation - Manage operand stack and operation stack and show log Signed-off-by: Hyeongseok Oh --- .../neurun/core/src/exec/interp/Interpreter.cc | 60 +++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/runtimes/neurun/core/src/exec/interp/Interpreter.cc b/runtimes/neurun/core/src/exec/interp/Interpreter.cc index 536b19c..f452697 100644 --- a/runtimes/neurun/core/src/exec/interp/Interpreter.cc +++ b/runtimes/neurun/core/src/exec/interp/Interpreter.cc @@ -17,6 +17,7 @@ #include "Interpreter.h" #include +#include #include "model/operand/IndexMap.h" #include "util/logging.h" @@ -58,7 +59,64 @@ void Interpreter::run() }); // Execution - throw std::runtime_error("NYI: interpreter run"); + std::unordered_set ready_check; + while (!operand_stack.empty()) + { + const auto current_operand_index = operand_stack.top(); + operand_stack.pop(); + VERBOSE(INTERPRETER) << "Poped operand " << current_operand_index.value() + << " is checked ready to use" << std::endl; + + assert(ready_check.find(current_operand_index) == ready_check.end()); + ready_check.insert(current_operand_index); + + // Find prepared operations by scan use of current operand + std::stack operation_stack; + const auto use_operators = _env->model().operands.at(current_operand_index).getUses(); + for (auto use_operator : use_operators.list()) + { + // Assumption: all parameters are ready to use + bool operator_ready = true; + for (auto input_index : _env->model().operations.at(use_operator).getInputs()) + { + if (ready_check.find(input_index) == ready_check.end()) + { + operator_ready = false; + break; + } + } + + if (operator_ready) + { + VERBOSE(INTERPRETER) << "Ready to execute operation " << use_operator.value() << std::endl; + operation_stack.push(use_operator); + } + } + + while (!operation_stack.empty()) + { + const auto current_operation_index = operation_stack.top(); + operation_stack.pop(); + VERBOSE(INTERPRETER) << "Poped operation: " << current_operation_index.value() << "(" + << _env->model().operations.at(current_operation_index).getName() << ")" + << std::endl; + + // execution + // 1. Prepare output tensor + // 2. Call operation kernel + // 3. Push each output into operand stack + + const auto def_operands = _env->model().operations.at(current_operation_index).getOutputs(); + for (auto def_operand : def_operands) + { + VERBOSE(INTERPRETER) << "Buffer: Push to operand stack " << def_operand.value() + << std::endl; + operand_stack.push(def_operand); + } + } + } + + throw std::runtime_error{"NYI: buffer alloc and kernel call in operation stack loop"}; } } // namespace interp -- 2.7.4