[neurun] Made scheduler to shuffle backends after all nodes are profiled (#7010)
authorIvan Vagin/AI Tools Lab /SRR/Engineer/삼성전자 <ivan.vagin@samsung.com>
Fri, 30 Aug 2019 01:39:28 +0000 (10:39 +0900)
committer이한종/On-Device Lab(SR)/Engineer/삼성전자 <hanjoung.lee@samsung.com>
Fri, 30 Aug 2019 01:39:28 +0000 (10:39 +0900)
[neurun] Made scheduler to shuffle backends after all nodes are already profiled

Signed-off-by: Ivan Vagin <ivan.vagin@samsung.com>
runtimes/neurun/core/src/compiler/Scheduler.cc
runtimes/neurun/core/src/compiler/Scheduler.h

index 3016fb6..0032a69 100644 (file)
@@ -173,6 +173,19 @@ void Scheduler::scheduleShufflingBackends()
   }
 }
 
+bool Scheduler::isNodeProfiled(const model::Operation &node)
+{
+  const bool quant = isQuant(*_graph, node);
+  const auto size = getOperationsFlattenedIOSize(*_graph, node);
+  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)
+      return false;
+  }
+  return true;
+}
+
 std::unique_ptr<compiler::BackendResolver> Scheduler::schedule(const graph::Graph &graph)
 {
   _graph = &graph;
@@ -188,40 +201,16 @@ std::unique_ptr<compiler::BackendResolver> Scheduler::schedule(const graph::Grap
   const bool is_profiling = util::getConfigBool(util::config::PROFILING_MODE);
   if (is_profiling)
   {
-    bool profile_data_transfer = true;
-    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)
-    {
-      const auto exec_time = _exec_time->getOperationExecTime(backend, node.getName(), quant, size);
-      // if there is a record for a backend
-      if (exec_time == _exec_time->NOT_FOUND)
-      {
-        profile_data_transfer = false;
-        break;
-      }
-    }
-    // Check if profiling of data transfer is already done
-    for (uint32_t i = 0; i < _all_backends.size() && profile_data_transfer; ++i)
-    {
-      for (const auto *another_backend : _all_backends)
-      {
-        if (_all_backends[i] == another_backend)
-        {
-          continue;
-        }
-        const auto permute_time =
-            _exec_time->getPermuteTime(_all_backends[i], another_backend, quant, size);
-        // if permutation already was done
-        if (permute_time != _exec_time->NOT_FOUND)
-        {
-          profile_data_transfer = false;
-          break;
-        }
-      }
-    }
-    if (profile_data_transfer)
+    // Check if profiling info about all backend/node pairs already exists
+    bool all_nodes_are_profiled = true;
+    _graph->operations().iterate([&](const model::OperationIndex &, const model::Operation &op) {
+      if (all_nodes_are_profiled)
+        all_nodes_are_profiled = isNodeProfiled(op);
+    });
+
+    // If all nodes are already profiled - schedule backends in such order, so more profiling
+    // information about between-backends data transfer could be collected
+    if (all_nodes_are_profiled)
     {
       scheduleShufflingBackends();
       VERBOSE(Scheduler::schedule) << "task scheduling finished" << std::endl;
index 991dce4..a245171 100644 (file)
@@ -76,6 +76,8 @@ public:
   std::shared_ptr<model::OperationIndexMap<int64_t>> getIndexedRanks() { return _op_to_rank; }
 
 private:
+  bool isNodeProfiled(const model::Operation &);
+
   void scheduleNode(const model::OperationIndex &);
   /**
    * @brief   Get earliest starting time and execution time of an operation on a backend.