@@ -584,17 +584,24 @@ void HighsMipSolver::run() {
584584 setParallelLock (true );
585585 for (HighsInt i = 0 ; i != static_cast <HighsInt>(search_indices.size ());
586586 i++) {
587- if (mipdata_->parallelLockActive () && search_indices.size () > 1 ) {
587+ if (mipdata_->parallelLockActive () && search_indices.size () > 1 &&
588+ !options_mip_->mip_search_simulate_concurrency ) {
588589 tg.spawn ([&, i]() {
589590 search_results[i] =
590591 mipdata_->workers [search_indices[i]].search_ptr_ ->evaluateNode ();
591592 });
592593 } else {
594+ mipdata_->debugSolution .resetDomain (
595+ mipdata_->workers [search_indices[i]].search_ptr_ ->getLocalDomain ());
596+ mipdata_->debugSolution .registerDomain (
597+ mipdata_->workers [search_indices[i]].search_ptr_ ->getLocalDomain ());
593598 search_results[i] =
594599 mipdata_->workers [search_indices[i]].search_ptr_ ->evaluateNode ();
595600 }
596601 }
597- if (mipdata_->parallelLockActive ()) tg.taskWait ();
602+ if (mipdata_->parallelLockActive () && search_indices.size () > 1 &&
603+ !options_mip_->mip_search_simulate_concurrency )
604+ tg.taskWait ();
598605 setParallelLock (false );
599606 analysis_.mipTimerStop (kMipClockEvaluateNode1 );
600607 for (HighsInt i = 0 ; i != static_cast <HighsInt>(search_indices.size ());
@@ -687,19 +694,24 @@ void HighsMipSolver::run() {
687694 if (!mipdata_->workers [search_indices[i]]
688695 .search_ptr_ ->currentNodePruned ())
689696 continue ;
690- if (mipdata_->parallelLockActive () && search_indices.size () > 1 ) {
697+ if (mipdata_->parallelLockActive () && search_indices.size () > 1 &&
698+ !options_mip_->mip_search_simulate_concurrency ) {
691699 tg.spawn ([&, i]() {
692700 doHandlePrunedNodes (search_indices[i], mipdata_->parallelLockActive (),
693701 flush[i], infeasible[i]);
694702 });
695703 } else {
704+ mipdata_->debugSolution .resetDomain (
705+ mipdata_->workers [search_indices[i]].search_ptr_ ->getLocalDomain ());
706+ mipdata_->debugSolution .resetDomain (
707+ mipdata_->workers [search_indices[i]].search_ptr_ ->getLocalDomain ());
696708 doHandlePrunedNodes (search_indices[i], mipdata_->parallelLockActive (),
697709 flush[i], infeasible[i]);
698710 }
699711 // This search object is "finished" and needs a new node
700712 prune[i] = true ;
701713 }
702- if (mipdata_->parallelLockActive ()) {
714+ if (mipdata_->parallelLockActive () && search_indices. size () > 1 ) {
703715 tg.taskWait ();
704716 for (HighsInt i = 0 ; i < static_cast <HighsInt>(search_indices.size ()) &&
705717 i < static_cast <HighsInt>(flush.size ());
@@ -769,18 +781,25 @@ void HighsMipSolver::run() {
769781 analysis_.mipTimerStart (kMipClockNodeSearchSeparation );
770782 setParallelLock (true );
771783 for (HighsInt i : search_indices) {
772- if (mipdata_->parallelLockActive ()) {
784+ if (mipdata_->parallelLockActive () &&
785+ !options_mip_->mip_search_simulate_concurrency ) {
773786 tg.spawn ([&, i]() {
774787 mipdata_->workers [i].sepa_ptr_ ->separate (
775788 mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
776789 });
777790 } else {
791+ mipdata_->debugSolution .resetDomain (
792+ mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
793+ mipdata_->debugSolution .resetDomain (
794+ mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
778795 mipdata_->workers [i].sepa_ptr_ ->separate (
779796 mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
780797 }
781798 }
782799 analysis_.mipTimerStop (kMipClockNodeSearchSeparation );
783- if (mipdata_->parallelLockActive ()) tg.taskWait ();
800+ if (mipdata_->parallelLockActive () &&
801+ !options_mip_->mip_search_simulate_concurrency )
802+ tg.taskWait ();
784803 setParallelLock (false );
785804
786805 for (HighsInt i : search_indices) {
@@ -877,14 +896,19 @@ void HighsMipSolver::run() {
877896 setParallelLock (true );
878897 std::vector<HighsInt> search_indices = getSearchIndicesWithNodes ();
879898 for (HighsInt i : search_indices) {
880- if (mipdata_->parallelLockActive ()) {
899+ if (mipdata_->parallelLockActive () &&
900+ !options_mip_->mip_search_simulate_concurrency ) {
881901 tg.spawn ([&, i]() { doRunHeuristics (mipdata_->workers [i]); });
882902 } else {
903+ mipdata_->debugSolution .resetDomain (
904+ mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
905+ mipdata_->debugSolution .resetDomain (
906+ mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
883907 doRunHeuristics (mipdata_->workers [i]);
884908 }
885909 }
886910 if (mipdata_->parallelLockActive ()) {
887- tg.taskWait ();
911+ if (!options_mip_-> mip_search_simulate_concurrency ) tg.taskWait ();
888912 for (const HighsInt i : search_indices) {
889913 if (mipdata_->workers [i].search_ptr_ ->currentNodePruned ()) {
890914 ++mipdata_->num_leaves ;
@@ -906,7 +930,8 @@ void HighsMipSolver::run() {
906930 setParallelLock (true );
907931 for (HighsInt i = 0 ; i != static_cast <HighsInt>(mipdata_->workers .size ());
908932 ++i) {
909- if (mipdata_->hasMultipleWorkers ()) {
933+ if (mipdata_->hasMultipleWorkers () &&
934+ !options_mip_->mip_search_simulate_concurrency ) {
910935 tg.spawn ([&, i]() {
911936 if (!mipdata_->workers [i].search_ptr_ ->hasNode () ||
912937 mipdata_->workers [i].search_ptr_ ->currentNodePruned ()) {
@@ -921,12 +946,18 @@ void HighsMipSolver::run() {
921946 mipdata_->workers [i].search_ptr_ ->currentNodePruned ()) {
922947 dive_times[i] = -1 ;
923948 } else {
949+ mipdata_->debugSolution .resetDomain (
950+ mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
951+ mipdata_->debugSolution .resetDomain (
952+ mipdata_->workers [i].search_ptr_ ->getLocalDomain ());
924953 dive_results[i] = mipdata_->workers [i].search_ptr_ ->dive ();
925954 dive_times[i] += analysis_.mipTimerRead (kMipClockNodeSearch );
926955 }
927956 }
928957 }
929- if (mipdata_->hasMultipleWorkers ()) tg.taskWait ();
958+ if (mipdata_->hasMultipleWorkers () &&
959+ !options_mip_->mip_search_simulate_concurrency )
960+ tg.taskWait ();
930961 analysis_.mipTimerStop (kMipClockTheDive );
931962 setParallelLock (false );
932963 bool suboptimal = false ;
0 commit comments