@@ -143,7 +143,6 @@ void HighsMipSolver::run() {
143143 HighsMipWorker& master_worker = mipdata_->workers .at (0 );
144144
145145restart:
146- mipdata_->parallel_lock = false ;
147146 if (modelstatus_ == HighsModelStatus::kNotset ) {
148147 // Check limits have not been reached before evaluating root node
149148 if (mipdata_->checkLimits ()) {
@@ -315,7 +314,6 @@ void HighsMipSolver::run() {
315314 // Initialize worker relaxations and mipworkers
316315 // todo lps and workers are still empty right now
317316
318- mipdata_->parallel_lock = true ;
319317 const HighsInt mip_search_concurrency = options_mip_->mip_search_concurrency ;
320318 const HighsInt num_worker = mip_search_concurrency - 1 ;
321319 highs::parallel::TaskGroup tg;
@@ -412,6 +410,14 @@ void HighsMipSolver::run() {
412410 return search.performed_dive_ ;
413411 };
414412
413+ auto setParallelLock = [&](bool lock) -> void {
414+ if (mipdata_->workers .size () <= 1 ) return ;
415+ mipdata_->parallel_lock = lock;
416+ for (HighsConflictPool& conflictpool : mipdata_->conflictpools ) {
417+ conflictpool.setAgeLock (lock);
418+ }
419+ };
420+
415421 auto syncSolutions = [&]() -> void {
416422 for (HighsMipWorker& worker : mipdata_->workers ) {
417423 for (auto & sol : worker.solutions_ ) {
@@ -427,6 +433,16 @@ void HighsMipSolver::run() {
427433 }
428434 };
429435
436+ auto syncPools = [&]() -> void {
437+ if (mipdata_->workers .size () <= 1 || mipdata_->parallelLockActive ()) return ;
438+ for (HighsInt i = 1 ; i < mipdata_->conflictpools .size (); ++i) {
439+ mipdata_->conflictpools [i].syncConflictPool (mipdata_->conflictPool );
440+ }
441+ for (HighsInt i = 1 ; i < mipdata_->cutpools .size (); ++i) {
442+ mipdata_->cutpools [i].syncCutPool (*this , mipdata_->cutpool );
443+ }
444+ };
445+
430446 auto syncGlobalDomain = [&]() -> void {
431447 if (mipdata_->workers .size () <= 1 ) return ;
432448 for (HighsMipWorker& worker : mipdata_->workers ) {
@@ -515,6 +531,7 @@ void HighsMipSolver::run() {
515531 auto evaluateNodes = [&](std::vector<HighsInt>& search_indices) -> void {
516532 std::vector<HighsSearch::NodeResult> search_results (search_indices.size ());
517533 analysis_.mipTimerStart (kMipClockEvaluateNode1 );
534+ setParallelLock (true );
518535 for (HighsInt i = 0 ; i != search_indices.size (); i++) {
519536 // TODO MT: Remove this dummy if statement
520537 if (i != 0 ) continue ;
@@ -529,6 +546,7 @@ void HighsMipSolver::run() {
529546 }
530547 }
531548 if (mipdata_->parallelLockActive ()) tg.taskWait ();
549+ setParallelLock (false );
532550 analysis_.mipTimerStop (kMipClockEvaluateNode1 );
533551 for (HighsInt i = 0 ; i != search_indices.size (); i++) {
534552 // TODO MT: Remove this dummy if statement
@@ -629,6 +647,7 @@ void HighsMipSolver::run() {
629647 std::deque<bool > infeasible;
630648 std::deque<bool > flush;
631649 std::vector<bool > prune (search_indices.size (), false );
650+ setParallelLock (true );
632651 for (HighsInt i = 0 ; i < search_indices.size (); i++) {
633652 // TODO MT: Remove this redundant if
634653 if (search_indices[i] != 0 || !mipdata_->workers [search_indices[i]]
@@ -658,6 +677,7 @@ void HighsMipSolver::run() {
658677 }
659678 }
660679 }
680+ setParallelLock (false );
661681
662682 // Remove search indices that need a new node
663683 HighsInt num_search_indices = static_cast <HighsInt>(search_indices.size ());
@@ -700,6 +720,7 @@ void HighsMipSolver::run() {
700720 [&](std::vector<HighsInt>& search_indices) -> bool {
701721 // the node is still not fathomed, so perform separation
702722 analysis_.mipTimerStart (kMipClockNodeSearchSeparation );
723+ setParallelLock (true );
703724 for (HighsInt i : search_indices) {
704725 // TODO MT: Get rid of this line
705726 if (i != 0 ) continue ;
@@ -715,6 +736,7 @@ void HighsMipSolver::run() {
715736 }
716737 analysis_.mipTimerStop (kMipClockNodeSearchSeparation );
717738 if (mipdata_->parallelLockActive ()) tg.taskWait ();
739+ setParallelLock (false );
718740
719741 for (HighsInt i : search_indices) {
720742 // TODO MT: Get rid of this line
@@ -765,6 +787,7 @@ void HighsMipSolver::run() {
765787 -analysis_.mipTimerRead (kMipClockTheDive ));
766788 std::vector<HighsSearch::NodeResult> dive_results (
767789 mip_search_concurrency, HighsSearch::NodeResult::kBranched );
790+ setParallelLock (true );
768791 if (mip_search_concurrency > 1 ) {
769792 for (int i = 0 ; i < mip_search_concurrency; i++) {
770793 tg.spawn ([&, i]() {
@@ -784,6 +807,7 @@ void HighsMipSolver::run() {
784807 dive_times[0 ] += analysis_.mipTimerRead (kMipClockNodeSearch );
785808 }
786809 }
810+ setParallelLock (false );
787811 bool suboptimal = false ;
788812 for (int i = 0 ; i < mip_search_concurrency; i++) {
789813 if (dive_times[i] != -1 ) {
0 commit comments