From f02ccb60247a472cf614022ec350684871017a0a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ivan=20Vagin/AI=20Tools=20Lab=20/SRR/Engineer/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 22 Aug 2019 14:21:53 +0900 Subject: [PATCH] [neurun] Removed uses of BackendManager in BackendResolver and Scheduler (#6785) Removed uses of BackendManager in BackendResolver and Scheduler Signed-off-by: Ivan Vagin --- .../neurun/core/src/compiler/BackendResolver.h | 5 ++- runtimes/neurun/core/src/compiler/Compiler.cc | 3 +- .../neurun/core/src/compiler/ManualScheduler.cc | 3 +- runtimes/neurun/core/src/compiler/Scheduler.cc | 52 +++++++++------------- runtimes/neurun/core/src/compiler/Scheduler.h | 26 +++++++---- 5 files changed, 47 insertions(+), 42 deletions(-) diff --git a/runtimes/neurun/core/src/compiler/BackendResolver.h b/runtimes/neurun/core/src/compiler/BackendResolver.h index a88d249..c152d78 100644 --- a/runtimes/neurun/core/src/compiler/BackendResolver.h +++ b/runtimes/neurun/core/src/compiler/BackendResolver.h @@ -34,9 +34,10 @@ namespace compiler class BackendResolver { public: - BackendResolver(const model::Operands &operands) + BackendResolver(const model::Operands &operands, + const std::vector &backends) { - for (const auto backend : backend::BackendManager::instance().getAll()) + for (const auto backend : backends) { _context_manager.emplace(backend, backend->newContext(operands)); } diff --git a/runtimes/neurun/core/src/compiler/Compiler.cc b/runtimes/neurun/core/src/compiler/Compiler.cc index 90b078e..467ae81 100644 --- a/runtimes/neurun/core/src/compiler/Compiler.cc +++ b/runtimes/neurun/core/src/compiler/Compiler.cc @@ -55,7 +55,8 @@ void Compiler::compile(void) std::shared_ptr> indexed_ranks; if (util::getConfigBool(util::config::USE_SCHEDULER)) { - auto scheduler = compiler::Scheduler(_graph->operands()); + auto scheduler = + compiler::Scheduler(_graph->operands(), backend::BackendManager::instance().getAll()); br = scheduler.schedule(*_graph); indexed_ranks = scheduler.getIndexedRanks(); } diff --git a/runtimes/neurun/core/src/compiler/ManualScheduler.cc b/runtimes/neurun/core/src/compiler/ManualScheduler.cc index 0739df7..7dd1491 100644 --- a/runtimes/neurun/core/src/compiler/ManualScheduler.cc +++ b/runtimes/neurun/core/src/compiler/ManualScheduler.cc @@ -29,7 +29,8 @@ namespace compiler std::unique_ptr ManualScheduler::schedule(const graph::Graph &graph) { - auto backend_resolver = nnfw::cpp14::make_unique(graph.operands()); + auto backend_resolver = nnfw::cpp14::make_unique( + graph.operands(), backend::BackendManager::instance().getAll()); // 1. Backend for All operations const auto backend_all_str = util::getConfigString(util::config::OP_BACKEND_ALLOPS); diff --git a/runtimes/neurun/core/src/compiler/Scheduler.cc b/runtimes/neurun/core/src/compiler/Scheduler.cc index 6480f2f..46e745f 100644 --- a/runtimes/neurun/core/src/compiler/Scheduler.cc +++ b/runtimes/neurun/core/src/compiler/Scheduler.cc @@ -74,7 +74,7 @@ static bool isWorkaroundSkip(const graph::Graph &graph, const backend::Backend * const auto lhs_index{node.getInputs().at(model::operation::AddNode::Input::LHS)}; const auto rhs_index{node.getInputs().at(model::operation::AddNode::Input::RHS)}; /*Broadcasting isn't supported on CPU: no way to differ the existing exec_time record of - * Add with and without broadcasting*/ + * Add with and without broadcasting*/ /*Quant is also unsupported: throws an exception in run(): in case of scheduling without warm-up it isn't catched by tryBackend()*/ if (quant || @@ -128,7 +128,6 @@ static bool isMergable(const graph::Graph &graph, const model::Operation &node) void Scheduler::scheduleShufflingBackends() { - const auto all_backends = backend::BackendManager::instance().getAll(); VERBOSE(Scheduler::scheduleNode) << "Started task scheduling: uses all backends to get more metrics for data transfer" << std::endl; @@ -141,33 +140,33 @@ void Scheduler::scheduleShufflingBackends() const auto size = getOperationsFlattenedIOSize(*_graph, node); for (size_t i = 0;; ++i) { - if (i == all_backends.size()) + if (i == _all_backends.size()) { // wasn't able to find backend assert(false); break; } - if (backend_ind == all_backends.size()) + if (backend_ind == _all_backends.size()) { backend_ind = 0; } - if (isWorkaroundSkip(*_graph, all_backends[backend_ind], node, quant)) + if (isWorkaroundSkip(*_graph, _all_backends[backend_ind], node, quant)) { ++backend_ind; continue; } const auto exec_time = - _exec_time->getOperationExecTime(all_backends[backend_ind], node.getName(), quant, size); - // Scheduling to measure data transfer must be done after measuring all backends seperately + _exec_time->getOperationExecTime(_all_backends[backend_ind], node.getName(), quant, size); + // Scheduling to measure data transfer must be done after measuring all backends separately assert(exec_time != _exec_time->NOT_FOUND); if (exec_time == _exec_time->getMax()) { ++backend_ind; continue; } - _backend_resolver->setBackend(rank.second, all_backends[backend_ind]); + _backend_resolver->setBackend(rank.second, _all_backends[backend_ind]); VERBOSE(Scheduler::schedule) << "backend for " << node.getName() << " is " - << all_backends[backend_ind]->config()->id() << std::endl; + << _all_backends[backend_ind]->config()->id() << std::endl; ++backend_ind; break; } @@ -181,8 +180,7 @@ std::unique_ptr Scheduler::schedule(const graph::Grap // Make ranks and save in descending order makeRank(); - const auto all_backends = backend::BackendManager::instance().getAll(); - for (const auto *backend : all_backends) + for (const auto *backend : _all_backends) { _backends_avail_time.emplace(backend, std::map{{0, 0}}); } @@ -194,7 +192,7 @@ std::unique_ptr Scheduler::schedule(const graph::Grap const auto &node = _graph->operations().at(_rank_to_op.begin()->second); const bool quant = isQuant(*_graph, node); const auto size = getOperationsFlattenedIOSize(*_graph, node); - for (const auto *backend : all_backends) + for (const auto *backend : _all_backends) { const auto exec_time = _exec_time->getOperationExecTime(backend, node.getName(), quant, size); if (exec_time == _exec_time->NOT_FOUND) @@ -277,17 +275,16 @@ int64_t Scheduler::DFSMaxRank(const model::OperationIndex &index) if (op_to_rank_it != _op_to_rank->end()) return op_to_rank_it->second; - const auto all_backends = backend::BackendManager::instance().getAll(); const auto &node = _graph->operations().at(index); int64_t rank = 0; const bool quant = isQuant(*_graph, node); const auto size = getOperationsFlattenedIOSize(*_graph, node); - auto supported_backends_quantity = static_cast(all_backends.size()); + auto supported_backends_quantity = static_cast(_all_backends.size()); const auto max_child_rank = DFSChildrenMaxRank(index); // get average exec time of this op - for (const auto &backend : all_backends) + for (const auto &backend : _all_backends) { auto exec_time = _exec_time->getOperationExecTime(backend, node.getName(), quant, size); if (exec_time == _exec_time->NOT_FOUND) @@ -309,7 +306,7 @@ int64_t Scheduler::DFSMaxRank(const model::OperationIndex &index) // get standard deviation int64_t std = 0; - for (const auto backend : all_backends) + for (const auto backend : _all_backends) { const auto exec_time = getTime(backend, node.getName(), quant, size); if (exec_time < _exec_time->getMax()) @@ -336,7 +333,6 @@ int64_t Scheduler::DFSMaxRank(const model::OperationIndex &index) int64_t Scheduler::DFSChildrenMaxRank(const model::OperationIndex &index) { - const auto all_backends = backend::BackendManager::instance().getAll(); const auto &node = _graph->operations().at(index); int64_t max_child_rank = 0; for (const auto &output : node.getOutputs()) @@ -345,9 +341,9 @@ int64_t Scheduler::DFSChildrenMaxRank(const model::OperationIndex &index) const bool quant = operand.typeInfo().type() == model::DataType::QUANT8_ASYMM; // average data transfer cost of this operand's data int64_t avg_transfer_cost = 1; - for (const auto *backend : all_backends) + for (const auto *backend : _all_backends) { - for (const auto *other_backend : all_backends) + for (const auto *other_backend : _all_backends) { if (backend == other_backend) { @@ -364,7 +360,7 @@ int64_t Scheduler::DFSChildrenMaxRank(const model::OperationIndex &index) avg_transfer_cost += transfer_cost; } } - avg_transfer_cost /= all_backends.size(); + avg_transfer_cost /= _all_backends.size(); for (const auto &use : operand.getUses().list()) { const auto cur_child_rank = DFSMaxRank(use); @@ -394,14 +390,13 @@ int64_t Scheduler::backendAvailableTime(const backend::Backend *backend, void Scheduler::scheduleNode(const model::OperationIndex &index) { VERBOSE(Scheduler::scheduleNode) << "scheduling (" << index.value() << ")" << std::endl; - const auto all_backends = backend::BackendManager::instance().getAll(); int64_t eft = std::numeric_limits::max(), selected_exec_time = 0; const auto &node = _graph->operations().at(index); std::multimap selected_transfer_st_exec_time; // select the backend with the smallest eft of this task const backend::Backend *chosen_backend = nullptr; - for (const auto *backend : all_backends) + for (const auto *backend : _all_backends) { std::multimap transfer_st_exec_time; const auto est_and_et = ESTAndExecTime(backend, index, transfer_st_exec_time); @@ -417,10 +412,8 @@ void Scheduler::scheduleNode(const model::OperationIndex &index) for (const auto &it : selected_transfer_st_exec_time) { - auto prev_op_ft = - backendAvailableTime(backend::BackendManager::instance().get("cpu"), it.first, it.second); - _backends_avail_time[backend::BackendManager::instance().get("cpu")].insert( - {prev_op_ft + it.second, prev_op_ft}); + auto prev_op_ft = backendAvailableTime(_cpu_backend, it.first, it.second); + _backends_avail_time[_cpu_backend].insert({prev_op_ft + it.second, prev_op_ft}); } _ops_eft[index] = eft; @@ -474,7 +467,6 @@ Scheduler::ESTAndExecTime(const backend::Backend *backend, const model::Operatio // Find free time for data transferring and insert it into backend taskset. This is needed: // 1. Time for multiple permutations for this node's input is found correctly // 2. If backend==cpu, then free time for this node must come after permutations - auto cpu_backend = backend::BackendManager::instance().get("cpu"); for (auto &it : transfer_st_exec_time) { if (is_parallel_exec) @@ -487,11 +479,11 @@ Scheduler::ESTAndExecTime(const backend::Backend *backend, const model::Operatio } total_transfer_cost += it.second; - const auto prev_op_ft = backendAvailableTime(cpu_backend, it.first, it.second); + const auto prev_op_ft = backendAvailableTime(_cpu_backend, it.first, it.second); max_pred_eft = std::max(max_pred_eft, prev_op_ft + it.second); - const auto tmp = _backends_avail_time[cpu_backend].emplace(prev_op_ft + it.second, prev_op_ft); + const auto tmp = _backends_avail_time[_cpu_backend].emplace(prev_op_ft + it.second, prev_op_ft); inserted_permutations.push_back(tmp.first); } // find the hole/gap, where this op can be put or the finishing time of the last assigned op @@ -500,7 +492,7 @@ Scheduler::ESTAndExecTime(const backend::Backend *backend, const model::Operatio // Remove inserted permutation from cpu's task set for (const auto &it : inserted_permutations) { - _backends_avail_time[cpu_backend].erase(it); + _backends_avail_time[_cpu_backend].erase(it); } /* In case non-parallel executor measure just exec time and data transfer time diff --git a/runtimes/neurun/core/src/compiler/Scheduler.h b/runtimes/neurun/core/src/compiler/Scheduler.h index 0dd8d80..991dce4 100644 --- a/runtimes/neurun/core/src/compiler/Scheduler.h +++ b/runtimes/neurun/core/src/compiler/Scheduler.h @@ -47,14 +47,22 @@ public: * @param[in] model Graph model * @param[in] backend_resolver backend resolver */ - Scheduler(const neurun::model::Operands &operands) + Scheduler(const neurun::model::Operands &operands, std::vector backends) : _run_cache{}, _backends_avail_time{}, _ops_eft{}, - _op_to_rank{std::make_shared>()} + _op_to_rank{std::make_shared>()}, + _all_backends(std::move(backends)) { - _backend_resolver = nnfw::cpp14::make_unique(operands); - _exec_time = - nnfw::cpp14::make_unique(backend::BackendManager::instance().getAll()); - // DO NOTHING + _backend_resolver = + nnfw::cpp14::make_unique(operands, _all_backends); + _exec_time = nnfw::cpp14::make_unique(_all_backends); + + // Find cpu backend + auto cpu_backend_it = std::find_if( + _all_backends.begin(), _all_backends.end(), + [](const backend::Backend *backend) { return backend->config()->id() == "cpu"; }); + if (cpu_backend_it == _all_backends.end()) + throw std::runtime_error("Scheduler could be used only if 'cpu' backend is available"); + _cpu_backend = *cpu_backend_it; } public: @@ -77,9 +85,9 @@ private: * * @param[in] backend: backend, for which to return the time * @param[in] index: index of an operation - * @param[out] transfer_st_exec_time: est and exec time of data tranfer operation + * @param[out] transfer_st_exec_time: est and exec time of data transfer operation * - * @return earliest starting tme and execution time + * @return earliest starting time and execution time */ std::pair ESTAndExecTime(const backend::Backend *backend, const model::OperationIndex &index, @@ -133,6 +141,8 @@ private: std::unique_ptr _backend_resolver; std::unique_ptr _exec_time; const graph::Graph *_graph{nullptr}; + const std::vector _all_backends; + const backend::Backend *_cpu_backend{nullptr}; }; } // namespace compiler -- 2.7.4