From 5c58d2ba915aa8764d72b7a608b0eef328648e04 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9D=B4=ED=95=9C=EC=A2=85/On-Device=20Lab=28SR=29/Enginee?= =?utf8?q?r/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 29 May 2019 16:34:47 +0900 Subject: [PATCH] Introduce IScheduler (#5296) * Introduce IScheduler Introduce IScheduler to support various kind of schedulers. It has just one `schedule` function that returns a `BackendResolver`, but it could be changed later as needed. Legacy scheduling procedure is now implemented in `ManualScheduler`. Signed-off-by: Hanjoung Lee * Fix comments --- runtimes/neurun/core/src/compiler/IScheduler.h | 38 ++++++++++ .../neurun/core/src/compiler/ManualScheduler.cc | 82 ++++++++++++++++++++++ .../neurun/core/src/compiler/ManualScheduler.h | 36 ++++++++++ runtimes/neurun/core/src/graph/Graph.cc | 56 ++------------- 4 files changed, 162 insertions(+), 50 deletions(-) create mode 100644 runtimes/neurun/core/src/compiler/IScheduler.h create mode 100644 runtimes/neurun/core/src/compiler/ManualScheduler.cc create mode 100644 runtimes/neurun/core/src/compiler/ManualScheduler.h diff --git a/runtimes/neurun/core/src/compiler/IScheduler.h b/runtimes/neurun/core/src/compiler/IScheduler.h new file mode 100644 index 0000000..5b425bf --- /dev/null +++ b/runtimes/neurun/core/src/compiler/IScheduler.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NEURUN_CORE_COMPILER_I_SCHEDULER_H__ +#define __NEURUN_CORE_COMPILER_I_SCHEDULER_H__ + +#include "BackendResolver.h" +#include "graph/Graph.h" + +namespace neurun +{ +namespace compiler +{ + +struct IScheduler +{ + virtual ~IScheduler() = default; + + virtual std::unique_ptr schedule(const graph::Graph &graph) = 0; +}; + +} // namespace compiler +} // namespace neurun + +#endif // __NEURUN_CORE_COMPILER_I_SCHEDULER_H__ diff --git a/runtimes/neurun/core/src/compiler/ManualScheduler.cc b/runtimes/neurun/core/src/compiler/ManualScheduler.cc new file mode 100644 index 0000000..98cef1c --- /dev/null +++ b/runtimes/neurun/core/src/compiler/ManualScheduler.cc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ManualScheduler.h" +#include "backend/Backend.h" +#include "backend/BackendManager.h" +#include "backend/IConfig.h" +#include "util/config/ConfigManager.h" + +namespace neurun +{ +namespace compiler +{ + +std::unique_ptr ManualScheduler::schedule(const graph::Graph &graph) +{ + auto backend_manager = std::make_shared(graph.operands()); + auto backend_resolver = nnfw::cpp14::make_unique(backend_manager); + + // 1. Backend for All operations + const auto backend_all_str = + config::ConfigManager::instance().get(config::OP_BACKEND_ALLOPS); + auto backend_all = backend_manager->get(backend_all_str); + + VERBOSE(Lower) << "Use backend for all ops: " << backend_all_str << std::endl; + + graph.operations().iterate([&](const model::OperationIndex &index, const model::Operation &) { + backend_resolver->setBackend(index, backend_all); + }); + + // 2. Backend per operation type + std::unordered_map op_type_map; +#define OP(InternalName, IsNnApi) \ + if (IsNnApi) \ + { \ + const auto &backend_str = \ + config::ConfigManager::instance().get(config::OP_BACKEND_##InternalName); \ + if (!backend_str.empty()) \ + { \ + auto backend = backend_manager->get(backend_str); \ + VERBOSE(Lower) << "backend for " << #InternalName << ": " << backend_str << std::endl; \ + op_type_map[typeid(model::operation::InternalName)] = backend; \ + } \ + } +#include "model/Operations.lst" +#undef OP + graph.operations().iterate([&](const model::OperationIndex &index, const model::Operation &) { + auto itr = op_type_map.find(typeid(index)); + if (itr != op_type_map.end()) + { + backend_resolver->setBackend(index, itr->second); + } + }); + + // 3. Backend per operation + // TODO TBD + + // Dump final assignment + backend_resolver->iterate( + [&](const model::OperationIndex &index, const backend::Backend *backend) { + VERBOSE(Lower) << "backend for operation #" << index.value() << ": " + << backend->config()->id() << std::endl; + }); + + return backend_resolver; +} + +} // namespace compiler +} // namespace neurun diff --git a/runtimes/neurun/core/src/compiler/ManualScheduler.h b/runtimes/neurun/core/src/compiler/ManualScheduler.h new file mode 100644 index 0000000..c40318a --- /dev/null +++ b/runtimes/neurun/core/src/compiler/ManualScheduler.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NEURUN_CORE_COMPILER_MANUAL_SCHEDULER_H__ +#define __NEURUN_CORE_COMPILER_MANUAL_SCHEDULER_H__ + +#include "IScheduler.h" + +namespace neurun +{ +namespace compiler +{ + +class ManualScheduler : public IScheduler +{ +public: + std::unique_ptr schedule(const graph::Graph &graph) override; +}; + +} // namespace compiler +} // namespace neurun + +#endif // __NEURUN_CORE_COMPILER_MANUAL_SCHEDULER_H__ diff --git a/runtimes/neurun/core/src/graph/Graph.cc b/runtimes/neurun/core/src/graph/Graph.cc index 6ce055c..fe7bd3e 100644 --- a/runtimes/neurun/core/src/graph/Graph.cc +++ b/runtimes/neurun/core/src/graph/Graph.cc @@ -27,6 +27,8 @@ #include "graph/operand/LowerInfo.h" #include "operand/Shape4DConvert.h" #include "compiler/BackendResolver.h" +#include "compiler/IScheduler.h" +#include "compiler/ManualScheduler.h" #include "backend/IConfig.h" #include "pass/PermutationInsertionPass.h" #include "pass/PermutationEliminationPass.h" @@ -104,57 +106,11 @@ void Graph::lower(void) nnfw::cpp14::make_unique(graph::operand::asShape4D(object.shape())); }); - auto backend_manager = std::make_shared(_model->operands); - _backend_resolver = nnfw::cpp14::make_unique(backend_manager); - - // BackendResolver building - // TODO When IScheduler interface is introduced, this building should be done in a derivative of - // IScheduler + // Schedule { - // 1. Backend for All operations - const auto backend_all_str = - config::ConfigManager::instance().get(config::OP_BACKEND_ALLOPS); - auto backend_all = backend_manager->get(backend_all_str); - - VERBOSE(Lower) << "Use backend for all ops: " << backend_all_str << std::endl; - - _model->operations.iterate([&](const model::OperationIndex &index, model::Operation &) { - _backend_resolver->setBackend(index, backend_all); - }); - - // 2. Backend per operation type - std::unordered_map op_type_map; -#define OP(InternalName, IsNnApi) \ - if (IsNnApi) \ - { \ - const auto &backend_str = \ - config::ConfigManager::instance().get(config::OP_BACKEND_##InternalName); \ - if (!backend_str.empty()) \ - { \ - auto backend = backend_manager->get(backend_str); \ - VERBOSE(Lower) << "backend for " << #InternalName << ": " << backend_str << std::endl; \ - op_type_map[typeid(model::operation::InternalName)] = backend; \ - } \ - } -#include "model/Operations.lst" -#undef OP - _model->operations.iterate([&](const model::OperationIndex &index, model::Operation &) { - auto itr = op_type_map.find(typeid(index)); - if (itr != op_type_map.end()) - { - _backend_resolver->setBackend(index, itr->second); - } - }); - - // 3. Backend per operation - // TODO TBD - - // Dump final assignment - _backend_resolver->iterate( - [&](const model::OperationIndex &index, const backend::Backend *backend) { - VERBOSE(Lower) << "backend for operation #" << index.value() << ": " - << backend->config()->id() << std::endl; - }); + std::unique_ptr scheduler = + nnfw::cpp14::make_unique(); + _backend_resolver = scheduler->schedule(*this); } _lower_info_map = nnfw::cpp14::make_unique(); -- 2.7.4