You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by GitBox <gi...@apache.org> on 2020/09/22 18:46:46 UTC

[GitHub] [incubator-tvm] comaniac commented on a change in pull request #6529: [Ansor] Parallel the InitPopulation

comaniac commented on a change in pull request #6529:
URL: https://github.com/apache/incubator-tvm/pull/6529#discussion_r492949744



##########
File path: src/auto_scheduler/search_policy/sketch_policy.cc
##########
@@ -332,29 +333,45 @@ Array<State> SketchPolicyNode::GenerateSketches() {
 }
 
 Array<State> SketchPolicyNode::SampleInitPopulation(const Array<State>& sketches, int out_size) {
-  int fail_ct = 0;
+  std::atomic<int> fail_ct(0);
   Array<State> out_states;
+  std::vector<std::mt19937> rand_seeds;
+  rand_seeds.reserve(out_size);
+  for (int i = 0; i < out_size; i++) {
+    rand_seeds.push_back(std::mt19937(rand_gen()));
+  }
   auto tic_begin = std::chrono::high_resolution_clock::now();
 
   while (static_cast<int>(out_states.size()) < out_size && fail_ct < out_size) {
-    // Random choose a starting sketch
-    // TODO(jcf94, merrymercy): Maybe choose sketches in different possibility for they may have
-    // different potential on generating state with better performance
-    State tmp_s = sketches[(rand_gen)() % sketches.size()];
-
-    // Derivation rule based enumeration
-    bool valid = true;
-    for (const auto& rule : init_rules) {
-      if (rule->Apply(this, &tmp_s) == PopulationGenerationRule::ResultKind::kInvalid) {
-        valid = false;
-        break;
+    std::vector<State> temp_states(out_size);
+
+    support::parallel_for(0, out_size - out_states.size(),
+        [this, &temp_states, &sketches, &rand_seeds, &fail_ct](int index) {
+      // Random choose a starting sketch
+      // TODO(jcf94, merrymercy): Maybe choose sketches in different possibility for they may have
+      // different potential on generating state with better performance

Review comment:
       Move the comments to the place of selecting sketches.

##########
File path: src/auto_scheduler/search_policy/sketch_policy.cc
##########
@@ -332,29 +333,45 @@ Array<State> SketchPolicyNode::GenerateSketches() {
 }
 
 Array<State> SketchPolicyNode::SampleInitPopulation(const Array<State>& sketches, int out_size) {
-  int fail_ct = 0;
+  std::atomic<int> fail_ct(0);
   Array<State> out_states;
+  std::vector<std::mt19937> rand_seeds;

Review comment:
       This is not rand_"seeds" but "rand_gens" to me.

##########
File path: src/auto_scheduler/search_policy/utils.cc
##########
@@ -414,19 +414,52 @@ void PruneInvalidState(const SearchTask& task, Array<State>* states) {
   }
 }
 
+/********** SplitFactorizationMemo **********/
+
+void SplitFactorizationMemo::ReadWriteLock::GetRead() {
+  std::unique_lock<std::mutex> lock(cv_mutex_);
+  cv_.wait(lock, [this](){ return !this->is_writing_; });
+  read_count_++;
+}
+
+void SplitFactorizationMemo::ReadWriteLock::GetWrite() {

Review comment:
       Better to comment the write condition (no one is reading or writing).

##########
File path: src/auto_scheduler/search_policy/sketch_policy.cc
##########
@@ -332,29 +333,45 @@ Array<State> SketchPolicyNode::GenerateSketches() {
 }
 
 Array<State> SketchPolicyNode::SampleInitPopulation(const Array<State>& sketches, int out_size) {
-  int fail_ct = 0;
+  std::atomic<int> fail_ct(0);
   Array<State> out_states;
+  std::vector<std::mt19937> rand_seeds;
+  rand_seeds.reserve(out_size);
+  for (int i = 0; i < out_size; i++) {
+    rand_seeds.push_back(std::mt19937(rand_gen()));
+  }
   auto tic_begin = std::chrono::high_resolution_clock::now();
 
   while (static_cast<int>(out_states.size()) < out_size && fail_ct < out_size) {
-    // Random choose a starting sketch
-    // TODO(jcf94, merrymercy): Maybe choose sketches in different possibility for they may have
-    // different potential on generating state with better performance
-    State tmp_s = sketches[(rand_gen)() % sketches.size()];
-
-    // Derivation rule based enumeration
-    bool valid = true;
-    for (const auto& rule : init_rules) {
-      if (rule->Apply(this, &tmp_s) == PopulationGenerationRule::ResultKind::kInvalid) {
-        valid = false;
-        break;
+    std::vector<State> temp_states(out_size);
+
+    support::parallel_for(0, out_size - out_states.size(),
+        [this, &temp_states, &sketches, &rand_seeds, &fail_ct](int index) {
+      // Random choose a starting sketch
+      // TODO(jcf94, merrymercy): Maybe choose sketches in different possibility for they may have
+      // different potential on generating state with better performance
+      State tmp_s = sketches[(rand_seeds[index])() % sketches.size()];
+
+      // Derivation rule based enumeration
+      bool valid = true;
+      for (const auto& rule : init_rules) {
+        if (rule->Apply(this, &tmp_s, &rand_seeds[index]) == PopulationGenerationRule::ResultKind::kInvalid) {
+          valid = false;
+          break;
+        }
       }
-    }
 
-    if (valid) {
-      out_states.push_back(std::move(tmp_s));
-    } else {
-      fail_ct++;
+      if (valid) {
+        temp_states[index] = std::move(tmp_s);
+      } else {
+        fail_ct++;

Review comment:
       It seems to me that this atomic add could be avoided as long as you simply put all schedules to `temp_states` and count the failures afterwards at L372.

##########
File path: src/auto_scheduler/search_policy/utils.cc
##########
@@ -414,19 +414,52 @@ void PruneInvalidState(const SearchTask& task, Array<State>* states) {
   }
 }
 
+/********** SplitFactorizationMemo **********/
+
+void SplitFactorizationMemo::ReadWriteLock::GetRead() {

Review comment:
       Better to comment the read condition (no one is writing).




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org