Scippy

UG

Ubiquity Generator framework

bbParaLoadCoordinator.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and software framework */
4 /* UG --- Ubquity Generator Framework */
5 /* */
6 /* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7 /* Copyright (C) 2021 by Zuse Institute Berlin, */
8 /* licensed under LGPL version 3 or later. */
9 /* Commercial licenses are available through <licenses@zib.de> */
10 /* */
11 /* This code is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 /* */
24 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25 
26 /**@file paraLoadCoordinator.cpp
27  * @brief Load coordinator.
28  * @author Yuji Shinano
29  *
30  *
31  *
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #ifdef _MSC_VER
37 #include <functional>
38 #else
39 #include <unistd.h>
40 #endif
41 #include <cmath>
42 #include <ctime>
43 #include <cfloat>
44 #include <cstdio>
45 #include <cerrno>
46 #include <cstring>
47 #include <climits>
48 #include <algorithm>
49 #include <iomanip>
50 
51 #ifdef UG_WITH_ZLIB
52 #include "ug/gzstream.h"
53 #endif
54 #include "ug/paraInitialStat.h"
55 #include "bbParaLoadCoordinator.h"
56 #include "bbParaNode.h"
57 #include "bbParaNodesMerger.h"
58 
59 using namespace UG;
60 
62 #ifdef UG_WITH_UGS
63  UGS::UgsParaCommMpi *inCommUgs,
64 #endif
65  int inNHandlers,
66  ParaComm *inComm,
67  ParaParamSet *inParaParamSet,
68  ParaInitiator *inParaInitiator,
69  bool *inRacingSolversExist,
70  ParaTimer *inParaTimer,
71  ParaDeterministicTimer *inParaDetTimer
72  )
74 #ifdef UG_WITH_UGS
75  inCommUgs,
76 #endif
77  inNHandlers,
78  inComm,
79  inParaParamSet,
80  inParaInitiator,
81  inRacingSolversExist,
82  inParaTimer,
83  inParaDetTimer
84  ),
85  initialNodesGenerated(false),
86  firstCollectingModeState(-1),
87  isCollectingModeRestarted(false),
88  breakingSolverId(-1),
89  nReplaceToBetterNode(0),
90  nNormalSelection(-1),
91  winnerSolverNodesCollected(false),
92  primalUpdated(false),
93  restartingRacing(false),
94  nRestartedRacing(0),
95  statEmptyNodePoolTime(DBL_MAX),
96  minDepthInWinnerSolverNodes(INT_MAX),
97  maxDepthInWinnerSolverNodes(-1),
98  merging(false),
99  nBoundChangesOfBestNode(0),
100 // varIndexTable(0),
101 // mergeInfoHead(0),
102 // mergeInfoTail(0),
103  nodesMerger(0),
104  nCollectedSolvers(0),
105  previousTabularOutputTime(0.0),
106  averageDualBoundGain(0.0),
107  nAverageDualBoundGain(0),
108  averageLastSeveralDualBoundGains(0.0),
109  starvingTime(-1.0),
110  hugeImbalanceTime(-1.0),
111  paraNodePoolToRestart(0),
112  paraNodePoolBufferToRestart(0),
113  paraNodePoolBufferToGenerateCPF(0),
114  paraNodeToKeepCheckpointFileNodes(0),
115  unprocessedParaNodes(0),
116  selfSplitFinisedSolvers(0),
117  osTabularSolvingStatus(0),
118  osLogSubtreeInfo(0),
119  allCompInfeasibleAfterSolution(false),
120  minmalDualBoundNormalTermSolvers(DBL_MAX),
121  warmStartNodeTransferring(false),
122  hugeImbalance(false),
123  isHeaderPrinted(false),
124  givenGapIsReached(false),
125  aSolverTerminatedWithOptimality(false),
126  pendingSolution(0)
127 {
128 
129  BbMessageHandlerFunctionPointer *bbMessageHandler = reinterpret_cast<BbMessageHandlerFunctionPointer *>(messageHandler);
130 
137  {
140  }
141 
142  if( paraParams->getIntParamValue(UG::RampUpPhaseProcess) == 3 ) // Self-Split ramp-up
143  {
151  selfSplitFinisedSolvers = new std::set<int>;
152  }
153 
156  {
158 
159  /** register message handlers */
160  for( int i = 0; i < nHandlers; i++ )
161  {
163  }
164 
165  BbMessageHandlerFunctionPointer *bbRacingRampUpMessageHandler = reinterpret_cast<BbMessageHandlerFunctionPointer *>(racingRampUpMessageHandler);
166 
167  bbRacingRampUpMessageHandler[TagSolution] = &UG::BbParaLoadCoordinator::processTagSolution;
171  bbRacingRampUpMessageHandler[TagTerminated] = &UG::BbParaLoadCoordinator::processTagTerminated;
173  // racingRampUpMessageHandler[TagInitialStat] = &UG::BbParaLoadCoordinator::processTagInitialStat;
177  {
180  }
182  {
183  bbRacingRampUpMessageHandler[TagToken] = &UG::BbParaLoadCoordinator::processTagToken;
184  }
185  }
186 
188  {
190  {
191  std::cout << "EnhancedCheckpointStartTime mast be greater than 1.0. " << std::endl;
192  std::cout << "EnhancedCheckpointStartTime = " << paraParams->getRealParamValue(UG::EnhancedCheckpointStartTime) << std::endl;
193  exit(1);
194  }
196  {
197  std::cout << "EnhancedCheckpointStartTime mast be less than FinalCheckpointGeneratingTime. " << std::endl;
198  std::cout << "EnhancedCheckpointStartTime = " << paraParams->getRealParamValue(UG::EnhancedCheckpointStartTime) << std::endl;
199  std::cout << "FinalCheckpointGeneratingTime = " << paraParams->getRealParamValue(UG::FinalCheckpointGeneratingTime) << std::endl;
200  exit(1);
201  }
203  {
204  std::cout << "FinalCheckpointNSolvers mast be less equal than the number of solvers. " << std::endl;
205  std::cout << "FinalCheckpointNSolvers = " << paraParams->getIntParamValue(UG::FinalCheckpointNSolvers) << std::endl;
206  std::cout << "The number of solvers = " << (paraComm->getSize() - 1) << std::endl;
207  exit(1);
208  }
209  }
211  {
213  std::cout << "** FinalCheckpointGeneratingTime is specified, then TimeLimit is omitted. ** " << std::endl;
214  }
215 
216  // disply ramp-up mode
218  {
219  std::cout <<"LC is working with normal ramp-up." << std::endl;
220  }
222  {
223  std::cout <<"LC is working with racing ramp-up." << std::endl;
224  }
226  {
227  std::cout <<"LC is working with racing ramp-up and with rebuilding tree after racing." << std::endl;
228  }
230  {
231  std::cout <<"LC is working with self-split ramp-up." << std::endl;
232  }
233 
234  /* if initial solution is given, output the primal value */
235  if( logSolvingStatusFlag && dynamic_cast<BbParaInitiator *>(paraInitiator)->getGlobalBestIncumbentSolution() )
236  {
238  << " LC" << " INITIAL_PRIMAL_VALUE "
239  << dynamic_cast<BbParaInitiator *>(paraInitiator)->convertToExternalValue(
240  dynamic_cast<BbParaSolution *>(dynamic_cast<BbParaInitiator *>(paraInitiator)->getGlobalBestIncumbentSolution())->getObjectiveFunctionValue()
241  ) << std::endl;
242  }
243 
245  if( logSubtreeInfoFlag )
246  {
247  std::ostringstream s;
248 #ifdef UG_WITH_UGS
249  if( commUgs )
250  {
252  << commUgs->getMySolverName() << "_"
253  << paraInitiator->getParaInstance()->getProbName() << "_LC" << paraComm->getRank() << ".treelog";
254  }
255  else
256  {
258  << paraInitiator->getParaInstance()->getProbName() << "_LC" << paraComm->getRank() << ".treelog";
259  }
260 #else
262  << paraInitiator->getParaInstance()->getProbName() << "_LC" << paraComm->getRank() << ".treelog";
263 #endif
264  ofsLogSubtreeInfo.open(s.str().c_str(), std::ios::app );
265  if( !ofsLogSubtreeInfo )
266  {
267  std::cout << "Sub tree info. log file cannot open : file name = " << s.str() << std::endl;
268  exit(1);
269  }
271  }
272 
275  {
277  {
278  osTabularSolvingStatus = &std::cout;
279  }
280  else
281  {
282  std::ostringstream s;
283 #ifdef UG_WITH_UGS
284  if( commUgs )
285  {
287  << commUgs->getMySolverName() << "_"
288  << paraInitiator->getParaInstance()->getProbName() << "_LC" << paraComm->getRank() << "_T.status";
289  }
290  else
291  {
293  << paraInitiator->getParaInstance()->getProbName() << "_LC" << paraComm->getRank() << "_T.status";
294  }
295 #else
297  << paraInitiator->getParaInstance()->getProbName() << "_LC" << paraComm->getRank() << "_T.status";
298 #endif
299  ofsTabularSolvingStatus.open(s.str().c_str(), std::ios::app );
301  {
302  std::cout << "Tabular solving status file cannot open : file name = " << s.str() << std::endl;
303  exit(1);
304  }
306  }
307 // if( outputTabularSolvingStatusFlag )
308 // {
309 // outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
310 // }
311  }
312 
313  paraSolverPool = new BbParaSolverPoolForMinimization( // always minimization problem
317  1, // paraSolver origin rank
319 
320  // always minimization problem
321  if( paraParams->getBoolParamValue(CleanUp) )
322  {
323  paraNodePool = new BbParaNodePoolForCleanUp(paraParams->getRealParamValue(BgapCollectingMode));
324  }
325  else
326  {
327  paraNodePool = new BbParaNodePoolForMinimization(paraParams->getRealParamValue(BgapCollectingMode));
328  }
329 
330  if( paraParams->getIntParamValue(NSolverNodesStartBreaking) == 0 ||
331  paraParams->getIntParamValue(NStopBreaking) == 0 )
332  {
333  isBreakingFinised = true;
334  }
335  else
336  {
337  isBreakingFinised = false;
338  }
339 
340  if( paraParams->getBoolParamValue(NChangeIntoCollectingModeNSolvers) )
341  {
342  paraParams->setIntParamValue(NChangeIntoCollectingMode, std::max((paraSolverPool->getNSolvers()/2), (size_t)1) );
343  }
344 
345  if( !EPSEQ( paraParams->getRealParamValue(RandomNodeSelectionRatio), 0.0, MINEPSILON ) )
346  {
347  nNormalSelection = -1;
348  }
349 
350  if( !paraParams->getBoolParamValue(CollectOnce) ||
351  !( paraParams->getIntParamValue(RampUpPhaseProcess) == 1 || paraParams->getIntParamValue(RampUpPhaseProcess) == 2 ) )
352  {
354  }
355 
356  if( paraParams->getBoolParamValue(UG::GenerateReducedCheckpointFiles) )
357  {
358  if( !( paraInitiator->getPrefixWarm() &&
359  paraParams->getBoolParamValue(UG::MergeNodesAtRestart) &&
360  !paraParams->getBoolParamValue(UG::DualBoundGainTest) ) )
361  {
362  std::cout << "** -w opttion = " << paraInitiator->getPrefixWarm() << " **" << std::endl;
363  std::cout << "** MergeNodesAtRestart = " << paraParams->getBoolParamValue(UG::MergeNodesAtRestart) << std::endl;
364  std::cout << "** DualBoundGainTest = " << paraParams->getBoolParamValue(UG::DualBoundGainTest) << std::endl;
365  std::cout << "** GenerateReducedCheckpointFiles is specified, then this solver shuld be executed with"
366  << "-w option and MergeNodesAtRestart = TRUE and DualBoundGainTest = FALSE ** " << std::endl;
367  exit(1);
368  }
370  }
371 
372  nBoundChangesOfBestNode = paraParams->getIntParamValue(UG::NBoundChangesOfMergeNode);
373 }
374 
376  )
377 {
378  // std::cout << "In: nTerminated = " << nTerminated << std::endl;
384  )
385  )
386  {
389  {
392  }
393  // assert( runningPhase == TerminationPhase );
394 
395  int source;
396  int tag;
397 
398  for(;;)
399  {
400  /*******************************************
401  * waiting for any message form anywhere *
402  *******************************************/
403  double inIdleTime = paraTimer->getElapsedTime();
404  (void)paraComm->probe(&source, &tag);
405  lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
406  if( messageHandler[tag] )
407  {
408  int status = (this->*messageHandler[tag])(source, tag);
409  if( status )
410  {
411  std::ostringstream s;
412  s << "[ERROR RETURN form termination message handler]:" << __FILE__ << "] func = "
413  << __func__ << ", line = " << __LINE__ << " - "
414  << "process tag = " << tag << std::endl;
415  abort();
416  }
417  }
418  else
419  {
420  ABORT_LOGICAL_ERROR3( "No message handler for ", tag, " is not registered" );
421  }
422 
423 #ifdef UG_WITH_UGS
424  if( commUgs ) checkAndReadIncumbent();
425 #endif
426 
427  // std::cout << "Loop: nTerminated = " << nTerminated << std::endl;
428  if( nTerminated == paraSolverPool->getNSolvers() ) break;
429  }
430  }
431 
432 // for( int i = 1; i <= paraSolverPool->getNSolvers(); i++ )
433 // {
434 // paraComm->send( NULL, 0, ParaBYTE, i, TagTerminated);
435 // }
436 
437  /** write final solution */
438  paraInitiator->writeSolution("Final Solution");
439 
440 #ifdef UG_WITH_ZLIB
441  /* wite final checkpoint file */
443  {
446  {
448  paraNodePool->insert(node);
449  }
450  updateCheckpointFiles();
451  }
452  else
453  {
454  if( interruptIsRequested &&
456  {
457  updateCheckpointFiles();
458  }
459  }
460 #endif
461 
463  {
464  int nKeepingNodes = 0;
465  int nNoProcessedNodes = 0;
467  {
469  {
472  }
474  {
475  nNoProcessedNodes = unprocessedParaNodes->getNumOfNodes();
476  }
477  *osLogTasksTransfer << std::endl << "BbParaLoadCoordinator: # received = " << lcts.nReceived
478  << ", # sent = " << lcts.nSent << ", # sent immediately = " << lcts.nSentBackImmediately << ", # deleted = " << lcts.nDeletedInLc
479  << ", # failed to send back = " << lcts.nFailedToSendBack
480  << ", Max usage of node pool = " << paraNodePool->getMaxUsageOfPool() + nKeepingNodes + nNoProcessedNodes << std::endl;
481  *osLogTasksTransfer << "# sent immediately ( another node ) = " << lcts.nSentBackImmediatelyAnotherNode
482  << ", # # failed to send back ( another node ) = " << lcts.nFailedToSendBackAnotherNode << std::endl;
483  if( !paraNodePool->isEmpty() ){
484  *osLogTasksTransfer << "LoadCoodibator: NodePool in LoadCoordinatator is not empty: "
485  << paraNodePool->getNumOfNodes() + nKeepingNodes + nNoProcessedNodes << " nodes remained" << std::endl;
486  }
488  {
489  *osLogTasksTransfer << "LoadCoodibator: NodePool in LoadCoordinatator is not empty: "
490  << (nKeepingNodes + nNoProcessedNodes) << " nodes remained" << std::endl;
491  }
492  }
493  lcts.nMaxUsageOfNodePool = paraNodePool->getMaxUsageOfPool() + nKeepingNodes + nNoProcessedNodes;
495  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool) ) // paraSolverPool may not be always BbParaSolverPoolForMinimization
496  {
497  lcts.mMaxCollectingNodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getMMaxCollectingNodes();
498  }
499  else
500  {
502  }
503  lcts.nNodesInNodePool = paraNodePool->getNumOfNodes() + nKeepingNodes + nNoProcessedNodes;
504  }
505 
506  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
507 
508  // set final solving status
510  {
512  }
513  else
514  {
516  {
518  }
519  else if( memoryLimitIsReached )
520  {
521  bbParaInitiator->setFinalSolverStatus(MemoryLimitIsReached);
522  }
523  else if ( givenGapIsReached )
524  {
525  bbParaInitiator->setFinalSolverStatus(GivenGapIsReached);
526  }
527  else
528  {
531  {
533  }
534  else
535  {
537  {
538 #ifdef UG_WITH_ZLIB
539  updateCheckpointFiles();
540 #endif
542  }
543  else
544  {
545  bbParaInitiator->setFinalSolverStatus(ProblemWasSolved);
546  }
548  {
549  outputTabularSolvingStatus(' '); /// this function cannot be overwritten, should turn off outputTabularSolvingStatusFlag, before destruct
550  }
551  }
552  }
553  }
554 
555 
556  // set number of nodes solved and final dual bound value
558  {
559  *osTabularSolvingStatus << "*** This is GenerateReducedCheckpointFiles run ***" << std::endl;
561  {
562  *osTabularSolvingStatus << "*** Current checkpoint-data have " <<
564  << " nodes."
566  << " initially keeping nodes by the run-time parameter."
567  << std::endl;
568  }
569  else
570  {
571  *osTabularSolvingStatus << "*** Current checkpoint-data have " << paraNodePool->getNumOfNodes()
572  << " nodes." << std::endl;
573  }
574 
575  }
576  else
577  {
579  {
580  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool) ) // paraSolverPool may not be always BbParaSolverPoolForMinimization
581  {
582  bbParaInitiator->setNumberOfNodesSolved( std::max(1ULL, dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getTotalNodesSolved()) );
583  }
584  else
585  {
586  bbParaInitiator->setNumberOfNodesSolved(1ULL); // always set 1 : no meaning
587  }
588  bbParaInitiator->setDualBound(paraNodePool->getBestDualBoundValue());
590  }
591  else
592  {
593  if( racingTermination )
594  {
596  {
597  bbParaInitiator->setNumberOfNodesSolved(dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver());
598  }
599  else
600  {
602  }
604  {
606  }
607  if( !givenGapIsReached )
608  {
610  {
612  }
613  }
614  if( paraNodePool->getNumOfNodes() > 0 )
615  {
617  }
618  bbParaInitiator->setDualBound(lcts.globalBestDualBoundValue);
620  }
621  else
622  {
624  {
625  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool) ) // paraSolverPool may not be always BbParaSolverPoolForMinimization
626  {
627  bbParaInitiator->setNumberOfNodesSolved( std::max(1ULL, dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getTotalNodesSolved()) );
628  }
629  else
630  {
631  bbParaInitiator->setNumberOfNodesSolved(1ULL); // always set 1 : no meaning
632  }
633 
635  {
637  if( paraNodePool->getNumOfNodes() > 0 )
638  {
640  }
641  bbParaInitiator->setDualBound(lcts.globalBestDualBoundValue);
643  }
644  else
645  {
647  {
648  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
649  {
652  }
653  else
654  {
656  }
657  }
658  if( paraNodePool->getNumOfNodes() > 0 )
659  {
661  }
662  bbParaInitiator->setDualBound(lcts.globalBestDualBoundValue);
664  }
665  }
666  else
667  {
668  if( paraNodePool->getNumOfNodes() > 0 )
669  {
671  }
673  {
675  {
676  bbParaInitiator->setDualBound(lcts.globalBestDualBoundValue);
677  bbParaInitiator->setNumberOfNodesSolved( dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver() );
678  }
679  else
680  {
681  ABORT_LOGICAL_ERROR1("Computation is interrupted in racing stage, but no paraRacingSolverPool");
682  }
683  }
684  else
685  {
686  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool) ) // paraSolverPool may not be always BbParaSolverPoolForMinimization
687  {
688  bbParaInitiator->setNumberOfNodesSolved( std::max(1ULL, dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers()) );
689  }
690  else
691  {
692  bbParaInitiator->setNumberOfNodesSolved(1ULL); // always set 1 : no meaning
693  }
694  bbParaInitiator->setDualBound(lcts.globalBestDualBoundValue);
695  }
697  }
698  }
699  }
700 
702  if( (!racingTermination) &&
703  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool) && // could be a specialized SolverPool for a specific problem solver
704  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getTotalNodesSolved() != dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers() )
705  {
706  *osTabularSolvingStatus << "* Warning: the number of nodes (total) including nodes solved by interrupted Solvers is "
707  << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers() << std::endl;
708  }
709  }
710 
711  if( racingWinnerParams )
712  {
713  delete racingWinnerParams;
714  }
715 
716  if( paraSolverPool && osStatisticsFinalRun && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool) ) // paraSolverPool may not be always BbParaSolverPoolForMinimization
717  {
718  lcts.nNodesLeftInAllSolvers = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers();
719  *osStatisticsFinalRun << "######### The number of nodes solved in all solvers: "
720  << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getTotalNodesSolved();
721  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getTotalNodesSolved() != dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers() )
722  {
723  *osStatisticsFinalRun << " : "
724  << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers();
725  }
726  *osStatisticsFinalRun << " #########" << std::endl;
727  }
728  // if( paraSolverPool ) delete paraSolverPool;
729 
732  {
733  *osLogSolvingStatus << lcts.runningTime << " BbParaLoadCoordinator_TERMINATED" << std::endl;
735  {
737  << paraRacingSolverPool->getNumActiveSolvers() << " active racing ramp-up solvers exist." << std::endl;
738  }
739  }
740 #ifdef _DEBUG_LB
741  std::cout << lcts.runningTime << " BbParaLoadCoordinator_TERMINATED" << std::endl;
743  {
744  std::cout << lcts.runningTime << " "
745  << paraRacingSolverPool->getNumActiveSolvers() << " active racing ramp-up solvers exist." << std::endl;
746  }
747 #endif
748 
749 
750  lcts.isCheckpointState = false;
752  {
753  std::cout << lcts.toString() << std::endl;
754  }
755 
757  {
759  }
760 
762  {
763  *osStatisticsFinalRun << "***** <<< NOTE >>> "
765  << " active racing ramp-up solvers exist." << std::endl;
766  *osStatisticsFinalRun << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getStrActiveSolerNumbers() << std::endl;
767  }
768 
770  {
771  delete paraRacingSolverPool;
773  *racingSolversExist = true;
774  }
775 
777  {
778  osStatisticsFinalRun->flush();
779  }
780 
781  if( nodesMerger ) delete nodesMerger;
782 
783  if( paraNodePool ) delete paraNodePool;
789 
790 }
791 
792 void
794  )
795 {
796  terminationIssued = true;
797  int exitSolverRequest = 0; // do nothing
798  for( int i = 1; i < paraComm->getSize(); i++ )
799  {
800  if( ( i < static_cast<int>(paraSolverPool->getNSolvers()) + 1 && paraSolverPool->isSolverActive(i) && !paraSolverPool->isInterruptRequested(i) ) ||
802  {
803  if( !paraSolverPool->isInterruptRequested(i) && !paraSolverPool->isTerminateRequested(i) ) /// even if racing solver is running, paraSolverPool flag is used
804  {
806  paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
807  );
809  }
810  }
811  if( i < static_cast<int>(paraSolverPool->getNSolvers()) + 1 && !paraSolverPool->isTerminateRequested(i) )
812  {
814  paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
815  );
818  {
819  int token[2];
820  token[0] = i;
821  token[1] = -2;
823  paraComm->send( token, 2, ParaINT, token[0], TagToken )
824  );
825  }
826  }
827  }
828 }
829 
830 int
832  int source,
833  int tag
834  )
835 {
836 
837  BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
838  paraNode->receive(paraComm, source);
839 
840 // std::cout << "S." << source
841 // << ", SEND: nBoundChanges = " << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges() << std::endl;
842 
843  // std::cout << "processTagTask: " << paraNode->toString() << std::endl;
844 
845 #ifdef UG_DEBUG_SOLUTION
846 #ifdef UG_DEBUG_SOLUTION_OPT_PATH
847  if( paraNode->getDiffSubproblem() && (!paraNode->getDiffSubproblem()->isOptimalSolIncluded()) )
848  {
849  delete paraNode;
851  paraComm->send( NULL, 0, ParaBYTE, source, TagTaskReceived);
852  );
853  return 0;
854  }
855 #endif
856 #endif
857 
858  // std::cout << paraTimer->getElapsedTime()<< " S." << source << " nodeId = " << paraNode->toSimpleString() << " is recived" << std::endl;
859 
860  lcts.nReceived++;
861 
863  {
864  delete paraNode;
865  return 0;
866  }
867 
868  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
869 
870  if( ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
871  paraNode->getDualBoundValue() < bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() ) ||
872  !( bbParaInitiator->getGlobalBestIncumbentSolution() ) )
873  {
875  /** in the case that ParaNode received from LoadCoordinator is not implemented yet */
876  ParaTask *ancestorNode = paraSolverPool->getCurrentTask(source);
877  paraNode->setAncestor(
878  new ParaTaskGenealogicalLocalPtr( ancestorNode->getTaskId(), ancestorNode ));
879  ancestorNode->addDescendant(
880  new ParaTaskGenealogicalLocalPtr( paraNode->getTaskId(), paraNode) );
881  if( hugeImbalance )
882  {
885  {
886  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
888  << " S." << source
889  << " |pb< "
890  << bbParaInitiator->convertToExternalValue(
891  paraNode->getDualBoundValue() )
892  << " "
893  << paraNode->toSimpleString();
894  if( paraNode->getDiffSubproblem() )
895  {
897  << ", "
898  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
899  << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
900  }
901  *osLogSolvingStatus << std::endl;
902  }
903  }
904  else
905  {
906  paraNodePool->insert(paraNode);
908  {
909  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
911  << " S." << source
912  << " |p< "
913  << bbParaInitiator->convertToExternalValue(
914  paraNode->getDualBoundValue() )
915  << " "
916  << paraNode->toSimpleString();
917  if( paraNode->getDiffSubproblem() )
918  {
920  << ", "
921  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
922  << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
923  }
924  *osLogSolvingStatus << std::endl;
925  }
926  }
927  if( merging )
928  {
929  assert(nodesMerger);
931  }
932 
934  source == racingWinner &&
936  {
937  if( minDepthInWinnerSolverNodes > paraNode->getDepth() )
938  {
940  }
941  }
942 
944  // In racing stage, some solver could take time for solving a node
945  // Therefore, some solver could stay idle so long time in paraSolverPool
946  // However, node collecting has to terminated to sending switch out message
947  {
948  // paraNodePool->insert(paraNode);
949  /** switch-out request might be delayed to reach the target solver.
950  * This behavior affects load balancing sometimes.
951  * Therefore, if additional nodes are received, sends switch-out request again.
952  //if( runningPhase != RampUpPhase && !(paraSolverPool->isInCollectingMode()) )
953  //{
954  // paraSolverPool->enforcedSwitchOutCollectingMode(source);
955  //}
956  ** I don't want to do this. So, I decided to wait message after each notification when LC in collecting mode if necessary */
957  // without consideration of keeping nodes in checkpoint file
958  double globalBestDualBoundValueLocal =
959  std::max (
960  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
962  if( runningPhase != RampUpPhase && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() &&
963  ( ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
966  ) ||
971  ) ) ) )
972  {
973  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
976  }
977  }
978  }
979  else
980  {
981  assert( !( EPSLT( paraNode->getDualBoundValue(), bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue(), eps) ) );
982 #ifdef UG_DEBUG_SOLUTION
983  if( paraNode->getDiffSubproblem() && paraNode->getDiffSubproblem()->isOptimalSolIncluded() )
984  {
985  throw "Optimal solution going to be killed.";
986  }
987 #endif
988  delete paraNode;
989  lcts.nDeletedInLc++;
990  if( runningPhase != RampUpPhase && !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode()) &&
992  paraNodePool->isEmpty() )
993  { // inactive solver exists but cannot send a ParaNode to it
994  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
995  if( firstCollectingModeState == -1 && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() ) firstCollectingModeState = 0;
996  }
997  }
998 
1000  paraComm->send( NULL, 0, ParaBYTE, source, TagTaskReceived);
1001  );
1002 
1003  return 0;
1004 }
1005 
1006 int
1008  int source,
1009  int tag
1010  )
1011 {
1012 
1013  BbParaSolution *sol = dynamic_cast<BbParaSolution *>(paraComm->createParaSolution());
1014  sol->receive(paraComm, source);
1015 
1016  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
1017 
1018 #ifdef _DEBUG_DET
1019  if( logSolvingStatusFlag )
1020  {
1022  << " S." << source << " R.SOL "
1023  << bbParaInitiator->convertToExternalValue(
1025  ) << std::endl;
1026  }
1027 #endif
1028 
1029  if( updateSolution(sol) )
1030  {
1031  delete sol;
1033  {
1034  if( bbParaInitiator->canGenerateSpecialCutOffValue() )
1035  {
1036  sendCutOffValue(source);
1037  }
1038  sendIncumbentValue(source);
1039  }
1040  primalUpdated = true;
1042  if( logSolvingStatusFlag )
1043  {
1045  << " S." << source << " I.SOL "
1046  << bbParaInitiator->convertToExternalValue(
1048  ) << std::endl;
1049  }
1050 #ifdef _DEBUG_LB
1051  std::cout << paraTimer->getElapsedTime()
1052  << " S." << source << " I.SOL "
1053  << paraInitiator->convertToExternalValue(
1054  paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue()
1055  ) << std::endl;
1056 #endif
1057  /** output tabular solving status */
1059  {
1061  }
1062 #ifdef UG_WITH_ZLIB
1063  /* Do not have to remove ParaNodes from NodePool. It is checked and removed before sending them */
1064  /** save incumbent solution */
1065  char solutionFileNameTemp[MaxStrLen];
1066  char solutionFileName[MaxStrLen];
1068  {
1069  snprintf(solutionFileNameTemp, MaxStrLen, "%s%s_after_checkpointing_solution_t.gz",
1072  paraInitiator->writeCheckpointSolution(std::string(solutionFileNameTemp));
1073  snprintf(solutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
1076  if ( rename(solutionFileNameTemp, solutionFileName) )
1077  {
1078  std::cout << "after checkpointing solution file cannot be renamed: errno = " << strerror(errno) << std::endl;
1079  exit(1);
1080  }
1081  }
1082 #endif
1083 #ifdef UG_WITH_UGS
1084  if( commUgs )
1085  {
1086  paraInitiator->writeUgsIncumbentSolution(commUgs);
1087  }
1088 #endif
1089  }
1090  else
1091  {
1092  delete sol;
1093  }
1094  return 0;
1095 }
1096 
1097 int
1099  int source,
1100  int tag
1101  )
1102 {
1103 
1104  double globalBestDualBoundValue = -DBL_MAX;
1105  double globalBestDualBoundValueLocal = -DBL_MAX;
1106 
1107  BbParaSolverState *solverState = dynamic_cast<BbParaSolverState *>(paraComm->createParaSolverState());
1108  solverState->receive(paraComm, source, tag);
1109 
1110  if( paraDetTimer
1111  && paraDetTimer->getElapsedTime() < solverState->getDeterministicTime() )
1112 
1113  {
1115  }
1116 
1117  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
1118 
1119  if( solverState->isRacingStage() )
1120  {
1121  globalBestDualBoundValueLocal = globalBestDualBoundValue =
1122  std::min(
1123  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(),
1126 
1127  /** not update paraSolverPool. The solver is inactive in paraSolverPool */
1128  if( logSolvingStatusFlag )
1129  {
1131  << " S." << source << " | "
1132  << bbParaInitiator->convertToExternalValue(
1133  solverState->getSolverLocalBestDualBoundValue()
1134  );
1135  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
1136  bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) > displayInfOverThisValue )
1137  {
1138  *osLogSolvingStatus << " ( Inf )";
1139  }
1140  else
1141  {
1142  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
1143  }
1144  *osLogSolvingStatus << " [ " << solverState->getNNodesLeft() << " ]";
1145  *osLogSolvingStatus << " ** G.B.: " << bbParaInitiator->convertToExternalValue(globalBestDualBoundValue);
1146  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
1147  bbParaInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
1148  {
1149  *osLogSolvingStatus << " ( Inf ) ";
1150  }
1151  else
1152  {
1153  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
1154  }
1155  *osLogSolvingStatus << "[ " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() << ", " << paraNodePool->getNumOfNodes()
1156  << " ( " << paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
1157  <<" ) ] ** R" << std::endl;
1158  // <<" ) ] ** RR " << solverState->getDeterministicTime() << std::endl; // for debug
1159 
1160  }
1161 #ifdef _DEBUG_LB
1162  std::cout << paraTimer->getElapsedTime()
1163  << " S." << source << " | "
1164  << paraInitiator->convertToExternalValue(
1165  solverState->getSolverLocalBestDualBoundValue()
1166  );
1167  if( !paraInitiator->getGlobalBestIncumbentSolution() ||
1169  {
1170  std::cout << " ( Inf )";
1171  }
1172  else
1173  {
1174  std::cout << " ( " << paraInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
1175  }
1176  std::cout << " [ " << solverState->getNNodesLeft() << " ]";
1177  globalBestDualBoundValue =
1178  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() );
1179  std::cout << " ** G.B.: " << paraInitiator->convertToExternalValue(globalBestDualBoundValue);
1180  if( !paraInitiator->getGlobalBestIncumbentSolution() ||
1181  paraInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
1182  {
1183  std::cout << " ( Inf ) ";
1184  }
1185  else
1186  {
1187  std::cout << " ( " << paraInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
1188  }
1189  std::cout << "[ " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() << ", " << paraNodePool->getNumOfNodes()
1190  << " ( " << paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
1191  <<" ) ] ** RR" << std::endl;
1192 #endif
1193  }
1194  else
1195  {
1196  if( !dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverActive(source) )
1197  {
1199  {
1200  delete solverState;
1201  return 0;
1202  }
1203  }
1204  assert( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
1205  double solverDualBoundGain = 0.0;
1206  double sum = 0.0;
1207  if(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source) == 0
1208  && solverState->getNNodesSolved() > 0
1209  && !paraSolverPool->getCurrentTask(source)->isRootTask() )
1210  {
1211  solverDualBoundGain = solverState->getSolverLocalBestDualBoundValue() - dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source))->getDualBoundValue();
1212  if( logSolvingStatusFlag )
1213  {
1215  << " S." << source << " G " << paraSolverPool->getCurrentTask(source)->toSimpleString()
1216  << ", a:" << averageDualBoundGain
1217  << ", ma:" << averageLastSeveralDualBoundGains
1218  << ", g:" << solverDualBoundGain;
1219  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isDualBounGainTesting(source) )
1220  {
1221  *osLogSolvingStatus << ", T";
1222  }
1224  << std::endl;
1225  }
1226  lastSeveralDualBoundGains.push_back(solverDualBoundGain);
1227  for(int i = 0; i < static_cast<int>(lastSeveralDualBoundGains.size()); i++ )
1228  {
1229  sum += lastSeveralDualBoundGains[i];
1230  }
1233  averageDualBoundGain * ( static_cast<double>(nAverageDualBoundGain)/(static_cast<double>(nAverageDualBoundGain) + 1.0) )
1234  + solverDualBoundGain * ( 1.0/(static_cast<double>(nAverageDualBoundGain) + 1.0 ) );
1235  if( lastSeveralDualBoundGains.size() > 7 )
1236  {
1237  lastSeveralDualBoundGains.pop_front();
1238  }
1240  }
1241 
1242 // std::cout << "R." << source
1243 // << ": solverState->getNNodesSolved() = " << solverState->getNNodesSolved()
1244 // << ", dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved = "
1245 // << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)
1246 // << ", solverState->getNNodesLeft() = " << solverState->getNNodesLeft() << std::endl;
1247 // assert( solverState->getNNodesSolved() >= dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source) );
1248  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->updateSolverStatus(source,
1249  solverState->getNNodesSolved(),
1250  solverState->getNNodesLeft(),
1251  solverState->getSolverLocalBestDualBoundValue(),
1252  paraNodePool
1253  );
1254 
1256  {
1257  globalBestDualBoundValue = paraNodeToKeepCheckpointFileNodes->getBestDualBoundValue();
1258  globalBestDualBoundValueLocal =
1259  std::max (
1260  std::min(
1261  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(),
1265  }
1267  {
1268  globalBestDualBoundValue = globalBestDualBoundValueLocal =
1269  std::max (
1270  std::min(
1271  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
1272  // minmalDualBoundNormalTermSolvers ), /// should not be in racing start
1275  }
1276  else
1277  {
1279  {
1280  globalBestDualBoundValueLocal = globalBestDualBoundValue =
1281  std::min(
1282  std::min(
1284  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() ),
1286  }
1287  else
1288  {
1289  if( isRacingStage() || racingTermination )
1290  {
1291  globalBestDualBoundValueLocal = globalBestDualBoundValue =
1292  std::max (
1293  std::min(
1294  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
1297  }
1298  else
1299  {
1300  globalBestDualBoundValueLocal = globalBestDualBoundValue =
1301  std::max (
1302  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
1304  }
1305 
1306  }
1307  }
1308 
1309  if( logSolvingStatusFlag )
1310  {
1312  << " S." << source << " | "
1313  << bbParaInitiator->convertToExternalValue(
1314  solverState->getSolverLocalBestDualBoundValue()
1315  );
1316  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
1317  bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) > displayInfOverThisValue )
1318  {
1319  *osLogSolvingStatus << " ( Inf )";
1320  }
1321  else
1322  {
1323  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
1324  }
1325  *osLogSolvingStatus << " [ " << solverState->getNNodesLeft() << " ]";
1326  *osLogSolvingStatus << " ** G.B.: " << bbParaInitiator->convertToExternalValue(globalBestDualBoundValue);
1327  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
1328  bbParaInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
1329  {
1330  *osLogSolvingStatus << " ( Inf ) ";
1331  }
1332  else
1333  {
1334  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
1335  }
1336  *osLogSolvingStatus << "[ " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() << ", " << paraNodePool->getNumOfNodes()
1337  << " ( " << paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
1338  <<" ) ] **";
1339  if( runningPhase == RampUpPhase ) *osLogSolvingStatus << " R";
1340  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() )
1341  {
1342  *osLogSolvingStatus << " C";
1343  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverInCollectingMode(source) )
1344  {
1345  *osLogSolvingStatus << " 1";
1346  }
1347  else
1348  {
1349  *osLogSolvingStatus << " 0";
1350  }
1351 
1352  }
1353  *osLogSolvingStatus << " " << solverState->getDeterministicTime(); // for debug
1355  {
1357  }
1358  *osLogSolvingStatus << std::endl;
1359 
1360  /** log the number of nodes transfer */
1362  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers() > lcts.nNodesOutputLog )
1363  {
1365  *osLogSolvingStatus << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers()
1366  << " " << (dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() + paraNodePool->getNumOfNodes())
1367  << " s " << lcts.nSent << " r " << lcts.nReceived
1368  << std::endl;
1370  ( ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers()/paraParams->getIntParamValue(NNodesTransferLogging) )+1)
1372  }
1373 
1376  {
1378  *osLogSolvingStatus << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers()
1379  << " " << (dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() + paraNodePool->getNumOfNodes())
1380  << " s " << lcts.nSent << " r " << lcts.nReceived
1381  << std::endl;
1384  }
1385  }
1386 
1387  BbParaNode *node = dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source));
1388  if( node->getMergeNodeInfo() != 0 && solverState->getNNodesSolved() > 2 ) // I stand on the safety side. we can write "> 1"
1389  {
1390  assert(nodesMerger);
1393  {
1394  // std::cout << "S." << source << " ParaNode is saved to Buffer." << std::endl;
1395  assert( !node->getMergeNodeInfo() );
1397  }
1398  }
1399 
1400 #ifdef _DEBUG_LB
1401  std::cout << paraTimer->getElapsedTime()
1402  << " S." << source << " | "
1403  << paraInitiator->convertToExternalValue(
1404  solverState->getSolverLocalBestDualBoundValue()
1405  );
1406  if( !paraInitiator->getGlobalBestIncumbentSolution() ||
1408  {
1409  std::cout << " ( Inf )";
1410  }
1411  else
1412  {
1413  std::cout << " ( " << paraInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
1414  }
1415  std::cout << " [ " << solverState->getNNodesLeft() << " ]";
1416  globalBestDualBoundValue =
1417  std::max (
1418  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
1420  std::cout << " ** G.B.: " << paraInitiator->convertToExternalValue(globalBestDualBoundValue);
1421  if( !paraInitiator->getGlobalBestIncumbentSolution() ||
1422  paraInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
1423  {
1424  std::cout << " ( Inf ) ";
1425  }
1426  else
1427  {
1428  std::cout << " ( " << paraInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
1429  }
1430  std::cout << "[ " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() << ", " << paraNodePool->getNumOfNodes()
1431  << " ( " << paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
1432  <<" ) ] **";
1433  if( runningPhase == RampUpPhase ) std::cout << " R";
1434  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() )
1435  {
1436  std::cout << " C";
1437  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverInCollectingMode(source) )
1438  {
1439  std::cout << " 1";
1440  }
1441  else
1442  {
1443  std::cout << " 0";
1444  }
1445 
1446  }
1447  std::cout << std::endl;
1448 #endif
1449 
1450  }
1451 
1452  /** the following should be before noticationId back to the source solver */
1454  {
1455  if( bbParaInitiator->getGlobalBestIncumbentSolution() &&
1457  < solverState->getGlobalBestPrimalBoundValue() )
1458  {
1459  bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, source);
1460  }
1461  }
1462 
1463  // if( paraParams->getBoolParamValue(CheckGapInLC) )
1464  // std::cout << "givenGapIsReached = " << givenGapIsReached << std::endl;
1465  if( !givenGapIsReached )
1466  {
1467  // std::cout << "absgap = " <<
1468  // bbParaInitiator->getAbsgap(globalBestDualBoundValue) <<
1469  // ", abs gap value = " << bbParaInitiator->getAbsgapValue() << std::endl;
1470  // std::cout << "gap = " <<
1471  // bbParaInitiator->getGap(globalBestDualBoundValue) <<
1472  // ", gap value = " << bbParaInitiator->getGapValue() << std::endl;
1473  if( bbParaInitiator->getAbsgap(globalBestDualBoundValue) < bbParaInitiator->getAbsgapValue() ||
1474  bbParaInitiator->getGap(globalBestDualBoundValue) < bbParaInitiator->getGapValue() )
1475  {
1476  // std::cout << "current dual = " << bbParaInitiator->convertToExternalValue(solverState->getSolverLocalBestDualBoundValue()) <<std::endl;
1477  // std::cout << "current gap = " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) <<std::endl;
1478  for( unsigned int i = 1; i <= paraSolverPool->getNSolvers(); i++ )
1479  {
1481  {
1483  paraComm->send( NULL, 0, ParaBYTE, i, TagGivenGapIsReached )
1484  );
1486  }
1487 
1488  }
1489  givenGapIsReached = true;
1490  }
1491  else
1492  {
1493  if( bbParaInitiator->getAbsgap(solverState->getSolverLocalBestDualBoundValue()) < bbParaInitiator->getAbsgapValue() ||
1494  bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) < bbParaInitiator->getGapValue() )
1495  {
1497  {
1499  paraComm->send( NULL, 0, ParaBYTE, source, TagGivenGapIsReached )
1500  );
1502  }
1503  }
1504  }
1505  }
1506 
1507  double lcBestDualBoundValue = paraNodePool->getBestDualBoundValue();
1509  paraComm->send( &lcBestDualBoundValue, 1, ParaDOUBLE, source, TagLCBestBoundValue)
1510  );
1511  unsigned int notificationId = solverState->getNotificaionId();
1513  paraComm->send( &notificationId, 1, ParaUNSIGNED, source, TagNotificationId)
1514  );
1515 
1517  (signed)( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() + paraNodePool->getNumOfNodes() ) >= paraParams->getIntParamValue(NumberOfInitialNodes) )
1518  {
1519  for(unsigned int i = 1; i <= paraSolverPool->getNSolvers(); i++ )
1520  {
1521  int nCollect = -1;
1522  if( paraSolverPool->isSolverActive(i) )
1523  {
1525  paraComm->send( &nCollect, 1, ParaINT, i, TagCollectAllNodes )
1526  );
1527  }
1528  }
1529  initialNodesGenerated = true;
1530  }
1531  else
1532  {
1533  if( runningPhase != RampUpPhase )
1534  {
1536  globalBestDualBoundValueLocal
1537  ) > 0 )
1538  {
1539  statEmptyNodePoolTime = DBL_MAX;
1540  isCollectingModeRestarted = false;
1541  }
1542  else // paraNodePool is empty in terms of the number of good nodes
1543  {
1545  {
1547  {
1548  double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
1549  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
1550  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
1551  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
1552  if( logSolvingStatusFlag )
1553  {
1555  << " Collecting mode is restarted with " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers()
1556  << std::endl;
1557  }
1558  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() ) isCollectingModeRestarted = true;
1559  }
1560  }
1561  else // no inactive solvers
1562  {
1564  {
1565  statEmptyNodePoolTime = DBL_MAX; // node pool is empty, but it becomes empty soon again, it is better to restart collecting mode
1566  isCollectingModeRestarted = false;
1567  }
1568  }
1570  {
1572  {
1574  }
1575  }
1576  else
1577  {
1579  {
1581  }
1582  }
1583  }
1584 
1589  {
1590  if( paraNodePool->getNumOfNodes() == 0 && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->canIncreaseLimitNLimitCollectingModeSolvers() )
1591  // ramp-up may collect nodes having not so good nodes. As long as nodes exist, the limit number should not be increased.
1592  {
1593  double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
1594  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
1595  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
1596  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->incNLimitCollectingModeSolvers();
1597  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
1598  if( logSolvingStatusFlag )
1599  {
1601  << " Limit number of collecting mode solvers extends to " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers()
1602  << ", p = " << paraParams->getIntParamValue(UG::NChangeIntoCollectingMode)*dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getMCollectingNodes()
1603  << std::endl;
1605  {
1607  "Limit number of collecting mode solvers extends to " <<
1608  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers() <<
1609  " after " << paraTimer->getElapsedTime() << " seconds." << std::endl;
1610  }
1611 #ifdef _DEBUG_LB
1612  std::cout << paraTimer->getElapsedTime()
1613  << " Limit number of collecting mode solvers extends to " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers()
1614  << std::endl;
1615 #endif
1616  }
1617  // isCollectingModeRestarted = false;
1618  }
1619  else // cannot increase the number of collecting mode solvers
1620  {
1621  double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
1622  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
1623  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
1624  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
1625  if( logSolvingStatusFlag )
1626  {
1628  << " Collecting mode is restarted with " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers()
1629  << std::endl;
1630  }
1631  }
1632  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() )
1633  {
1635  statEmptyNodePoolTime = DBL_MAX;
1636  }
1637  }
1638  }
1639 
1640  if( !( solverState->isRacingStage() ) &&
1641  runningPhase != RampUpPhase && !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode()) &&
1642  ( (signed)paraNodePool->getNumOfGoodNodes(
1643  globalBestDualBoundValueLocal
1645  &&
1646  (signed)paraNodePool->getNumOfNodes(
1649  ) )
1650  {
1651  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
1652  if( firstCollectingModeState == -1 && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() ) firstCollectingModeState = 0;
1653  }
1654 
1655  if( !isBreakingFinised )
1656  {
1657  if( (!solverState->isRacingStage()) && runningPhase == NormalRunningPhase )
1658  {
1660  (signed)dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() < paraParams->getIntParamValue(NStopBreaking) )
1661  {
1662  isBreakingFinised = true;
1663  }
1664  else
1665  {
1666  if( breakingSolverId == -1 )
1667  {
1668  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesLeftInBestSolver()
1670  {
1671  breakingSolverId = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getBestSolver();
1672  assert( breakingSolverId != -1 );
1673  double targetBound = ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue()*
1675  int nLimitTransfer = paraParams->getIntParamValue(NTransferLimitForBreaking);
1677  paraComm->send( &targetBound, 1, ParaDOUBLE, breakingSolverId, TagBreaking )
1678  );
1680  paraComm->send( &nLimitTransfer, 1, ParaINT, breakingSolverId, TagBreaking )
1681  );
1682  }
1683  else
1684  {
1685  if( ( ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue()
1687  solverState->getSolverLocalBestDualBoundValue() ) &&
1688  (signed)dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() >
1690  solverState->getNNodesLeft() > ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()*0.5 ) )
1691  {
1692  breakingSolverId = source;
1693  double targetBound = ( solverState->getSolverLocalBestDualBoundValue()*
1695  int nLimitTransfer = paraParams->getIntParamValue(NTransferLimitForBreaking);
1697  paraComm->send( &targetBound, 1, ParaDOUBLE, breakingSolverId, TagBreaking )
1698  );
1700  paraComm->send( &nLimitTransfer, 1, ParaINT, breakingSolverId, TagBreaking )
1701  );
1702  }
1703  }
1704  }
1705  }
1706  }
1707  }
1708  else // isBootstrapFinised
1709  {
1712  (signed)dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
1714  {
1715  // break again. several solvers can be in breaking situation. That is, braking message can be sent to breaking solver
1716  isBreakingFinised = false;
1717  breakingSolverId = -1;
1718  }
1719  }
1720  }
1721 
1722  lcts.globalBestDualBoundValue = std::max(lcts.globalBestDualBoundValue, globalBestDualBoundValue);
1723  lcts.externalGlobalBestDualBoundValue = bbParaInitiator->convertToExternalValue(globalBestDualBoundValue);
1724 
1725  delete solverState;
1726  return 0;
1727 }
1728 
1729 int
1731  int source,
1732  int tag
1733  )
1734 {
1735 
1737  calcState->receive(paraComm, source, tag);
1738  if( paraRacingSolverPool && paraRacingSolverPool->isSolverActive(source) ) // racing root node termination
1739  {
1740  writeTransferLogInRacing(source, calcState);
1741  }
1742  else
1743  {
1744  writeTransferLog(source, calcState);
1745  }
1746 
1748  racingWinner == source )
1749  {
1751  if( merging )
1752  {
1753  assert(nodesMerger);
1754  nodesMerger->generateMergeNodesCandidates(paraComm, paraInitiator); // Anyway,merge nodes candidates have to be generated,
1755  // even if running with InitialNodesGeneration
1756  merging = false;
1757  }
1760  {
1761  initialNodesGenerated = true;
1762  }
1763  }
1764 
1765  int calcTerminationState = calcState->getTerminationState();
1766 
1767  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
1768 
1769  if( logSolvingStatusFlag )
1770  {
1771  switch ( calcTerminationState )
1772  {
1774  {
1776  << " S." << source << " > " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1777  break;
1778  }
1780  {
1781  /** When starts with racing ramp-up, solvers except winner should be terminated in this state */
1783  << " S." << source << " >(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1784  break;
1785  }
1787  {
1789  << " S." << source << " >(INTERRUPTED) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1790  break;
1791  }
1793  {
1795  << " S." << source << " >(TERMINATED_IN_RACING_STAGE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1796  break;
1797  }
1799  {
1801  << " S." << source << " >(INTERRUPTED_IN_RACING_STAGE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1802  break;
1803  }
1805  {
1807  << " S." << source << " >(INTERRUPTED_IN_MERGING) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1808  break;
1809  }
1811  {
1813  << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1814  break;
1815  }
1817  {
1819  << " S." << source << " >(INTERRUPTED_BY_MEMORY_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
1820  break;
1821  }
1822  default:
1823  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
1824  }
1825 
1827  calcState->getNSolvedWithNoPreprocesses() > 0 )
1828  {
1829  *osLogSolvingStatus << " SOLVED_AT_ROOT ( DEPTH = "
1830  << dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source))->getDepth()
1831  << ", Gap = "
1832  << bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source))->getDualBoundValue()) * 100
1833  << "%, TrueGap = "
1834  << bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source))->getInitialDualBoundValue()) * 100
1835  << "% ) [ "
1836  << calcState->getNSolvedWithNoPreprocesses() << " ]";
1837  }
1838 
1839  *osLogSolvingStatus << ", " << dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source))->toSimpleString();
1840 
1841  *osLogSolvingStatus << ", ct:" << calcState->getCompTime()
1842  << ", nr:" << calcState->getNRestarts()
1843  << ", n:" << calcState->getNSolved()
1844  << ", rt:" << calcState->getRootTime()
1845  << ", avt:" << calcState->getAverageNodeCompTimeExcpetRoot()
1846  << std::endl;
1847  }
1848 
1849 #ifdef _DEBUG_LB
1850  switch ( calcTerminationState )
1851  {
1853  {
1854  std::cout << paraTimer->getElapsedTime()
1855  << " S." << source << " >";
1856  break;
1857  }
1859  {
1860  /** When starts with racing ramp-up, solvers except winner should be terminated in this state */
1861  std::cout << paraTimer->getElapsedTime()
1862  << " S." << source << " >(INTERRUPTED_BY_ANOTHER_NODE)";
1863  break;
1864  }
1866  {
1867  std::cout << paraTimer->getElapsedTime()
1868  << " S." << source << " >(INTERRUPTED)";
1869  break;
1870  }
1872  {
1873  std::cout << paraTimer->getElapsedTime()
1874  << " S." << source << " >(TERMINATED_IN_RACING_STAGE)";
1875  break;
1876  }
1878  {
1879  std::cout << paraTimer->getElapsedTime()
1880  << " S." << source << " >(INTERRUPTED_IN_RACING_STAGE)";
1881  break;
1882  }
1883  default:
1884  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
1885  }
1886 
1888  calcState->getNSolvedWithNoPreprocesses() > 0 )
1889  {
1890  std::cout << " SOLVED_AT_ROOT ( DEPTH = " << paraSolverPool->getCurrentTask(source)->getDepth()
1891  << ", Gap = " << paraInitiator->getGap(paraSolverPool->getCurrentTask(source)->getDualBoundValue()) * 100 << "%, TrueGap = "
1892  << paraInitiator->getGap(paraSolverPool->getCurrentTask(source)->getInitialDualBoundValue()) * 100 << "% ) [ "
1893  << calcState->getNSolvedWithNoPreprocesses() << " ]";
1894  }
1895  std::cout << std::endl;
1896 #endif
1897 
1898  switch ( calcTerminationState )
1899  {
1901  {
1902  writeSubtreeInfo(source, calcState);
1903  BbParaNode *node = dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(source));
1904  if( node->getMergeNodeInfo() )
1905  {
1906  node->setDualBoundValue(bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue()));
1907  assert(nodesMerger);
1909  }
1910  if( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ) // RacingSolverPool is inactivated below
1911  {
1912  if( paraNodePoolToRestart )
1913  {
1914  BbParaNode *solvingNode = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool);
1915  if( solvingNode->getAncestor() )
1916  {
1917  delete solvingNode;
1918  }
1919  else
1920  {
1921  paraNodePoolToRestart->insert(solvingNode); // to stand a safety side about timing issue. two branch nodes may be romved.
1922  }
1923  return 0;
1924  }
1925 
1929  {
1930  // Exceptional case (reqested to a node whoes root node was solving), but it happend.
1931  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
1932  if( solvingNode->areNodesCollected() )
1933  {
1934  if( logSolvingStatusFlag )
1935  {
1937  << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
1938  }
1939  delete solvingNode;
1942 // std::cout << "sendInterrruptRequest 1" << std::endl;
1943  }
1944  else
1945  {
1947  delete solvingNode;
1948  }
1949 #ifdef UG_WITH_ZLIB
1954  {
1955  updateCheckpointFiles();
1956  }
1957 #endif
1958  }
1959  else
1960  {
1961  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverInCollectingMode(source) )
1962  {
1963  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, calcState->getNSolved(),paraNodePool);
1964  // reschedule collecting mode
1966  {
1967  double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
1968  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
1969  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
1970  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
1971  }
1972  }
1973  else
1974  {
1975  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverActive(source) ) // the solver can be inactive for timing issue
1976  {
1977  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, calcState->getNSolved(),paraNodePool);
1978  }
1979  }
1980  }
1981  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
1982  }
1983  // std::cout << "Rank" << source
1984  // << ", lcts.best = " << lcts.externalGlobalBestDualBoundValue
1985  // << ", bound = " << paraInitiator->convertToExternalValue(calcState->getDualBoundValue())
1986  // << ", gap = " << std::setprecision(5) << paraInitiator->getGap(calcState->getDualBoundValue())*100 << "%" << std::endl;
1987  if( !EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, paraInitiator->getEpsilon() ) )
1988  {
1992  {
1993  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
1994  {
1996  }
1997  else
1998  {
2000  }
2001  }
2002  /*
2003  if( // maximal dual bound value of terminated solver should be taken.
2004  // Therefore, the gap value is better than the real value
2005  calcState->getDualBoundValue() <
2006  std::min(
2007  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
2008  minmalDualBoundNormalTermSolvers ) &&
2009  lcts.globalBestDualBoundValue < calcState->getDualBoundValue() )
2010  {
2011  lcts.globalBestDualBoundValue = calcState->getDualBoundValue();
2012  lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
2013  // std::cout << "Updated Rank" << source
2014  // << ", lcts.best = " << lcts.externalGlobalBestDualBoundValue
2015  // << ", bound = " << paraInitiator->convertToExternalValue(calcState->getDualBoundValue())
2016  // << ", gap = " << std::setprecision(5) << paraInitiator->getGap(calcState->getDualBoundValue())*100 << "%" << std::endl;
2017  }
2018  */
2019  }
2020  // DO NOT send ParaNode here!
2021  // Send ParaNode after solver termination state is received.
2025  {
2027  {
2029  paraComm->send( NULL, 0, ParaBYTE, source, TagTerminateRequest )
2030  );
2031 // std::cout << "TagTerminateRequest 1" << std::endl;
2034  {
2035  int token[2];
2036  token[0] = source;
2037  token[1] = -2;
2039  paraComm->send( token, 2, ParaINT, token[0], TagToken )
2040  );
2041  }
2042  }
2043  }
2044  break;
2045  }
2047  {
2048  // DO NOT send ParaNode here!
2049  // Send ParaNode after solver termination state is received and RacingSolver is inactivated.
2050  // Do not have to update counters of ParaSolverPool.
2051  break;
2052  }
2054  {
2055  /** in this case the following two numbers should be different */
2056  /** # Total > # Solved */
2057  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
2058  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
2059  // dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, calcState->getNSolved(),paraNodePool); // Keep running to get another task
2060  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
2064  {
2066  {
2068  paraComm->send( NULL, 0, ParaBYTE, source, TagTerminateRequest )
2069  );
2070 // std::cout << "TagTerminateRequest 2" << std::endl;
2073  {
2074  int token[2];
2075  token[0] = source;
2076  token[1] = -2;
2078  paraComm->send( token, 2, ParaINT, token[0], TagToken )
2079  );
2080  }
2081  }
2082  }
2083  break;
2084  }
2086  {
2087  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
2088  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
2089  // dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, calcState->getNSolved(),paraNodePool); // this does not work
2090  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
2094  {
2096  {
2097  writeSubtreeInfo(source, calcState);
2098  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
2099  if( solvingNode->areNodesCollected() )
2100  {
2101  if( logSolvingStatusFlag )
2102  {
2104  << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
2105  }
2106  if( calcState->getNSolved() > 1 ||
2107  ( calcState->getNSolved() >= 1 && calcState->getNSent() > 0 ) )
2108  {
2109  delete solvingNode;
2110  }
2111  else
2112  {
2113  paraNodePool->insert(solvingNode);
2114  }
2116 #ifdef UG_WITH_ZLIB
2118  {
2119  updateCheckpointFiles();
2120  }
2121 #endif
2123 // std::cout << "sendInterrruptRequest 2" << std::endl;
2124  }
2125  else
2126  {
2127  paraNodePool->insert(solvingNode);
2129 // std::cout << "sendInterrruptRequest 3" << std::endl;
2130  }
2131  }
2132  break;
2133  }
2134  if( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ) // RacingSolverPool is inactivated below
2135  {
2136  // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
2137  BbParaNode *solvingNode = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool);
2138  if( paraNodePoolToRestart )
2139  {
2140  if( solvingNode->getAncestor() )
2141  {
2142  delete solvingNode;
2143  }
2144  else
2145  {
2146  if( bbParaInitiator->getAbsgap(solvingNode->getDualBoundValue()) < bbParaInitiator->getAbsgapValue() ||
2147  bbParaInitiator->getGap(solvingNode->getDualBoundValue()) < bbParaInitiator->getGapValue() )
2148  {
2149  delete solvingNode;
2150  }
2151  else
2152  {
2153  paraNodePoolToRestart->insert(solvingNode);
2154  }
2155  }
2156  }
2157  else
2158  {
2159  if( bbParaInitiator->getAbsgap(solvingNode->getDualBoundValue()) < bbParaInitiator->getAbsgapValue() ||
2160  bbParaInitiator->getGap(solvingNode->getDualBoundValue()) < bbParaInitiator->getGapValue() )
2161  {
2162  delete solvingNode;
2163  }
2164  else
2165  {
2166  paraNodePool->insert(solvingNode);
2167  }
2168  }
2169  }
2170  //
2171  // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
2172  // just use SolerState update
2173  //
2174  break;
2175  }
2177  {
2178  racingTermination = true; // even if interruptIsRequested,
2179  // solver should have been terminated before receiveing it
2181  {
2182  *osStatisticsRacingRampUp << "######### Solver Rank = " <<
2183  source << " is terminated in racing stage #########" << std::endl;
2184  }
2185  nSolvedRacingTermination = calcState->getNSolved();
2186 
2187  if( !EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, bbParaInitiator->getEpsilon() ) &&
2188  EPSEQ( minmalDualBoundNormalTermSolvers, DBL_MAX, bbParaInitiator->getEpsilon() ) )
2189  {
2190  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
2191  {
2193  }
2194  else
2195  {
2197  }
2198  }
2199  if( EPSLE(lcts.globalBestDualBoundValue, calcState->getDualBoundValue(), bbParaInitiator->getEpsilon()) &&
2200  minmalDualBoundNormalTermSolvers < calcState->getDualBoundValue() )
2201  {
2202  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
2203  {
2205  }
2206  else
2207  {
2209  }
2210  }
2211  if( (!givenGapIsReached) && bbParaInitiator->getGlobalBestIncumbentSolution() &&
2213  EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, bbParaInitiator->getEpsilon() ) ) )
2214  {
2216  if( paraNodePool->getNumOfNodes() > 0 )
2217  {
2219  }
2221  }
2222  break;
2223  }
2225  {
2226  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
2228  {
2229  // std::cout << "S." << source << " is interrupted." << std::endl;
2230  if( solvingNode->getMergeNodeInfo() )
2231  {
2232  assert(nodesMerger);
2234  paraNodePool->insert(solvingNode);
2235  }
2236  // else, node shuld be in paraNodePoolBufferToGenerateCPF.
2237  }
2238  else
2239  {
2240  assert(solvingNode->getMergeNodeInfo());
2241  assert(nodesMerger);
2243  paraNodePool->insert(solvingNode);
2244  }
2245  break;
2246  }
2248  {
2249  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
2250  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
2251  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
2255  {
2257  {
2258  writeSubtreeInfo(source, calcState);
2259  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
2260  if( solvingNode->areNodesCollected() )
2261  {
2262  if( logSolvingStatusFlag )
2263  {
2265  << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
2266  }
2267  if( calcState->getNSolved() > 1 ||
2268  ( calcState->getNSolved() >= 1 && calcState->getNSent() > 0 ) )
2269  {
2270  delete solvingNode;
2271  }
2272  else
2273  {
2274  paraNodePool->insert(solvingNode);
2275  }
2277 #ifdef UG_WITH_ZLIB
2282  {
2283  updateCheckpointFiles();
2284  }
2285 #endif
2287 // std::cout << "sendInterrruptRequest 4" << std::endl;
2288  }
2289  else
2290  {
2291  paraNodePool->insert(solvingNode);
2293 // std::cout << "sendInterrruptRequest 5" << std::endl;
2294  }
2295  }
2296  break;
2297  }
2298  if( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ) // RacingSolverPool is inactivated below
2299  {
2300  // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
2301  BbParaNode *solvingNode = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool);
2302  if( paraNodePoolToRestart )
2303  {
2304  if( solvingNode ) // solvingNode can be NULL
2305  {
2306  if( solvingNode->getAncestor() )
2307  {
2308  delete solvingNode;
2309  }
2310  else
2311  {
2312  paraNodePoolToRestart->insert(solvingNode);
2313  }
2314  }
2315  }
2316  else
2317  {
2318  if( solvingNode ) // solvingNode can be NULL
2319  {
2320  paraNodePool->insert(solvingNode);
2321  }
2322  }
2323  }
2324  //
2325  // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
2326  // just use SolerState update
2327  //
2328  break;
2329  }
2331  {
2332  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
2333  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
2334  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
2338  {
2340  {
2341  if( dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNumInactiveSolvers() == 0 )
2342  {
2343  /// when it is the first solver terminated (this have to be checked very carefully for restart racing (no debug)
2344  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->extractNode());
2345  paraNodePool->insert(solvingNode);
2346  }
2347  dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->inactivateSolver(source);
2348  }
2349  else
2350  {
2351  writeSubtreeInfo(source, calcState);
2352  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
2353  paraNodePool->insert(solvingNode);
2354 
2355  }
2356 #ifdef UG_WITH_ZLIB
2361  {
2362  updateCheckpointFiles();
2363  }
2364 #endif
2365  }
2367 // std::cout << "sendInterrruptRequest 6" << std::endl;
2369  //
2370  // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
2371  // just use SolerState update
2372  //
2373  break;
2374  }
2375  default:
2376  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
2377  }
2378 
2379  if( calcState->getTerminationState() == CompTerminatedByTimeLimit )
2380  {
2381  hardTimeLimitIsReached = true;
2382  // std::cout << "####### Rank " << paraComm->getRank() << " solver terminated with timelimit in solver side. #######" << std::endl;
2383  // std::cout << "####### Final statistics may be messed up!" << std::endl;
2384  }
2385 
2386  if( calcState->getTerminationState() == CompTerminatedByMemoryLimit )
2387  {
2388  memoryLimitIsReached = true;
2389  }
2390 
2391  delete calcState;
2392 
2393  return 0;
2394 }
2395 
2396 int
2398  int source,
2399  int tag
2400  )
2401 {
2402 
2404 
2405  termState->receive(paraComm, source, TagTermStateForInterruption);
2406 
2407  if( paraDetTimer )
2408  {
2409  if( paraDetTimer->getElapsedTime() < termState->getDeterministicTime() )
2410  {
2412  }
2413  // assert( !paraRacingSolverPool ); // can have paraRacingSolverPool, but it would be ok to do as follows
2414  // std::cout << "paraRacingSolverPool = " << paraRacingSolverPool << std::endl;
2415  // std::cout << "paraSolverPool->isTerminateRequested(source) = " << paraSolverPool->isTerminateRequested(source) << std::endl;
2416  // if( paraRacingSolverPool )
2417  // {
2418  // std::cout << "paraRacingSolverPool->isSolverActive(source) = " << paraRacingSolverPool->isSolverActive(source) << std::endl;
2419  // }
2420  if( !paraSolverPool->isTerminateRequested(source) ||
2422  {
2424  paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
2425  );
2426  }
2427  }
2428 
2429  switch( termState->getInterruptedMode() )
2430  {
2431  case 2: /** checkpoint; This is normal termination */
2432  {
2433  /** in order to save termination status to check point file, keep this information to solver pool */
2434  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setTermState(source, termState);
2435  // don't delete termState! it is saved in paraSolverPool
2436  if( runningPhase != TerminationPhase &&
2438  dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByTimeLimit &&
2439  dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByMemoryLimit )
2440  {
2441  if( paraNodePool->isEmpty() )
2442  {
2444  if( runningPhase != RampUpPhase && !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode()) )
2445  {
2446  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
2447  if( firstCollectingModeState == -1 && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() ) firstCollectingModeState = 0;
2448  }
2449  }
2450  else
2451  {
2453  {
2455  }
2456  }
2457  }
2458  if( dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() == CompTerminatedByTimeLimit )
2459  {
2460  hardTimeLimitIsReached = true;
2461  }
2462  if( dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() == CompTerminatedByMemoryLimit )
2463  {
2464  memoryLimitIsReached = true;
2465  }
2466  break;
2467  }
2468  case 3: /** racing ramp-up */
2469  {
2471  {
2473  osStatisticsRacingRampUp->flush();
2474  }
2475  // nTerminated++; We should not count this, We should always send Term from LC!
2476  // there is a timming to receive this message after paraRacingSolverPool is removed
2477  if( paraRacingSolverPool )
2478  {
2480  }
2481  /* Anyway, incumbent value is sent to all Solvers except its generator. In such case, this is not necessary.
2482  double globalBestIncumbentValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
2483  PARA_COMM_CALL(
2484  paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, source, TagIncumbentValue )
2485  );
2486  */
2487  if( runningPhase != TerminationPhase &&
2488  dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByTimeLimit &&
2489  dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByMemoryLimit )
2490  {
2491  if( paraNodePool->isEmpty() )
2492  {
2494  if( runningPhase != RampUpPhase && !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode()) )
2495  {
2496  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
2497  if( firstCollectingModeState == -1 && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() ) firstCollectingModeState = 0;
2498  }
2499  }
2500  else
2501  {
2503  {
2505  }
2506  }
2507  }
2508  if( dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() == CompTerminatedByTimeLimit )
2509  {
2510  hardTimeLimitIsReached = true;
2511  }
2512  if( dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() == CompTerminatedByMemoryLimit )
2513  {
2514  memoryLimitIsReached = true;
2515  }
2516  delete termState;
2517  break;
2518  }
2519  default: /** unexpected mode */
2520  THROW_LOGICAL_ERROR4("Unexpected termination state received from rank = ", source,
2521  ", interrupted mode = ", termState->getInterruptedMode());
2522  }
2523 
2524  if( dynamic_cast<BbParaSolverPool *>(paraSolverPool)->isInterruptRequested(source)
2525  && !dynamic_cast<BbParaSolverPool *>(paraSolverPool)->getCurrentTask(source) ) // solver is interrupted
2526  {
2527  dynamic_cast<BbParaSolverPool *>(paraSolverPool)->inactivateSolver(source, -1, paraNodePool);
2528  }
2529 
2530  if( racingTermination && dynamic_cast<BbParaSolverPool *>(paraSolverPool)->isTerminateRequested(source) )
2531  {
2532  // nTerminated++;
2533  return 0;
2534  }
2535 
2536 #ifndef _COMM_MPI_WORLD
2538  {
2539  if( nTerminated == 0 )
2540  {
2541  /** in this case, do not have to wait statistical information from the other solvers */
2542  // nTerminated = 1;
2544  // std::cout << "UG_BB nTerminated = " << nTerminated << std::endl;
2545  delete this;
2546  }
2547  else
2548  {
2549  // THROW_LOGICAL_ERROR2("unexpated termination received. nTeminated = ", nTerminated);
2550  }
2551 
2552 #ifdef _COMM_PTH
2553  _exit(0);
2554 #else
2555  exit(0);
2556 #endif
2557  }
2558 #endif
2559 
2560  if( source == breakingSolverId )
2561  {
2562  breakingSolverId = -1;
2563  isBreakingFinised = false;
2564  }
2565  return 0;
2566 }
2567 
2568 int
2570  int source,
2571  int tag
2572  )
2573 {
2574 
2575  double bestDualBoundValue;
2577  paraComm->receive( &bestDualBoundValue, 1, ParaDOUBLE, source, TagAnotherNodeRequest)
2578  );
2579 
2580  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2581 
2582  if( paraNodePool->isEmpty() || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->currentSolvingNodehaeDescendant(source) )
2583  {
2585  paraComm->send( NULL, 0, ParaBYTE, source, TagNoNodes)
2586  );
2588  }
2589  else
2590  {
2591  BbParaNode *paraNode = 0;
2592  while( !paraNodePool->isEmpty() )
2593  {
2594  paraNode = paraNodePool->extractNode();
2595  if( !paraNode ) break;
2596  if( ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
2597  paraNode->getDualBoundValue() < bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() ) ||
2598  !( bbParaInitiator->getGlobalBestIncumbentSolution() ) )
2599  {
2600  break;
2601  }
2602  else
2603  {
2604 #ifdef UG_DEBUG_SOLUTION
2605  if( paraNode->getDiffSubproblem() && paraNode->getDiffSubproblem()->isOptimalSolIncluded() )
2606  {
2607  throw "Optimal solution going to be killed.";
2608  }
2609 #endif
2610  delete paraNode;
2611  paraNode = 0;
2612  lcts.nDeletedInLc++;
2613  }
2614  }
2615  if( paraNode )
2616  {
2617  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverActive(source) && // can be interrupting
2618  ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getDualBoundValue(source) - paraNode->getDualBoundValue()) > 0.0 &&
2619  ( REALABS( ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getDualBoundValue(source) - paraNode->getDualBoundValue() )
2620  / std::max( std::fabs(paraNode->getDualBoundValue()), 1.0) ) > paraParams->getRealParamValue(BgapStopSolvingMode) ) )
2621  {
2622  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->sendSwitchOutCollectingModeIfNecessary(source);
2623  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
2624  solvingNode->setDualBoundValue(bestDualBoundValue);
2625  solvingNode->setInitialDualBoundValue(bestDualBoundValue);
2626  paraNodePool->insert(solvingNode);
2627  if( solvingNode->getMergeNodeInfo() )
2628  {
2629  assert(nodesMerger);
2630  nodesMerger->mergeNodes(solvingNode, paraNodePool);
2631  }
2632  // without consideration of keeping nodes in checkpoint file
2633  double globalBestDualBoundValueLocal =
2634  std::max (
2635  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
2637  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activateSolver(source, paraNode,
2638  paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains);
2639  // paraNode->send(paraComm, source); // send the node in acitivateSolver
2640  lcts.nSent++;
2642  writeTransferLog(source);
2643  if( logSolvingStatusFlag )
2644  {
2646  << " S." << source << " <(ANOTHER_NODE) "
2647  << bbParaInitiator->convertToExternalValue(
2648  paraNode->getDualBoundValue() );
2649  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
2650  {
2651  if( bbParaInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
2652  {
2653  *osLogSolvingStatus << " ( Inf )";
2654  }
2655  else
2656  {
2657  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
2658  }
2659  }
2660  *osLogSolvingStatus << std::endl;
2661  }
2662 #ifdef _DEBUG_LB
2663  std::cout << paraTimer->getElapsedTime()
2664  << " S." << source << " <(ANOTHER_NODE) "
2665  << paraInitiator->convertToExternalValue(
2666  paraNode->getDualBoundValue() );
2667  if( paraInitiator->getGlobalBestIncumbentSolution() )
2668  {
2669  if( paraInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
2670  {
2671  std::cout << " ( Inf )";
2672  }
2673  else
2674  {
2675  std::cout << " ( " << paraInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
2676  }
2677  }
2678  std::cout << std::endl;
2679 #endif
2680  }
2681  else
2682  {
2683  paraNodePool->insert(paraNode);
2685  paraComm->send( NULL, 0, ParaBYTE, source, TagNoNodes)
2686  );
2688  }
2689  }
2690  else
2691  {
2693  paraComm->send( NULL, 0, ParaBYTE, source, TagNoNodes)
2694  );
2696  }
2697  }
2698  return 0;
2699 }
2700 
2701 int
2703  int source,
2704  int tag
2705  )
2706 {
2707 
2710  );
2711  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setCollectingIsAllowed(source);
2712 
2713  return 0;
2714 }
2715 
2716 int
2718  int source,
2719  int tag
2720  )
2721 {
2722 
2723  int tightenedIdex;
2724  double tightenedBound;
2726  paraComm->receive( (void *)&tightenedIdex, 1, ParaINT, source, TagLbBoundTightenedIndex )
2727  );
2729  paraComm->receive( (void *)&tightenedBound, 1, ParaDOUBLE, source, TagLbBoundTightenedBound )
2730  );
2731  if( EPSLT(dynamic_cast<BbParaInitiator *>(paraInitiator)->getTightenedVarLbs(tightenedIdex), tightenedBound, MINEPSILON ) )
2732  {
2733  // std::cout << "From Rank " << source << ": in initiator LB = " << paraInitiator->getTightenedVarLbs(tightenedIdex) << ", rv = " << tightenedBound << std::endl;
2734  dynamic_cast<BbParaInitiator *>(paraInitiator)->setTightenedVarLbs(tightenedIdex, tightenedBound);
2736  {
2737  for( size_t i = 1; i <= paraRacingSolverPool->getNumActiveSolvers(); i++ )
2738  {
2739  if( static_cast<int>(i) != source )
2740  {
2742  paraComm->send( (void *)&tightenedIdex, 1, UG::ParaINT, i, UG::TagLbBoundTightenedIndex )
2743  );
2745  paraComm->send( (void *)&tightenedBound, 1, UG::ParaDOUBLE, i, UG::TagLbBoundTightenedBound )
2746  );
2747  }
2748  }
2749  // std::cout << "From Rank " << source << ": broadcast tightened lower bond. idx = " << tightenedIdex << ", bound = " << tightenedBound << std::endl;
2750  }
2751  }
2752 
2753  return 0;
2754 }
2755 
2756 int
2758  int source,
2759  int tag
2760  )
2761 {
2762 
2763  int tightenedIdex;
2764  double tightenedBound;
2766  paraComm->receive( (void *)&tightenedIdex, 1, ParaINT, source, TagUbBoundTightenedIndex )
2767  );
2769  paraComm->receive( (void *)&tightenedBound, 1, ParaDOUBLE, source, TagUbBoundTightenedBound )
2770  );
2771  if( EPSGT(dynamic_cast<BbParaInitiator *>(paraInitiator)->getTightenedVarUbs(tightenedIdex), tightenedBound, MINEPSILON ) )
2772  {
2773  // std::cout << "From Rank " << source << ": in initiator UB = " << paraInitiator->getTightenedVarUbs(tightenedIdex) << ", rv = " << tightenedBound << std::endl;
2774  dynamic_cast<BbParaInitiator *>(paraInitiator)->setTightenedVarUbs(tightenedIdex, tightenedBound);
2776  {
2777  for( size_t i = 1; i <= paraRacingSolverPool->getNumActiveSolvers(); i++ )
2778  {
2779  if( static_cast<int>(i) != source )
2780  {
2782  paraComm->send( (void *)&tightenedIdex, 1, UG::ParaINT, i, UG::TagUbBoundTightenedIndex )
2783  );
2785  paraComm->send( (void *)&tightenedBound, 1, UG::ParaDOUBLE, i, UG::TagUbBoundTightenedBound )
2786  );
2787  }
2788  }
2789  // std::cout << "From Rank " << source << ": broadcast tightened upper bond. idx = " << tightenedIdex << ", bound = " << tightenedBound << std::endl;
2790  }
2791  }
2792 
2793  return 0;
2794 }
2795 
2796 int
2798  int source,
2799  int tag
2800  )
2801 {
2802 
2803  assert( tag == TagSelfSplitFinished );
2805  paraComm->receive( NULL, 0, ParaBYTE, source, TagSelfSplitFinished )
2806  );
2807  selfSplitFinisedSolvers->insert(source);
2808 // std::cout << "***TagSelfSplitFinished*** R." << source
2809 // << ": dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved = "
2810 // << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source) << std::endl;
2811  return 0;
2812 }
2813 
2814 int
2816  int source,
2817  int tag
2818  )
2819 {
2820 
2821  BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2822  paraNode->receiveNewSubtreeRoot(paraComm, source);
2823 
2824 // std::cout << "S." << source
2825 // << ", KEEP: nBoundChanges = " << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges() << std::endl;
2826 
2827  assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2828 
2830  {
2831  dynamic_cast<BbParaSolverPool *>(paraSolverPool)->addNewSubtreeRootNode(source, paraNode);
2832  }
2833 
2834  assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2835 
2836  if( logSolvingStatusFlag )
2837  {
2838  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2840  << " S." << source
2841  << " |< "
2842  << bbParaInitiator->convertToExternalValue(
2843  paraNode->getDualBoundValue() )
2844  << " "
2845  << paraNode->toSimpleString();
2846  if( paraNode->getDiffSubproblem() )
2847  {
2849  << ", "
2850  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
2851  << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
2852  }
2853  *osLogSolvingStatus << std::endl;
2854  }
2855 // std::cout << "***TagNewSubtreeRootNode*** R." << source
2856 // << ": dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved = "
2857 // << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source) << std::endl;
2858  return 0;
2859 }
2860 
2861 int
2863  int source,
2864  int tag
2865  )
2866 {
2867 
2868  BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2869  // BbParaNode *nextNode = 0;
2871  // std::cout << "processTagSubtreeRootNodeToBeRemoved" << paraNode->toSimpleString() << std::endl;
2872 
2874  {
2875  dynamic_cast<BbParaSolverPool *>(paraSolverPool)->makeSubtreeRootNodeCurrent(source, paraNode);
2876  if( logSolvingStatusFlag )
2877  {
2878  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2880  << " S." << source
2881  << " |s "
2882  << dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPool *>(paraSolverPool)->getCurrentTask(source))->toSimpleString();
2883  *osLogSolvingStatus << std::endl;
2884  }
2885  }
2886 
2887  assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2888 
2889  return 0;
2890 }
2891 
2892 int
2894  int source,
2895  int tag
2896  )
2897 {
2898 
2899  BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2900  // BbParaNode *nextNode = 0;
2902  // std::cout << "processTagSubtreeRootNodeToBeRemoved" << paraNode->toSimpleString() << std::endl;
2903 
2904  assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2905 
2906  if( runningPhase == TerminationPhase &&
2907  (!dynamic_cast<BbParaSolverPool *>(paraSolverPool)->isSolverActive(source) ) )
2908  {
2909  return 0; // Anyway, the node is going to paraNodePool
2910  }
2911 
2913  {
2914  dynamic_cast<BbParaSolverPool *>(paraSolverPool)->removeSubtreeRootNode(source, paraNode);
2915  }
2916  if( logSolvingStatusFlag )
2917  {
2918  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2920  << " S." << source
2921  << " |> "
2922  << bbParaInitiator->convertToExternalValue(
2923  paraNode->getDualBoundValue() )
2924  << " "
2925  << paraNode->toSimpleString();
2926  if( paraNode->getDiffSubproblem() )
2927  {
2929  << ", "
2930  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
2931  << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
2932  }
2933  *osLogSolvingStatus << std::endl;
2934  }
2935 
2936  delete paraNode;
2937 
2938  lcts.nDeletedInLc++; // this node is deleted without calcutaion
2939 
2940  return 0;
2941 }
2942 
2943 int
2945  int source,
2946  int tag
2947  )
2948 {
2949 
2950  BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2951  // BbParaNode *nextNode = 0;
2953  // std::cout << "processTagReassignSelfSplitSubtreeRootNode" << paraNode->toSimpleString() << std::endl;
2954 
2955  assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2956 
2957 // if( runningPhase == TerminationPhase )
2958 // {
2959 // return 0; // Anyway, the node is going to paraNodePool
2960 // }
2961 
2963  {
2964  BbParaNode *reassignedNode = dynamic_cast<BbParaSolverPool *>(paraSolverPool)->extractSelfSplitSubtreeRootNode(source, paraNode);
2965 
2966  if( logSolvingStatusFlag )
2967  {
2968  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2970  << " S." << source
2971  << " |>p< "
2972  << bbParaInitiator->convertToExternalValue(
2973  reassignedNode->getDualBoundValue() )
2974  << " "
2975  << reassignedNode->toSimpleString();
2976  if( reassignedNode->getDiffSubproblem() )
2977  {
2979  << ", "
2980  // << dynamic_cast<BbParaDiffSubproblem *>(reassignedNode->getDiffSubproblem())->getNBoundChanges()
2981  << dynamic_cast<BbParaDiffSubproblem *>(reassignedNode->getDiffSubproblem())->toStringStat();
2982  }
2983  *osLogSolvingStatus << std::endl;
2984  }
2985 
2986  paraNodePool->insert(reassignedNode);
2987 
2988  }
2989 
2990  delete paraNode;
2991 
2992  return 0;
2993 }
2994 
2995 int
2997  int source,
2998  int tag
2999  )
3000 {
3001 
3003  calcState->receive(paraComm, source, tag);
3004 
3005  writeTransferLog(source, calcState);
3006 
3007  int calcTerminationState = calcState->getTerminationState();
3008  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3009  BbParaSolverPool *bbParaSolverPool = dynamic_cast<BbParaSolverPool *>(paraSolverPool);
3010  if( logSolvingStatusFlag )
3011  {
3012  switch ( calcTerminationState )
3013  {
3015  {
3016  if( bbParaSolverPool->getSelfSplitSubtreeRootNodes(source) )
3017  {
3019  << " S." << source << " |> " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3020  << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3021  }
3022  else
3023  {
3025  << " S." << source << " > " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3026  << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3027  }
3028  break;
3029  }
3031  {
3032  if( bbParaSolverPool->getSelfSplitSubtreeRootNodes(source) )
3033  {
3034  /** When starts with racing ramp-up, solvers except winner should be terminated in this state */
3036  << " S." << source << " |>(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3037  << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3038  }
3039  else
3040  {
3041  /** When starts with racing ramp-up, solvers except winner should be terminated in this state */
3043  << " S." << source << " |>(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
3044  }
3045  break;
3046  }
3048  {
3050  << " S." << source << " >(INTERRUPTED) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3051  << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3052  break;
3053  }
3055  {
3057  << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3058  << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3059  break;
3060  }
3062  {
3064  << " S." << source << " >(INTERRUPTED_BY_MEMORY_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3065  << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3066  break;
3067  }
3068  default:
3069  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
3070  }
3071  *osLogSolvingStatus << ", ct:" << calcState->getCompTime()
3072  << ", nr:" << calcState->getNRestarts()
3073  << ", n:" << calcState->getNSolved()
3074  << ", rt:" << calcState->getRootTime()
3075  << ", avt:" << calcState->getAverageNodeCompTimeExcpetRoot()
3076  << std::endl;
3077  }
3078 
3079  switch ( calcTerminationState )
3080  {
3082  {
3083  writeSubtreeInfo(source, calcState);
3084  // std::cout << "*** R." << source << ", calcState->getNSolved() = " << calcState->getNSolved() << std::endl;
3085  // BbParaNode *node = dynamic_cast<BbParaNode *>(bbParaSolverPool->getCurrentTask(source));
3086  // assert( (node->next) ); // should always has next. node->next == null should be processed in processTagCompletionOfCalculation
3087  // No: can be null, when a node is reassigned
3088  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3089 
3090  assert( !paraNodePoolToRestart );
3091 
3092  bbParaSolverPool->resetCountersInSolver(source, calcState->getNSolved(), calcState->getNSelfSplitNodesLeft(), paraNodePool);
3093  if( bbParaSolverPool->isSolverInCollectingMode(source) )
3094  {
3095  // reschedule collecting mode
3096  double tempTime = bbParaSolverPool->getSwichOutTime();
3097  bbParaSolverPool->switchOutCollectingMode();
3098  bbParaSolverPool->setSwichOutTime(tempTime);
3099  bbParaSolverPool->switchInCollectingMode(paraNodePool);
3100  }
3101  // delete node; // should not delete
3102  bbParaSolverPool->addTotalNodesSolved(calcState->getNSolved());
3103 
3104  // std::cout << "Rank" << source
3105  // << ", lcts.best = " << lcts.externalGlobalBestDualBoundValue
3106  // << ", bound = " << paraInitiator->convertToExternalValue(calcState->getDualBoundValue())
3107  // << ", gap = " << std::setprecision(5) << paraInitiator->getGap(calcState->getDualBoundValue())*100 << "%" << std::endl;
3108  if( !EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, paraInitiator->getEpsilon() ) )
3109  {
3113  {
3114  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3115  {
3117  }
3118  else
3119  {
3121  }
3122  }
3123  }
3124 
3125  if( !bbParaSolverPool->getSelfSplitSubtreeRootNodes(source) )
3126  {
3127  // dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, calcState->getNSolved(),paraNodePool);
3128  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, -1, paraNodePool); // already updated in above
3129  }
3130  else
3131  {
3132  bbParaSolverPool->deleteCurrentSubtreeRootNode(source);
3133  }
3134 
3135  break;
3136  }
3138  {
3139  /** in this case the following two numbers should be different */
3140  /** # Total > # Solved */
3141  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3142  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
3143  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3147  {
3149  {
3151  paraComm->send( NULL, 0, ParaBYTE, source, TagTerminateRequest )
3152  );
3153 // std::cout << "TagTerminateRequest 3" << std::endl;
3156  {
3157  int token[2];
3158  token[0] = source;
3159  token[1] = -2;
3161  paraComm->send( token, 2, ParaINT, token[0], TagToken )
3162  );
3163  }
3164  }
3165  }
3166  break;
3167  }
3169  {
3170  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3171  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
3172  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3176  {
3177  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) );
3178  writeSubtreeInfo(source, calcState);
3179  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
3180  if( solvingNode->areNodesCollected() )
3181  {
3182  if( logSolvingStatusFlag )
3183  {
3185  << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
3186  }
3187  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3188  while( nodes )
3189  {
3190  BbParaNode *temp = nodes;
3191  nodes = nodes->next;
3192  temp->next = 0;
3193  paraNodePool->insert(temp);
3194  if( logSolvingStatusFlag )
3195  {
3196  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3198  << " S." << source
3199  << " p< "
3200  << bbParaInitiator->convertToExternalValue(
3201  temp->getDualBoundValue() )
3202  << " "
3203  << temp->toSimpleString();
3204  if( temp->getDiffSubproblem() )
3205  {
3207  << ", "
3208  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3209  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3210  }
3211  *osLogSolvingStatus << std::endl;
3212  }
3213  }
3214  if( calcState->getNSolved() > 1 ||
3215  ( calcState->getNSolved() >= 1 && calcState->getNSent() > 0 ) )
3216  {
3217  delete solvingNode;
3218  }
3219  else
3220  {
3221  paraNodePool->insert(solvingNode);
3222  }
3224 #ifdef UG_WITH_ZLIB
3226  {
3227  updateCheckpointFiles();
3228  }
3229 #endif
3231 // std::cout << "sendInterrruptRequest 7" << std::endl;
3232  }
3233  else
3234  {
3235  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3236  while( nodes )
3237  {
3238  BbParaNode *temp = nodes;
3239  nodes = nodes->next;
3240  temp->next = 0;
3241  paraNodePool->insert(temp);
3242  if( logSolvingStatusFlag )
3243  {
3244  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3246  << " S." << source
3247  << " p< "
3248  << bbParaInitiator->convertToExternalValue(
3249  temp->getDualBoundValue() )
3250  << " "
3251  << temp->toSimpleString();
3252  if( temp->getDiffSubproblem() )
3253  {
3255  << ", "
3256  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3257  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3258  }
3259  *osLogSolvingStatus << std::endl;
3260  }
3261  }
3262  paraNodePool->insert(solvingNode);
3263  if( logSolvingStatusFlag )
3264  {
3265  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3267  << " S." << source
3268  << " p< "
3269  << bbParaInitiator->convertToExternalValue(
3270  solvingNode->getDualBoundValue() )
3271  << " "
3272  << solvingNode->toSimpleString();
3273  if( solvingNode->getDiffSubproblem() )
3274  {
3276  << ", "
3277  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3278  << dynamic_cast<BbParaDiffSubproblem *>(solvingNode->getDiffSubproblem())->toStringStat();
3279  }
3280  *osLogSolvingStatus << std::endl;
3281  }
3282 #ifdef UG_WITH_ZLIB
3283  updateCheckpointFiles();
3284 #endif
3285  }
3286  break;
3287  }
3288  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3289 
3290  // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
3291  // BbParaNode *solvingNode = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool);
3292  if( paraNodePoolToRestart )
3293  {
3294  assert( !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool))->getAncestor() );
3295  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3296  while( nodes )
3297  {
3298  BbParaNode *temp = nodes;
3299  nodes = nodes->next;
3300  temp->next = 0;
3302  if( logSolvingStatusFlag )
3303  {
3304  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3306  << " S." << source
3307  << " rp< "
3308  << bbParaInitiator->convertToExternalValue(
3309  temp->getDualBoundValue() )
3310  << " "
3311  << temp->toSimpleString();
3312  if( temp->getDiffSubproblem() )
3313  {
3315  << ", "
3316  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3317  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3318  }
3319  *osLogSolvingStatus << std::endl;
3320  }
3321  }
3322  }
3323  else
3324  {
3325  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3326  while( nodes )
3327  {
3328  BbParaNode *temp = nodes;
3329  nodes = nodes->next;
3330  temp->next = 0;
3331  paraNodePool->insert(temp);
3332  if( logSolvingStatusFlag )
3333  {
3334  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3336  << " S." << source
3337  << " p< "
3338  << bbParaInitiator->convertToExternalValue(
3339  temp->getDualBoundValue() )
3340  << " "
3341  << temp->toSimpleString();
3342  if( temp->getDiffSubproblem() )
3343  {
3345  << ", "
3346  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3347  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3348  }
3349  *osLogSolvingStatus << std::endl;
3350  }
3351  }
3352  }
3353 
3354  //
3355  // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
3356  // just use SolerState update
3357  //
3358  break;
3359  }
3361  {
3362  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3363  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
3364  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3365  hardTimeLimitIsReached = true;
3369  {
3370  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) );
3371  writeSubtreeInfo(source, calcState);
3372  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
3373  if( solvingNode->areNodesCollected() )
3374  {
3375  if( logSolvingStatusFlag )
3376  {
3378  << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
3379  }
3380  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3381  while( nodes )
3382  {
3383  BbParaNode *temp = nodes;
3384  nodes = nodes->next;
3385  temp->next = 0;
3386  paraNodePool->insert(temp);
3387  }
3388  if( calcState->getNSolved() > 1 ||
3389  ( calcState->getNSolved() >= 1 && calcState->getNSent() > 0 ) )
3390  {
3391  delete solvingNode;
3392  }
3393  else
3394  {
3395  paraNodePool->insert(solvingNode);
3396  }
3398 #ifdef UG_WITH_ZLIB
3403  {
3404  updateCheckpointFiles();
3405  }
3406 #endif
3408 // std::cout << "sendInterrruptRequest 8" << std::endl;
3409  }
3410  else
3411  {
3412  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3413  while( nodes )
3414  {
3415  BbParaNode *temp = nodes;
3416  nodes = nodes->next;
3417  temp->next = 0;
3418  paraNodePool->insert(temp);
3419  if( logSolvingStatusFlag )
3420  {
3421  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3423  << " S." << source
3424  << " p< "
3425  << bbParaInitiator->convertToExternalValue(
3426  temp->getDualBoundValue() )
3427  << " "
3428  << temp->toSimpleString();
3429  if( temp->getDiffSubproblem() )
3430  {
3432  << ", "
3433  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3434  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3435  }
3436  *osLogSolvingStatus << std::endl;
3437  }
3438  }
3439 #ifdef UG_WITH_ZLIB
3440  updateCheckpointFiles();
3441 #endif
3442  paraNodePool->insert(solvingNode);
3443  if( logSolvingStatusFlag )
3444  {
3445  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3447  << " S." << source
3448  << " p< "
3449  << bbParaInitiator->convertToExternalValue(
3450  solvingNode->getDualBoundValue() )
3451  << " "
3452  << solvingNode->toSimpleString();
3453  if( solvingNode->getDiffSubproblem() )
3454  {
3456  << ", "
3457  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3458  << dynamic_cast<BbParaDiffSubproblem *>(solvingNode->getDiffSubproblem())->toStringStat();
3459  }
3460  *osLogSolvingStatus << std::endl;
3461  }
3462  }
3463  break;
3464  }
3465  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3466  // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
3467  if( paraNodePoolToRestart )
3468  {
3469  if( paraNodePoolToRestart )
3470  {
3471  assert( !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool))->getAncestor() );
3472  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3473  while( nodes )
3474  {
3475  BbParaNode *temp = nodes;
3476  nodes = nodes->next;
3477  temp->next = 0;
3479  if( logSolvingStatusFlag )
3480  {
3481  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3483  << " S." << source
3484  << " rp< "
3485  << bbParaInitiator->convertToExternalValue(
3486  temp->getDualBoundValue() )
3487  << " "
3488  << temp->toSimpleString();
3489  if( temp->getDiffSubproblem() )
3490  {
3492  << ", "
3493  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3494  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3495  }
3496  *osLogSolvingStatus << std::endl;
3497  }
3498  }
3499  }
3500  }
3501  else
3502  {
3503  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3504  while( nodes )
3505  {
3506  BbParaNode *temp = nodes;
3507  nodes = nodes->next;
3508  temp->next = 0;
3509  paraNodePool->insert(temp);
3510  if( logSolvingStatusFlag )
3511  {
3512  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3514  << " S." << source
3515  << " p< "
3516  << bbParaInitiator->convertToExternalValue(
3517  temp->getDualBoundValue() )
3518  << " "
3519  << temp->toSimpleString();
3520  if( temp->getDiffSubproblem() )
3521  {
3523  << ", "
3524  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3525  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3526  }
3527  *osLogSolvingStatus << std::endl;
3528  }
3529  }
3530  }
3531  //
3532  // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
3533  // just use SolerState update
3534  //
3535  break;
3536  }
3538  {
3539  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3540  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
3541  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3542  memoryLimitIsReached = true;
3546  {
3547  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) );
3548  writeSubtreeInfo(source, calcState);
3549  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
3550  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3551  while( nodes )
3552  {
3553  BbParaNode *temp = nodes;
3554  nodes = nodes->next;
3555  temp->next = 0;
3556  paraNodePool->insert(temp);
3557  if( logSolvingStatusFlag )
3558  {
3559  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3561  << " S." << source
3562  << " p< "
3563  << bbParaInitiator->convertToExternalValue(
3564  temp->getDualBoundValue() )
3565  << " "
3566  << temp->toSimpleString();
3567  if( temp->getDiffSubproblem() )
3568  {
3570  << ", "
3571  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3572  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3573  }
3574  *osLogSolvingStatus << std::endl;
3575  }
3576  }
3577 #ifdef UG_WITH_ZLIB
3578  updateCheckpointFiles();
3579 #endif
3580  paraNodePool->insert(solvingNode);
3581  if( logSolvingStatusFlag )
3582  {
3583  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3585  << " S." << source
3586  << " p< "
3587  << bbParaInitiator->convertToExternalValue(
3588  solvingNode->getDualBoundValue() )
3589  << " "
3590  << solvingNode->toSimpleString();
3591  if( solvingNode->getDiffSubproblem() )
3592  {
3594  << ", "
3595  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3596  << dynamic_cast<BbParaDiffSubproblem *>(solvingNode->getDiffSubproblem())->toStringStat();
3597  }
3598  *osLogSolvingStatus << std::endl;
3599  }
3601 // std::cout << "sendInterrruptRequest 9" << std::endl;
3603  break;
3604  }
3605  assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3606  // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
3607  if( paraNodePoolToRestart )
3608  {
3609  if( paraNodePoolToRestart )
3610  {
3611  assert( !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool))->getAncestor() );
3612  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3613  while( nodes )
3614  {
3615  BbParaNode *temp = nodes;
3616  nodes = nodes->next;
3617  temp->next = 0;
3619  if( logSolvingStatusFlag )
3620  {
3621  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3623  << " S." << source
3624  << " rp< "
3625  << bbParaInitiator->convertToExternalValue(
3626  temp->getDualBoundValue() )
3627  << " "
3628  << temp->toSimpleString();
3629  if( temp->getDiffSubproblem() )
3630  {
3632  << ", "
3633  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3634  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3635  }
3636  *osLogSolvingStatus << std::endl;
3637  }
3638  }
3639  }
3640  }
3641  else
3642  {
3643  BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3644  while( nodes )
3645  {
3646  BbParaNode *temp = nodes;
3647  nodes = nodes->next;
3648  temp->next = 0;
3649  paraNodePool->insert(temp);
3650  if( logSolvingStatusFlag )
3651  {
3652  // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3654  << " S." << source
3655  << " p< "
3656  << bbParaInitiator->convertToExternalValue(
3657  temp->getDualBoundValue() )
3658  << " "
3659  << temp->toSimpleString();
3660  if( temp->getDiffSubproblem() )
3661  {
3663  << ", "
3664  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3665  << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3666  }
3667  *osLogSolvingStatus << std::endl;
3668  }
3669  }
3670  }
3672 // std::cout << "sendInterrruptRequest1 10" << std::endl;
3674  //
3675  // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
3676  // just use SolerState update
3677  //
3678  break;
3679  }
3680  default:
3681  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
3682  }
3683 
3684 // if( calcState->getTerminationState() == CompTerminatedByTimeLimit )
3685 // {
3686 // hardTimeLimitIsReached = true;
3687 // // std::cout << "####### Rank " << paraComm->getRank() << " solver terminated with timelimit in solver side. #######" << std::endl;
3688 // // std::cout << "####### Final statistics may be messed up!" << std::endl;
3689 // }
3690 
3691  delete calcState;
3692 
3693  return 0;
3694 }
3695 
3696 int
3698  int source,
3699  int tag
3700  )
3701 {
3702 
3704 
3706 
3707  if( paraDetTimer )
3708  {
3709  if( paraDetTimer->getElapsedTime() < termState->getDeterministicTime() )
3710  {
3712  }
3713  assert( !paraRacingSolverPool );
3714  if( !paraSolverPool->isTerminateRequested(source) )
3715  {
3717  paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
3718  );
3719  }
3720  }
3721 
3722  switch( termState->getInterruptedMode() )
3723  {
3724  case 2: /** checkpoint; This is normal termination */
3725  {
3726  /** in order to save termination status to check point file, keep this information to solver pool */
3727  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setTermState(source, termState);
3728  // don't delete termState! it is saved in paraSolverPool
3729  if( runningPhase != TerminationPhase &&
3731  dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByTimeLimit &&
3732  dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByMemoryLimit )
3733  {
3734  if( paraNodePool->isEmpty() )
3735  {
3737  if( runningPhase != RampUpPhase && !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode()) )
3738  {
3739  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
3740  if( firstCollectingModeState == -1 && dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode() ) firstCollectingModeState = 0;
3741  }
3742  }
3743  else
3744  {
3746  {
3748  }
3749  }
3750  }
3751  if( dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() == CompTerminatedByTimeLimit )
3752  {
3753  hardTimeLimitIsReached = true;
3754  }
3755  if( dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() == CompTerminatedByMemoryLimit )
3756  {
3757  memoryLimitIsReached = true;
3758  }
3759  break;
3760  }
3761  default: /** unexpected mode */
3762  THROW_LOGICAL_ERROR4("Unexpected termination state received from rank = ", source,
3763  ", interrupted mode = ", termState->getInterruptedMode());
3764  }
3765 
3766  return 0;
3767 }
3768 
3769 void
3771  )
3772 {
3773  // output title line 1
3774  *osTabularSolvingStatus << std::setw(1) << " ";
3775  *osTabularSolvingStatus << std::setw(8) << std::right << " ";
3776  *osTabularSolvingStatus << std::setw(15) << std::right << " ";
3777  *osTabularSolvingStatus << std::setw(12) << std::right << "Nodes";
3778  *osTabularSolvingStatus << std::setw(10) << std::right << "Active";
3779  *osTabularSolvingStatus << std::setw(17) << std::right << " ";
3780  *osTabularSolvingStatus << std::setw(17) << std::right << " ";
3781  *osTabularSolvingStatus << std::setw(10) << std::right << " ";
3782  *osTabularSolvingStatus << std::endl;
3783  // output title line 2
3784  *osTabularSolvingStatus << std::setw(1) << " ";
3785  *osTabularSolvingStatus << std::setw(8) << std::right << "Time";
3786  *osTabularSolvingStatus << std::setw(15) << std::right << "Nodes";
3787  *osTabularSolvingStatus << std::setw(12) << std::right << "Left";
3788  *osTabularSolvingStatus << std::setw(10) << std::right << "Solvers";
3789  *osTabularSolvingStatus << std::setw(17) << std::right << "Best Integer";
3790  *osTabularSolvingStatus << std::setw(17) << std::right << "Best Node";
3791  *osTabularSolvingStatus << std::setw(11) << std::right << "Gap";
3792  *osTabularSolvingStatus << std::setw(17) << std::right << "Best Node(S)";
3793  *osTabularSolvingStatus << std::setw(11) << std::right << "Gap(S)";
3794  *osTabularSolvingStatus << std::endl;
3795 
3796  isHeaderPrinted = true;
3797 }
3798 
3799 void
3801  char incumbent
3802  )
3803 {
3804 
3805  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3806 
3807  *osTabularSolvingStatus << std::setw(1) << incumbent;
3808  *osTabularSolvingStatus << std::setw(8) << std::right << std::setprecision(0) << std::fixed << paraTimer->getElapsedTime();
3809  if( // !restarted &&
3812  && !racingWinnerParams )
3813  {
3814  /** racing ramp-up stage now */
3816  {
3817  *osTabularSolvingStatus << std::setw(15) << std::right << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver();
3818 
3819  if( paraNodePool->getNumOfNodes() > 0 )
3820  {
3821  *osTabularSolvingStatus << std::setw(12) << std::right
3822  << (dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver()
3824  }
3825  else
3826  {
3827  *osTabularSolvingStatus << std::setw(12) << std::right << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver();
3828  }
3829 
3830  *osTabularSolvingStatus << std::setw(10) << std::right << paraRacingSolverPool->getNumActiveSolvers();
3831  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3832  {
3833  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3834  bbParaInitiator->convertToExternalValue(
3836  }
3837  else
3838  {
3839  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3840  }
3841  if( dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver() == 0 )
3842  {
3844  {
3845  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3847  }
3848  else
3849  {
3850  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3851  }
3852  }
3853  else
3854  {
3856  {
3857  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3858  }
3859  else
3860  {
3861  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3863  }
3864  }
3865  }
3866  else // One of ParaSolvers terminates in racing stage
3867  {
3868  if( nSolvedRacingTermination > 0 )
3869  {
3870  *osTabularSolvingStatus << std::setw(15) << std::right << nSolvedRacingTermination;
3871  *osTabularSolvingStatus << std::setw(12) << std::right << 0;
3872  *osTabularSolvingStatus << std::setw(10) << std::right << 0;
3873  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3874  {
3875  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3876  bbParaInitiator->convertToExternalValue(
3878  }
3879  else
3880  {
3881  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3882  }
3883  // *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3884  if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
3885  {
3886  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3887  }
3888  else
3889  {
3890  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3892  }
3893  }
3894  else // should be interrupted
3895  {
3896  *osTabularSolvingStatus << std::setw(15) << std::right << nSolvedInInterruptedRacingSolvers;
3897  *osTabularSolvingStatus << std::setw(12) << std::right << nTasksLeftInInterruptedRacingSolvers;
3898  *osTabularSolvingStatus << std::setw(10) << std::right << 0;
3899  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3900  {
3901  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3902  bbParaInitiator->convertToExternalValue(
3904  }
3905  else
3906  {
3907  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3908  }
3909  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3911  }
3912  }
3914  (!bbParaInitiator->getGlobalBestIncumbentSolution() ||
3917  ) )
3918  {
3919  *osTabularSolvingStatus << std::setw(11) << std::right << " -";
3920  }
3921  else
3922  {
3923  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
3924  bbParaInitiator->getGap(lcts.globalBestDualBoundValue) * 100 << "%";
3925  }
3926  }
3927  else
3928  {
3929  *osTabularSolvingStatus << std::setw(15) << std::right << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers();
3930  if( unprocessedParaNodes )
3931  {
3932  *osTabularSolvingStatus << std::setw(12) << std::right << ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
3935  }
3937  {
3938  *osTabularSolvingStatus << std::setw(12) << std::right << ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
3941  }
3942  else
3943  {
3944  *osTabularSolvingStatus << std::setw(12) << std::right << ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
3945  + paraNodePool->getNumOfNodes() );
3946  }
3947  *osTabularSolvingStatus << std::setw(10) << std::right << paraSolverPool->getNumActiveSolvers();
3948  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3949  {
3950  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3951  bbParaInitiator->convertToExternalValue(
3953  }
3954  else
3955  {
3956  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3957  }
3958 
3960  {
3961  // lcts.globalBestDualBoundValue = std::min(std::min( paraNodePool->getBestDualBoundValue(), paraNodePoolForBuffering->getBestDualBoundValue() ),
3962  // dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() );
3963  // lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue( lcts.globalBestDualBoundValue );
3964 
3965  // *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) << lcts.externalGlobalBestDualBoundValue;
3966  if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
3967  {
3968  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3969  }
3970  else
3971  {
3972  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3974  }
3975  if( bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) > displayInfOverThisValue )
3976  {
3977  *osTabularSolvingStatus << std::setw(11) << std::right << " -";
3978  }
3979  else
3980  {
3981  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
3982  bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
3983  }
3984  }
3985  else
3986  {
3988  ( paraSolverPool->getNumActiveSolvers() == 0 &&
3989  ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers() == 0
3990  || paraNodePool->getNumOfNodes() == 0 )
3991  ) )
3992  {
3993  if( (!givenGapIsReached) && bbParaInitiator->getGlobalBestIncumbentSolution() )
3994  {
3996  /*
3997  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3998  paraInitiator->convertToExternalValue(
3999  paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue());
4000  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4001  paraInitiator->getGap( paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue() ) * 100 << "%";
4002  */
4003  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4005  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4006  bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
4007  }
4008  else
4009  {
4010  if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
4011  {
4012  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4013  }
4014  else
4015  {
4016  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4018  }
4019  if( bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) > displayInfOverThisValue )
4020  {
4021  *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4022  }
4023  else
4024  {
4025  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4026  bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
4027  }
4028  }
4029  // *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4030  }
4031  else
4032  {
4033  //*osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4034  // lcts.externalGlobalBestDualBoundValue;
4035  if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
4036  {
4037  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4038  }
4039  else
4040  {
4041  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4043  }
4045  {
4046  double globalBestDualBound = paraNodeToKeepCheckpointFileNodes->getBestDualBoundValue();
4047  if( bbParaInitiator->getGap( globalBestDualBound ) > displayInfOverThisValue )
4048  {
4049  *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4050  }
4051  else
4052  {
4053  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4054  bbParaInitiator->getGap( globalBestDualBound ) * 100 << "%";
4055  }
4056  }
4057  else
4058  {
4059  if( bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) > displayInfOverThisValue )
4060  {
4061  *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4062  }
4063  else
4064  {
4065  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4066  bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
4067  }
4068  }
4069  }
4070  /*
4071  if( !paraNodeToKeepCheckpointFileNodes &&
4072  ( !paraInitiator->getGlobalBestIncumbentSolution() ||
4073  paraInitiator->getGap(lcts.globalBestDualBoundValue) > displayInfOverThisValue ||
4074  ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() && paraSolverPool->getNumActiveSolvers() == 0 && paraNodePool->getNumOfNodes() == 0 )
4075  ) )
4076  {
4077  *osTabularSolvingStatus << std::setw(10) << std::right << "-";
4078  }
4079  else
4080  {
4081  *osTabularSolvingStatus << std::setw(9) << std::right << std::setprecision(2) <<
4082  paraInitiator->getGap(lcts.globalBestDualBoundValue) * 100 << "%";
4083  }
4084  */
4085  }
4086 
4087  if( paraSolverPool->getNumActiveSolvers() > 0 )
4088  {
4089  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() >= -1e+10 )
4090  {
4091  *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4092  bbParaInitiator->convertToExternalValue( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() );
4093  }
4094  else
4095  {
4096  *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4097  }
4098  if( bbParaInitiator->getGap( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() ) > displayInfOverThisValue )
4099  {
4100  *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4101  }
4102  else
4103  {
4104  *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4105  bbParaInitiator->getGap( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() ) * 100 << "%";
4106  }
4107  }
4108  else
4109  {
4110  // *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4111  }
4112 
4113  }
4114  *osTabularSolvingStatus << std::endl;
4115 }
4116 
4117 void
4119  )
4120 {
4121 
4123  {
4124  outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
4125  }
4126 
4127  int source;
4128  int tag;
4129 
4130  for(;;)
4131  {
4132  if( paraSolverPool->getNumActiveSolvers() == 0 )
4133  {
4134  if( paraNodePool->isEmpty() ) // paraNodePool has to be checked
4135  // because node cannot send in a parameter settings
4136  {
4138  {
4139  /*
4140  if( !interruptedFromControlTerminal
4141  && !computationIsInterrupted
4142  && !hardTimeLimitIsReached
4143  && paraInitiator->getGlobalBestIncumbentSolution() )
4144  {
4145  lcts.globalBestDualBoundValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
4146  lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
4147  }
4148  */
4149  /* No active solver exists */
4152  /*
4153  if( !racingTermination )
4154  {
4155  lcts.globalBestDualBoundValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
4156  lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
4157  }
4158  */
4159  }
4160  else // runningPhase == TerminationPhase
4161  {
4162  if( ( paraRacingSolverPool &&
4163  // paraSolverPool->getNumInactiveSolvers() == (paraRacingSolverPool->getNumActiveSolvers() + nTerminated ) ) ||
4164  // paraSolverPool->getNumInactiveSolvers() == nTerminated )
4167  {
4168  break;
4169  }
4170  }
4171  }
4172  else
4173  {
4174  if( initialNodesGenerated )
4175  {
4177  {
4180 #ifdef UG_WITH_ZLIB
4181  updateCheckpointFiles();
4182 #endif
4183  /* No active solver exists */
4186  }
4187  else // runningPhase == TerminationPhase
4188  {
4189  // if( paraSolverPool->getNumInactiveSolvers() == nTerminated )
4191  {
4192  break;
4193  }
4194  }
4195  }
4196  }
4200  {
4201  break;
4202  }
4203  }
4204 
4206  firstCollectingModeState == 1 &&
4208  )
4209  {
4211  {
4214 #ifdef UG_WITH_ZLIB
4215  updateCheckpointFiles();
4216 #endif
4217  /* No active solver exists */
4219  std::cout << "### REACHED TO THE SPECIFIED NUMBER OF IDLER SOLVERS, then EXIT ###" << std::endl;
4220  exit(1); // try to terminate all solvers, but do not have to wait until all solvers have terminated.
4221  // Basically, this procedure is to kill the ug[*,*].
4222  } // if already in TerminaitonPhase, just keep on running.
4223  }
4224 
4226  {
4227  if( paraParams->getRealParamValue(TimeLimit) > 0.0 )
4228  {
4230  {
4231  hardTimeLimitIsReached = true;
4232  break;
4233  }
4234  if( givenGapIsReached )
4235  break;
4236  // std::cout << "ElapsedTime = " << paraTimer->getElapsedTime() << ", runningPhase = " << static_cast<int>(runningPhase) << std::endl;
4240  {
4241  break;
4242  }
4243  }
4244  else
4245  {
4246  break;
4247  }
4248  }
4249 
4250  if( racingTermination
4253  && paraNodePool->getNumOfNodes() <= 1
4255  {
4256  /*
4257  * special timining problem
4258  *
4259  * 1113.58 S.4 I.SOL 0
4260  * 1113.58 S.3 is the racing winner! Selected strategy 2.
4261  * 1113.58 S.4 >(TERMINATED_IN_RACING_STAGE)
4262  *
4263  */
4264  break;
4265  }
4266 
4267  /*******************************************
4268  * waiting for any message form anywhere *
4269  *******************************************/
4270  double inIdleTime = paraTimer->getElapsedTime();
4271  (void)paraComm->probe(&source, &tag);
4272  lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
4273  if( messageHandler[tag] )
4274  {
4275  int status = (this->*messageHandler[tag])(source, tag);
4276  if( status )
4277  {
4278  std::ostringstream s;
4279  s << "[ERROR RETURN form Message Hander]:" << __FILE__ << "] func = "
4280  << __func__ << ", line = " << __LINE__ << " - "
4281  << "process tag = " << tag << std::endl;
4282  abort();
4283  }
4284  }
4285  else
4286  {
4287  THROW_LOGICAL_ERROR3( "No message hander for ", tag, " is not registered" );
4288  }
4289 
4290 #ifdef UG_WITH_UGS
4291  if( commUgs ) checkAndReadIncumbent();
4292 #endif
4293 
4294  /** completion message may delay */
4296  {
4297  delete paraRacingSolverPool;
4299  if( racingTermination )
4300  {
4301  break;
4302  }
4303  }
4304 
4305  /** output tabular solving status */
4316  {
4319  {
4321  {
4323  }
4324  else
4325  {
4327  }
4328  }
4329  else
4330  {
4332  }
4333  }
4334 
4335  switch ( runningPhase )
4336  {
4337  case RampUpPhase:
4338  {
4340  selfSplitFinisedSolvers->size() == (unsigned)(paraComm->getSize() - 1) ) // all solvers have finished self-split
4341  {
4345  delete selfSplitFinisedSolvers;
4348  {
4350  }
4351  break;
4352  }
4353  if( ( racingTermination && paraNodePool->isEmpty() ) ||
4356  {
4358 // std::cout << "sendInterrruptRequest1 11" << std::endl;
4360  }
4361  else
4362  {
4364  {
4365  // without consideration of keeping nodes in checkpoint file
4366  double globalBestDualBoundValueLocal =
4367  std::max (
4368  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
4371  {
4372  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() &&
4373  ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
4377  paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
4378  {
4381  }
4382  }
4383  else
4384  {
4386  {
4387  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() &&
4388  ( (signed)paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
4390  ( (signed)paraNodePool->getNumOfNodes()
4392  paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
4393  {
4396  }
4397  }
4398  }
4399  }
4400  else
4401  {
4403  {
4404  // maybe some solver hard to interrupt in a large scale execution
4405  // without consideration of keeping nodes in checkpoint file
4406  double globalBestDualBoundValueLocal =
4407  std::max (
4408  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
4410  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() &&
4413  paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) )
4414  {
4417  }
4418  }
4419  }
4420  (void) sendParaTasksToIdleSolvers();
4421  }
4422  break;
4423  }
4424  case NormalRunningPhase:
4425  {
4426  if( ( racingTermination && paraNodePool->isEmpty() )||
4433  {
4434  if( !paraSolverPool->isInterruptRequested(source) )
4435  {
4437 // std::cout << "sendInterrruptRequest1 12" << std::endl;
4438  }
4440  }
4441  else
4442  {
4443  (void) sendParaTasksToIdleSolvers();
4444  }
4447  {
4452  {
4455  }
4456  }
4457 
4458 #ifdef UG_WITH_ZLIB
4460  {
4463  {
4464  if( starvingTime < 0.0 )
4465  {
4467  }
4468  }
4469  else
4470  {
4471  starvingTime = -1.0;
4472  }
4473  // std::cout << "active solvers:" << paraSolverPool->getNumActiveSolvers() << std::endl;
4474  if( starvingTime > 0 &&
4477  ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() + paraNodePool->getNumOfNodes() )
4479  {
4480  hugeImbalance = false;
4481  restartInRampDownPhase();
4482  }
4483  }
4484 #endif
4485 
4487  {
4490  {
4491  if( hugeImbalanceTime < 0.0 )
4492  {
4495  }
4496  }
4497  else
4498  {
4500  hugeImbalanceTime = -1.0;
4501  }
4502  // std::cout << "active solvers:" << paraSolverPool->getNumActiveSolvers() << std::endl;
4503  if( hugeImbalanceTime > 0 &&
4506  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() > paraSolverPool->getNumActiveSolvers()*100 )
4507  {
4508  hugeImbalance = true;
4510  {
4512  }
4513  // reschedule collecting mode
4514  double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
4515  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
4516  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
4517  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
4518  }
4519  if( hugeImbalance &&
4521  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() < paraSolverPool->getNumActiveSolvers() * 5 ||
4523  {
4524  hugeImbalance = false;
4525  hugeImbalanceTime = -1.0;
4527  {
4529  }
4530  (void) sendParaTasksToIdleSolvers();
4531  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(-1.0); // restart collecting
4532  }
4533  }
4534 
4535  break;
4536  }
4537  case TerminationPhase:
4538  {
4539  break;
4540  }
4541  default:
4542  {
4543  THROW_LOGICAL_ERROR2( "Undefined running phase: ", static_cast<int>(runningPhase) );
4544  }
4545  }
4546 #ifdef UG_WITH_ZLIB
4550  {
4551  if( !( interruptIsRequested &&
4553  {
4554  updateCheckpointFiles();
4556  }
4557  }
4558 #endif
4559  }
4560 }
4561 
4562 #ifdef UG_WITH_ZLIB
4563 void
4564 BbParaLoadCoordinator::restartInRampDownPhase(
4565  )
4566 {
4567  updateCheckpointFiles();
4568  /** send interrupt request */
4569  int stayAlive = 0; // exit!
4570  for( int i = 1; i < paraComm->getSize(); i++ )
4571  {
4573  paraComm->send( &stayAlive, 1, ParaINT, i, TagInterruptRequest )
4574  );
4575  }
4576 
4577  /** the pupose of the updateCheckpoitFiles is two
4578  * 1. Can be killed during restaart, for example, in a case that a solver cannot be intterrupted so long time
4579  * 2. To update initial dual bound values
4580  */
4581  // updateCheckpointFiles();
4582 
4583  if( logSolvingStatusFlag )
4584  {
4586  << " Interrupt all solvers to restart"
4587  << std::endl;
4589  {
4591  "Interrupt all solvers to restart after "
4592  << paraTimer->getElapsedTime() << " seconds." << std::endl;
4593  }
4594  }
4595 
4596  exit(1); // Terminate LoadCoordinator. Restart did not work well over 10,000 solvers.
4597 
4599 
4600  /** for a timing issue, paraNodePool may not be empty. paraNodes in the pool should be just recived,
4601  * because paraSolverPool was empty. Then, no check for the ancestors.
4602  */
4603  while( !paraNodePool->isEmpty() )
4604  {
4605  ParaTask *node = paraNodePool->extractNode();
4606  delete node;
4607  }
4609  {
4611  delete node;
4612  }
4613 
4614  /*******************************************
4615  * waiting for any message form anywhere *
4616  *******************************************/
4617  for(;;)
4618  {
4619  int source;
4620  int tag;
4621  double inIdleTime = paraTimer->getElapsedTime();
4622  (void)paraComm->probe(&source, &tag);
4623  lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
4624  if( messageHandler[tag] )
4625  {
4626  int status = (this->*messageHandler[tag])(source, tag);
4627  if( status )
4628  {
4629  std::ostringstream s;
4630  s << "[ERROR RETURN form Message Hander]:" << __FILE__ << "] func = "
4631  << __func__ << ", line = " << __LINE__ << " - "
4632  << "process tag = " << tag << std::endl;
4633  abort();
4634  }
4635  }
4636  else
4637  {
4638  THROW_LOGICAL_ERROR3( "No message hander for ", tag, " is not registered" );
4639  }
4640 
4641 #ifdef UG_WITH_UGS
4642  if( commUgs ) checkAndReadIncumbent();
4643 #endif
4644 
4645  if( paraSolverPool->getNumActiveSolvers() == 0 )
4646  {
4647  break;
4648  }
4649 
4650  }
4651 
4652  if( !paraNodePool->isEmpty() )
4653  {
4654  std::cout << "Logical error occurred during restart in ramp-down phase." << std::endl;
4655  std::cout << "You can restart from the chakepoint file." << std::endl;
4656  // exit(1);
4657  abort();
4658  }
4659 
4660  while( !paraNodePoolToRestart->isEmpty() )
4661  {
4662  BbParaNode *node = dynamic_cast<BbParaNode *>(paraNodePoolToRestart->extractNode());
4664  paraNodePool->insert(node);
4665  }
4666 
4667  delete paraNodePoolToRestart;
4669 
4671  /** initialize paraSolerPool */
4672  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->reinitToRestart();
4673 
4674  for( int i = 1; i < paraComm->getSize(); i++ )
4675  {
4677  paraComm->send( NULL, 0, ParaBYTE, i, TagRestart )
4678  );
4679  }
4680 
4681  if( logSolvingStatusFlag )
4682  {
4684  << " Restart"
4685  << std::endl;
4687  {
4689  "Restart after "
4690  << paraTimer->getElapsedTime() << " seconds." << std::endl;
4691  }
4692  }
4693 
4694  (void) sendParaTasksToIdleSolvers();
4695 }
4696 #endif
4697 
4698 bool
4700  )
4701 {
4707  ( !restarted &&
4708  // paraParamSet->getBoolParamValue(RacingStatBranching) &&
4712  )
4713  )
4714  )
4715  {
4716  return false;
4717  }
4718 
4719  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
4720 
4721  bool sentNode = false;
4723  {
4724  BbParaNode *paraNode = 0;
4725  while( !paraNodePool->isEmpty() )
4726  {
4728  {
4729  if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4730  {
4731  paraNode = paraNodePool->extractNodeRandomly();
4732  }
4733  else
4734  {
4735  paraNode = paraNodePool->extractNode();
4736  }
4737  }
4738  else
4739  {
4740  paraNode = paraNodePool->extractNode();
4741  }
4742  if( !paraNode ) break;
4743  assert( !paraNode->getMergeNodeInfo() ||
4744  ( paraNode->getMergeNodeInfo() &&
4746  paraNode->getMergeNodeInfo()->mergedTo == 0 ) );
4747 
4749  ( ( !paraNode->getMergeNodeInfo() ) ||
4750  ( paraNode->getMergeNodeInfo() &&
4751  paraNode->getMergeNodeInfo()->nMergedNodes <= 0 ) ) )
4752  {
4753  assert( !paraNode->getMergeNodeInfo() || ( paraNode->getMergeNodeInfo() && paraNode->getMergeNodeInfo()->nMergedNodes == 0 ) );
4754  if( paraNode->getMergeNodeInfo() )
4755  {
4756  BbParaMergeNodeInfo *mNode = paraNode->getMergeNodeInfo();
4757  if( mNode->origDiffSubproblem )
4758  {
4759  paraNode->setDiffSubproblem(mNode->origDiffSubproblem);
4760  delete mNode->mergedDiffSubproblem;
4761  mNode->mergedDiffSubproblem = 0;
4762  mNode->origDiffSubproblem = 0;
4763  }
4764  paraNode->setMergeNodeInfo(0);
4765  paraNode->setMergingStatus(-1);
4766  assert(nodesMerger);
4768  }
4770  /*
4771  if( logSolvingStatusFlag )
4772  {
4773  *osLogSolvingStatus << paraTimer->getElapsedTime()
4774  << " node saved to the buffer. Dual bound:"
4775  << paraInitiator->convertToExternalValue( paraNode->getDualBoundValue() ) << std::endl;
4776  }
4777  */
4778  paraNode = 0;
4779 
4780  continue;
4781  }
4782 
4783  if( ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
4784  ( paraNode->getDualBoundValue() < bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() ||
4785  ( bbParaInitiator->isObjIntegral() &&
4786  static_cast<int>(ceil( paraNode->getDualBoundValue() ) )
4787  < static_cast<int>(bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() + MINEPSILON ) )
4788  ) ) ||
4789  !( bbParaInitiator->getGlobalBestIncumbentSolution() ) )
4790  {
4791  if( bbParaInitiator->getAbsgap(paraNode->getDualBoundValue() ) > bbParaInitiator->getAbsgapValue() ||
4792  bbParaInitiator->getGap(paraNode->getDualBoundValue()) > bbParaInitiator->getGapValue() )
4793  {
4794  break;
4795  }
4796  else
4797  {
4798 #ifdef UG_DEBUG_SOLUTION
4799  if( paraNode->getDiffSubproblem() && paraNode->getDiffSubproblem()->isOptimalSolIncluded() )
4800  {
4801  throw "Optimal solution going to be killed.";
4802  }
4803 #endif
4804  delete paraNode;
4805  paraNode = 0;
4806  lcts.nDeletedInLc++;
4808  {
4809  if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4810  {
4811  nNormalSelection = 0;
4812  }
4813  else
4814  {
4815  nNormalSelection++;
4816  }
4817  }
4818  /*
4819  std::cout << "dual bound = " << paraNode->getDualBoundValue() << std::endl;
4820  std::cout << "agap(dual bound) = " << paraInitiator->getAbsgap(paraNode->getDualBoundValue())
4821  << ", agap = " << paraInitiator->getAbsgapValue() << std::endl;
4822  std::cout << "gap(dual bound) = " << paraInitiator->getGap(paraNode->getDualBoundValue())
4823  << ", gap = " << paraInitiator->getGapValue() << std::endl;
4824  break;
4825  */
4826  }
4827  }
4828  else
4829  {
4830 #ifdef UG_DEBUG_SOLUTION
4831  if( paraNode->getDiffSubproblem() && paraNode->getDiffSubproblem()->isOptimalSolIncluded() )
4832  {
4833  throw "Optimal solution going to be killed.";
4834  }
4835 #endif
4836  delete paraNode;
4837  paraNode = 0;
4838  lcts.nDeletedInLc++;
4839  }
4840  }
4841 
4842  if( paraNode )
4843  {
4845  {
4846  if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4847  {
4848  nNormalSelection = 0;
4849  }
4850  else
4851  {
4852  nNormalSelection++;
4853  }
4854  }
4855 
4856  if( paraNode->getMergeNodeInfo() && paraNode->getMergeNodeInfo()->nMergedNodes == 0 )
4857  {
4858  BbParaMergeNodeInfo *mNode = paraNode->getMergeNodeInfo();
4859  paraNode->setDiffSubproblem(mNode->origDiffSubproblem);
4860  paraNode->setMergeNodeInfo(0);
4861  paraNode->setMergingStatus(-1);
4862  delete mNode->mergedDiffSubproblem;
4863  mNode->mergedDiffSubproblem = 0;
4864  mNode->origDiffSubproblem = 0;
4865  assert(nodesMerger);
4867  }
4869  paraNode->isSameParetntTaskSubtaskIdAs( TaskId() ) && // if parent is the root node
4870  paraNode->getDiffSubproblem() // paraNode deos not root
4871  )
4872  {
4873  bbParaInitiator->setInitialStatOnDiffSubproblem(
4875  dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem()));
4876  }
4877  // without consideration of keeping nodes in checkpoint file
4879  double globalBestDualBoundValueLocal =
4880  std::max (
4881  std::min( bbParaSolverPool->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
4883  int destination = bbParaSolverPool->activateSolver(paraNode,
4884  dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool), (runningPhase==RampUpPhase),
4885  paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains );
4886  if( destination < 0 )
4887  {
4888  /** cannot activate */
4889  paraNodePool->insert(paraNode);
4890  return sentNode;
4891  }
4892  else
4893  {
4894  lcts.nSent++;
4895  writeTransferLog(destination);
4896  sentNode = true;
4897  if( runningPhase == RampUpPhase &&
4900  // paraSolverPool->getNumActiveSolvers() < paraSolverPool->getNSolvers()/2
4904  )
4905  {
4906  int nCollect = -1;
4908  paraComm->send( &nCollect, 1, ParaINT, destination, TagCollectAllNodes )
4909  );
4910  }
4911  if( logSolvingStatusFlag )
4912  {
4914  << " S." << destination << " < "
4915  << bbParaInitiator->convertToExternalValue(
4916  paraNode->getDualBoundValue() );
4917  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
4918  {
4919  if( bbParaInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
4920  {
4921  *osLogSolvingStatus << " ( Inf )";
4922  }
4923  else
4924  {
4925  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
4926  }
4927  }
4932  {
4933  *osLogSolvingStatus << " L";
4934  }
4935  if( paraNode->getMergeNodeInfo() )
4936  {
4937  *osLogSolvingStatus << " M(" << paraNode->getMergeNodeInfo()->nMergedNodes + 1 << ")";
4938  if( paraNode->getMergeNodeInfo()->nMergedNodes < 1 )
4939  {
4940  std::cout << "node id = " << (paraNode->getTaskId()).toString() << std::endl;
4941  abort();
4942  }
4943  }
4944  if( paraNode->getDiffSubproblem() )
4945  {
4946  *osLogSolvingStatus << " " << paraNode->toSimpleString()
4947  << ", "
4948  // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges();
4949  << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
4950  }
4951  // for debug
4952  // *osLogSolvingStatus << " " << paraNode->toSimpleString();
4953  *osLogSolvingStatus << std::endl;
4954  }
4955 #ifdef _DEBUG_LB
4956  std::cout << paraTimer->getElapsedTime()
4957  << " S." << destination << " < "
4958  << paraInitiator->convertToExternalValue(
4959  paraNode->getDualBoundValue() );
4960  if( paraInitiator->getGlobalBestIncumbentSolution() )
4961  {
4962  if( paraInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
4963  {
4964  std::cout << " ( Inf )";
4965  }
4966  else
4967  {
4968  std::cout << " ( " << paraInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
4969  }
4970  }
4975  {
4976  std::cout << " L";
4977  }
4978  std::cout << std::endl;
4979 #endif
4980  }
4981  }
4982  else
4983  {
4984  break;
4985  }
4986  }
4987  return sentNode;
4988 }
4989 
4990 #ifdef UG_WITH_ZLIB
4991 void
4992 BbParaLoadCoordinator::updateCheckpointFiles(
4993  )
4994 {
4995  time_t timer;
4996  char timeStr[30];
4997 
4998  if( paraNodePoolToRestart )
4999  {
5000  return; // Interrupting all solvers;
5001  }
5002 
5004  {
5005  return; // Collecting nodes.
5006  }
5007 
5009  {
5010  return;
5011  }
5012 
5013  /** get checkpoint time */
5014  time(&timer);
5015  /** make checkpoint time string */
5016 #ifdef _MSC_VER
5017  int bufsize = 256;
5018  ctime_s(timeStr, bufsize, &timer);
5019 #else
5020  ctime_r(&timer, timeStr);
5021 #endif
5022  for( int i = 0; timeStr[i] != '\0' && i < 26; i++ )
5023  {
5024  if( timeStr[i] == ' ') timeStr[i] = '_';
5025  if( timeStr[i] == '\n' ) timeStr[i] = '\0';
5026  }
5027  char *newCheckpointTimeStr = &timeStr[4]; // remove a day of the week
5028  // std::cout << "lstCheckpointTimeStr = " << lastCheckpointTimeStr << std::endl;
5029  // std::cout << "newCheckpointTimeStr = " << newCheckpointTimeStr << std::endl;
5030  if( strcmp(newCheckpointTimeStr,lastCheckpointTimeStr) == 0 )
5031  {
5032  int l = strlen(newCheckpointTimeStr);
5033  newCheckpointTimeStr[l] = 'a';
5034  newCheckpointTimeStr[l+1] = '\0';
5035  }
5036 
5037  /** save nodes information */
5038  char nodesFileName[MaxStrLen];
5039  snprintf(nodesFileName, MaxStrLen, "%s%s_%s_nodes_LC%d.gz",
5041  paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr, paraComm->getRank());
5042  gzstream::ogzstream checkpointNodesStream;
5043  checkpointNodesStream.open(nodesFileName, std::ios::out | std::ios::binary);
5044  if( !checkpointNodesStream )
5045  {
5046  std::cout << "Checkpoint file for ParaNodes cannot open. file name = " << nodesFileName << std::endl;
5047  exit(1);
5048  }
5049  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->updateDualBoundsForSavingNodes();
5051  int n = 0;
5053  {
5054  n += paraNodeToKeepCheckpointFileNodes->writeBbParaNodesToCheckpointFile(checkpointNodesStream);
5055  }
5056  n += dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->writeParaNodesToCheckpointFile(checkpointNodesStream);
5057  n += paraNodePool->writeBbParaNodesToCheckpointFile(checkpointNodesStream);
5059  {
5060  int nUnprocessedNodes = unprocessedParaNodes->writeBbParaNodesToCheckpointFile(checkpointNodesStream);
5063  {
5064  for(int i = n;
5067  i++ )
5068  {
5069  BbParaNode *tempParaNode = unprocessedParaNodes->extractNode();
5070  paraNodePool->insert(tempParaNode);
5071  }
5072  }
5073  n += nUnprocessedNodes;
5074  }
5075  checkpointNodesStream.close();
5076  if( logSolvingStatusFlag )
5077  {
5079  << " Checkpoint: " << n << " ParaNodes were saved" << std::endl;
5080  }
5081 #ifdef _DEBUG_LB
5082  std::cout << paraTimer->getElapsedTime()
5083  << " Checkpoint: " << n << " ParaNodes were saved" << std::endl;
5084 #endif
5085 
5087  {
5089  "Storing check-point data after " <<
5090  paraTimer->getElapsedTime() << " seconds. " <<
5091  n << " nodes were saved." << std::endl;
5092  }
5093 
5094  /** save incumbent solution */
5095  char solutionFileName[MaxStrLen];
5096  if( paraComm->getRank() == 0 )
5097  {
5098  snprintf(solutionFileName, MaxStrLen, "%s%s_%s_solution.gz",
5100  paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr);
5101  paraInitiator->writeCheckpointSolution(std::string(solutionFileName));
5102  }
5103 
5104  /** save Solver statistics */
5105  char solverStatisticsFileName[MaxStrLen];
5106  snprintf(solverStatisticsFileName, MaxStrLen, "%s%s_%s_solverStatistics_LC%d.gz",
5108  paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr, paraComm->getRank());
5109  gzstream::ogzstream checkpointSolverStatisticsStream;
5110  checkpointSolverStatisticsStream.open(solverStatisticsFileName, std::ios::out | std::ios::binary);
5111  if( !checkpointSolverStatisticsStream )
5112  {
5113  std::cout << "Checkpoint file for SolverStatistics cannot open. file name = " << solverStatisticsFileName << std::endl;
5114  exit(1);
5115  }
5116  int nSolverInfo = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->writeSolverStatisticsToCheckpointFile(checkpointSolverStatisticsStream);
5117  checkpointSolverStatisticsStream.close();
5118 
5119  /** save LoadCoordinator statistics */
5120  char loadCoordinatorStatisticsFileName[MaxStrLen];
5121  snprintf(loadCoordinatorStatisticsFileName, MaxStrLen, "%s%s_%s_loadCoordinatorStatistics_LC%d.gz",
5123  paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr, paraComm->getRank());
5124  gzstream::ogzstream loadCoordinatorStatisticsStream;
5125  loadCoordinatorStatisticsStream.open(loadCoordinatorStatisticsFileName, std::ios::out | std::ios::binary);
5126  if( !loadCoordinatorStatisticsStream )
5127  {
5128  std::cout << "Checkpoint file for SolverStatistics cannot open. file name = " << loadCoordinatorStatisticsFileName << std::endl;
5129  exit(1);
5130  }
5131  // double globalBestDualBoundValue =
5132  // std::max (
5133  // std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
5134  // lcts.globalBestDualBoundValue );
5135  // double externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(globalBestDualBoundValue);
5136  writeLoadCoordinatorStatisticsToCheckpointFile(loadCoordinatorStatisticsStream, nSolverInfo,
5138  loadCoordinatorStatisticsStream.close();
5139 
5140  if( lastCheckpointTimeStr[0] == ' ' )
5141  {
5142  /** the first time for checkpointing */
5143  if( racingWinnerParams )
5144  {
5145  /** save racing winner params */
5146  char racingWinnerParamsName[MaxStrLen];
5147  snprintf(racingWinnerParamsName, MaxStrLen, "%s%s_racing_winner_params.gz",
5150  gzstream::ogzstream racingWinnerParamsStream;
5151  racingWinnerParamsStream.open(racingWinnerParamsName, std::ios::out | std::ios::binary);
5152  if( !racingWinnerParamsStream )
5153  {
5154  std::cout << "Racing winner parameter file cannot open. file name = " << racingWinnerParamsName << std::endl;
5155  exit(1);
5156  }
5157  racingWinnerParams->write(racingWinnerParamsStream);
5158  racingWinnerParamsStream.close();
5159  }
5160  }
5161  else
5162  {
5163  /** remove old check point files */
5164  snprintf(nodesFileName, MaxStrLen, "%s%s_%s_nodes_LC%d.gz",
5167  if( paraComm->getRank() == 0 )
5168  {
5169  snprintf(solutionFileName, MaxStrLen, "%s%s_%s_solution.gz",
5172  }
5173  snprintf(solverStatisticsFileName, MaxStrLen, "%s%s_%s_solverStatistics_LC%d.gz",
5176  snprintf(loadCoordinatorStatisticsFileName, MaxStrLen, "%s%s_%s_loadCoordinatorStatistics_LC%d.gz",
5179  if( remove(nodesFileName) )
5180  {
5181  std::cout << "checkpoint nodes file cannot be removed: errno = " << strerror(errno) << std::endl;
5182  exit(1);
5183  }
5184  if ( remove(solutionFileName) )
5185  {
5186  std::cout << "checkpoint solution file cannot be removed: errno = " << strerror(errno) << std::endl;
5187  exit(1);
5188  }
5189  if ( remove(solverStatisticsFileName) )
5190  {
5191  std::cout << "checkpoint SolverStatistics file cannot be removed: errno = " << strerror(errno) << std::endl;
5192  exit(1);
5193  }
5194  if ( remove(loadCoordinatorStatisticsFileName) )
5195  {
5196  std::cout << "checkpoint LoadCoordinatorStatistics file cannot be removed: errno = " << strerror(errno) << std::endl;
5197  exit(1);
5198  }
5199  }
5200 
5201  char afterCheckpointingSolutionFileName[MaxStrLen];
5202  snprintf(afterCheckpointingSolutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
5205  gzstream::igzstream afterCheckpointingSolutionStream;
5206  afterCheckpointingSolutionStream.open(afterCheckpointingSolutionFileName, std::ios::in | std::ios::binary);
5207  if( afterCheckpointingSolutionStream )
5208  {
5209  /** afater checkpointing solution file exists */
5210  afterCheckpointingSolutionStream.close();
5211  if ( remove(afterCheckpointingSolutionFileName) )
5212  {
5213  std::cout << "after checkpointing solution file cannot be removed: errno = " << strerror(errno) << std::endl;
5214  exit(1);
5215  }
5216  }
5217 
5218  /** update last checkpoint time string */
5219  strcpy(lastCheckpointTimeStr,newCheckpointTimeStr);
5220 }
5221 
5222 void
5223 BbParaLoadCoordinator::writeLoadCoordinatorStatisticsToCheckpointFile(
5224  gzstream::ogzstream &loadCoordinatorStatisticsStream,
5225  int nSolverInfo,
5226  double globalBestDualBoundValue,
5227  double externalGlobalBestDualBoundValue
5228  )
5229 {
5230  loadCoordinatorStatisticsStream.write((char *)&nSolverInfo, sizeof(int));
5231  lcts.isCheckpointState = true;
5233  {
5236  }
5237  else
5238  {
5241  }
5242  lcts.nNodesLeftInAllSolvers = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers();
5243  lcts.globalBestDualBoundValue = std::max( globalBestDualBoundValue, lcts.globalBestDualBoundValue );
5246  if( nodesMerger )
5247  {
5252  }
5253  lcts.write(loadCoordinatorStatisticsStream);
5254 }
5255 
5256 void
5257 BbParaLoadCoordinator::warmStart(
5258  )
5259 {
5260  ///
5261  /// check parameter consistency
5262  ///
5264  {
5266  {
5267  std::cout << "*** When warm start with racing is specified, you should specify CollectOnce = TRUE ***" << std::endl;
5269  {
5270  std::cout << "*** When warm start with racing is specified, you cannot specify MergeNodesAtRestart = TRUE ***" << std::endl;
5271  }
5272  exit(1);
5273  }
5275  {
5276  std::cout << "*** When warm start with racing is specified, you cannot specify MergeNodesAtRestart = TRUE ***" << std::endl;
5277  exit(1);
5278  }
5279  std::cout << "*** Warm start with racing ramp-up ***" << std::endl;
5280  }
5281  else
5282  {
5284  {
5286  }
5287  std::cout << "*** Warm start with normal ramp-up ***" << std::endl;
5288  }
5289 
5290 
5291  restarted = true;
5292  /** write previous statistics information */
5293  writePreviousStatisticsInformation();
5294 
5295  if( paraParams->getIntParamValue(RampUpPhaseProcess) == 0 ) // if it is not racing ramp-up
5296  {
5297  /** try to read racing winner params */
5298  char racingWinnerParamsName[MaxStrLen];
5299  snprintf(racingWinnerParamsName, MaxStrLen, "%s%s_racing_winner_params.gz",
5302  gzstream::igzstream racingWinnerParamsStream;
5303  racingWinnerParamsStream.open(racingWinnerParamsName, std::ios::in | std::ios::binary);
5304  if( racingWinnerParamsStream )
5305  {
5306  assert(!racingWinnerParams);
5308  racingWinnerParams->read(paraComm, racingWinnerParamsStream);
5309  racingWinnerParamsStream.close();
5310  for( int i = 1; i < paraComm->getSize(); i++ )
5311  {
5312  /** send racing winner params: NOTE: should not broadcast. if we do it, solver routine need to recognize staring process */
5315  );
5316  }
5317  std::cout << "*** winner parameter is read from " << racingWinnerParamsName << "***" << std::endl;
5318  }
5319  }
5320 
5321  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5322 
5323  /** set solution and get internal incumbent value */
5324  char afterCheckpointingSolutionFileName[MaxStrLen];
5325  snprintf(afterCheckpointingSolutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
5328  double incumbentValue = paraInitiator->readSolutionFromCheckpointFile(afterCheckpointingSolutionFileName);
5330  {
5331  bbParaInitiator->writeSolution("[Warm started from "+std::string(bbParaInitiator->getPrefixWarm())+" : the solution from the checkpoint file]");
5332  }
5333 
5334  int n = 0;
5335  BbParaNode *paraNode;
5336  bool onlyBoundChanges = false;
5338  {
5339  onlyBoundChanges = true;
5340  }
5342  {
5343  if( nodesMerger ) delete nodesMerger;
5344  nodesMerger = new BbParaNodesMerger(dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance())->getVarIndexRange(),
5345  nBoundChangesOfBestNode,paraTimer,dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance()),paraParams);
5346  }
5347 
5349 
5350  for(;;)
5351  {
5352  paraNode = bbParaInitiator->readParaNodeFromCheckpointFile(onlyBoundChanges);
5353  // paraParamSet->getBoolParamValue(MergingNodeStatusInCheckpointFile) );
5354  if( paraNode == 0 )
5355  break;
5356 #ifdef UG_DEBUG_SOLUTION
5357 #ifdef UG_DEBUG_SOLUTION_OPT_PATH
5358  if( paraNode->getDiffSubproblem() && (!paraNode->getDiffSubproblem()->isOptimalSolIncluded()) )
5359  {
5360  delete paraNode;
5361  paraNode = 0;
5362  continue;
5363  }
5364 #endif
5365 #endif
5366  n++;
5367  if( paraNode->getAncestor() )
5368  {
5369  std::cout << "Checkpoint node has ancestor: " << paraNode->toString() << std::endl;
5370  std::cout << "Something wrong for this checkpoint file." << std::endl;
5371  exit(1);
5372  }
5373  paraNode->setDualBoundValue(paraNode->getInitialDualBoundValue());
5374  // paraNodePool->insert(paraNode); /** in order to sort ParaNodes, insert paraNodePool once */
5378  {
5379  tempParaNodePool.insert(paraNode); /** in order to sort ParaNodes with new dual value, insert it to tempParaNodePool once */
5380  // addNodeToMergeNodeStructs(paraNode);
5381  }
5382  else
5383  {
5384  paraNodePool->insert(paraNode); /** in order to sort ParaNodes, insert paraNodePool once */
5385  }
5386  }
5387 
5389  {
5391  {
5392  std::cout << "### NNodesToKeepInCheckpointFile is specified to "
5394  << " and also NEagerToSolveAtRestart is specified to "
5396  << ". The both values should not greater than 0 together." << std::endl;
5397  exit(-1);
5398  }
5400  {
5401  std::cout << "### NNodesToKeepInCheckpointFile is specified to "
5403  << " and also MergeNodesAtRestart = TRUE is specified. This combination is not allowed." << std::endl;
5404  exit(-1);
5405  }
5406  if( (signed)tempParaNodePool.getNumOfNodes() <= paraParams->getIntParamValue(NNodesToKeepInCheckpointFile) )
5407  {
5408  std::cout << "### NNodesToKeepInCheckpointFile is specified to " << paraParams->getIntParamValue(NNodesToKeepInCheckpointFile) <<
5409  ", but the number of nodes in checkpoint file is " << tempParaNodePool.getNumOfNodes() << ". ###" << std::endl;
5410  exit(-1);
5411  }
5413  {
5414  std::cout << "### NEagerToSolveAtRestart is specified to "
5416  << ", but RampUpPhaseProcess != 0 is specified. This combination is not allowed." << std::endl;
5417  exit(-1);
5418  }
5420  for(int i = 0; i < paraParams->getIntParamValue(NNodesToKeepInCheckpointFile); i++ )
5421  {
5422  BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5424  }
5425  while( tempParaNodePool.getNumOfNodes() > 0 )
5426  {
5427  BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5428  paraNodePool->insert(tempParaNode);
5429  }
5430  std::cout << "### NNodesToKeepInCheckpointFile is specified to "
5432  << " ###" << std::endl;
5433  std::cout << "### The number of no process nodes = " << paraNodeToKeepCheckpointFileNodes->getNumOfNodes()
5434  << " ###" << std::endl;
5435  std::cout << "### The number of nodes will be processed = " << paraNodePool->getNumOfNodes()
5436  << " ###" << std::endl;
5437  }
5438 
5440  {
5441  if( (signed)tempParaNodePool.getNumOfNodes() < paraParams->getIntParamValue(NEagerToSolveAtRestart) )
5442  {
5443  std::cout << "### NEagerToSolveAtRestart is specified to " << paraParams->getIntParamValue(NEagerToSolveAtRestart) <<
5444  ", but the number of nodes in checkpoint file is " << tempParaNodePool.getNumOfNodes() << ". ###" << std::endl;
5445  exit(-1);
5446  }
5448  {
5449  std::cout << "### NEagerToSolveAtRestart is specified to "
5451  << " and also MergeNodesAtRestart = TRUE is specified. This combination is not allowed." << std::endl;
5452  exit(-1);
5453  }
5455  {
5456  std::cout << "### NEagerToSolveAtRestart is specified to "
5458  << ", but RampUpPhaseProcess != 0 is specified. This combination is not allowed." << std::endl;
5459  exit(-1);
5460  }
5462  for(int i = 0; i < paraParams->getIntParamValue(NEagerToSolveAtRestart); i++ )
5463  {
5464  BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5465  paraNodePool->insert(tempParaNode);
5466  }
5467  while( tempParaNodePool.getNumOfNodes() > 0 )
5468  {
5469  BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5470  unprocessedParaNodes->insert(tempParaNode);
5471  }
5472  std::cout << "### NEagerToSolveAtRestart is specified to "
5474  << " ###" << std::endl;
5475  std::cout << "### The number of no process nodes in the beginning = " << unprocessedParaNodes->getNumOfNodes()
5476  << " ###" << std::endl;
5477  }
5478 
5479  // std::cout << "insrt to node pool: " << paraTimer->getElapsedTime() << std::endl;
5480 
5482  {
5483  int nMerge = 0;
5484  BbParaNode *tempNode = 0;
5485  while( ( tempNode = tempParaNodePool.extractNode() ) )
5486  {
5487  if( nBoundChangesOfBestNode < 0 )
5488  {
5489  if( tempNode->getDiffSubproblem() )
5490  {
5491  nBoundChangesOfBestNode = dynamic_cast<BbParaDiffSubproblem *>(tempNode->getDiffSubproblem())->getNBoundChanges();
5492  }
5493  else
5494  {
5496  }
5497  }
5498  paraNodePool->insert(tempNode);
5501  {
5502  assert(nodesMerger);
5504  nMerge++;
5505  }
5506  }
5507  assert(nodesMerger);
5509  }
5510 
5513 
5514  // std::cout << "merging finished:" << paraTimer->getElapsedTime() << std::endl;
5515 
5516  if( logSolvingStatusFlag )
5517  {
5518  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
5519  {
5521  << " Warm started from "
5523  << " : " << n << " ParaNodes read. Current incumbent value = "
5524  << bbParaInitiator->convertToExternalValue(
5526  << std::endl;
5527  }
5528  else
5529  {
5531  << " Warm started from "
5533  << " : " << n << " ParaNodes read. No solution is generated." << std::endl;
5534  }
5535  }
5536 #ifdef _DEBUG_LB
5537  std::cout << paraTimer->getElapsedTime()
5538  << " Warm started from "
5540  << " : " << n << " ParaNodes read. Current incumbent value = "
5541  << paraInitiator->convertToExternalValue(
5542  paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() )
5543  << std::endl;
5544 #endif
5547  {
5548  for( int i = 1; i < paraComm->getSize(); i++ )
5549  {
5550  /** send internal incumbent value */
5552  paraComm->send( &incumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
5553  );
5555  {
5556  bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, i);
5557  }
5558  /** send internal global dual bound value */
5561  );
5562  }
5564  (void) sendParaTasksToIdleSolvers();
5565  warmStartNodeTransferring = false;
5567  {
5569  }
5570  else
5571  {
5572  // without consideration of keeping nodes in checkpoint file
5573  double globalBestDualBoundValueLocal =
5574  std::max (
5575  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
5578  {
5580  {
5581  if( ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
5585  paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
5586  {
5589  }
5590  else
5591  {
5593  }
5594  }
5595  else
5596  {
5597  if( ( (signed)paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
5599  ( (signed)paraNodePool->getNumOfNodes()
5601  paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
5602  {
5605  }
5606  else
5607  {
5609  }
5610  }
5611  }
5612  else
5613  {
5615  {
5616  if( ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
5620  paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
5621  {
5624  }
5625  else
5626  {
5628  }
5629  }
5630  else
5631  {
5634  }
5635  }
5636  }
5637  // std::cout << "before run:" << paraTimer->getElapsedTime() << std::endl;
5638  // exit(1);
5639  run();
5640  }
5641  else
5642  {
5644  || paraParams->getIntParamValue(RampUpPhaseProcess) == 2 ) // if it isracing ramp-up
5645  {
5646  /// racing ramp-up
5647  assert(!racingWinnerParams);
5648 
5649  paraNode = paraNodePool->extractNode();
5652  paraInitiator->generateRacingRampUpParameterSets( (paraComm->getSize()-1), racingRampUpParams );
5653 
5654  if( paraNodePool->isEmpty() )
5655  {
5656  for( int i = 1; i < paraComm->getSize(); i++ )
5657  {
5658  int noKeep = 0;
5660  paraComm->send( &noKeep, 1, ParaINT, i, TagKeepRacing)
5661  );
5663  racingRampUpParams[i-1]->send(paraComm, i)
5664  );
5665  }
5666  }
5667  else
5668  {
5669  for( int i = 1; i < paraComm->getSize(); i++ )
5670  {
5671  int keep = 1;
5673  paraComm->send( &keep, 1, ParaINT, i, TagKeepRacing)
5674  );
5676  racingRampUpParams[i-1]->send(paraComm, i)
5677  );
5678  }
5679  }
5680 
5681  run(paraNode, (paraComm->getSize()-1), racingRampUpParams );
5682 
5683  if( paraNodePool->isEmpty() )
5684  {
5685  for( int i = 1; i < paraComm->getSize(); i++ )
5686  {
5687  /** send internal incumbent value */
5689  paraComm->send( &incumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
5690  );
5692  {
5693  bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, i);
5694  }
5695  /** send internal global dual bound value */
5698  );
5699  if( racingRampUpParams[i-1] ) delete racingRampUpParams[i-1];
5700  }
5701  }
5702  else
5703  {
5704  for( int i = 1; i < paraComm->getSize(); i++ )
5705  {
5706  /** send internal incumbent value */
5708  paraComm->send( &incumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
5709  );
5711  {
5712  bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, i);
5713  }
5714  /** send internal global dual bound value */
5717  );
5719  paraComm->send( NULL, 0, ParaBYTE, i, TagKeepRacing)
5720  );
5721  if( racingRampUpParams[i-1] ) delete racingRampUpParams[i-1];
5722  }
5723  }
5724  delete [] racingRampUpParams;
5725  }
5726  }
5727 
5728 }
5729 
5730 void
5731 BbParaLoadCoordinator::writePreviousStatisticsInformation(
5732  )
5733 {
5734  /* read previous LoadCoordinator statistics */
5735  char loadCoordinatorStatisticsFileName[MaxStrLen];
5736  snprintf(loadCoordinatorStatisticsFileName, MaxStrLen, "%s_loadCoordinatorStatistics_LC0.gz", paraInitiator->getPrefixWarm());
5737  gzstream::igzstream loadCoordinatorStatisticsStream;
5738  loadCoordinatorStatisticsStream.open(loadCoordinatorStatisticsFileName, std::ios::in | std::ios::binary);
5739  if( !loadCoordinatorStatisticsStream )
5740  {
5741  std::cout << "checkpoint LoadCoordinatorStatistics file cannot open: file name = " << loadCoordinatorStatisticsFileName << std::endl;
5742  exit(1);
5743  }
5744  int nSolverStatistics;
5745  loadCoordinatorStatisticsStream.read((char *)&nSolverStatistics, sizeof(int));
5747  if( !prevLcts->read(paraComm, loadCoordinatorStatisticsStream) )
5748  {
5749  std::cout << "checkpoint LoadCoordinatorStatistics file cannot read: file name = " << loadCoordinatorStatisticsFileName << std::endl;
5750  exit(1);
5751  }
5752  loadCoordinatorStatisticsStream.close();
5753 
5754  /* open Solver statistics file */
5755  char solverStatisticsFileName[MaxStrLen];
5756  snprintf(solverStatisticsFileName, MaxStrLen, "%s_solverStatistics_LC0.gz", paraInitiator->getPrefixWarm());
5757  gzstream::igzstream solverStatisticsStream;
5758  solverStatisticsStream.open(solverStatisticsFileName, std::ios::in | std::ios::binary);
5759  if( !solverStatisticsStream )
5760  {
5761  std::cout << "checkpoint SolverStatistics file cannot open: file name = " << solverStatisticsFileName << std::endl;
5762  exit(1);
5763  }
5764 
5765  /* opne output statistics file */
5766  char previousStatisticsFileName[MaxStrLen];
5767  snprintf(previousStatisticsFileName, MaxStrLen, "%s_statistics_w%05lld_LC0",
5769  prevLcts->nWarmStart);
5770  std::ofstream ofsStatistics;
5771  ofsStatistics.open(previousStatisticsFileName);
5772  if( !ofsStatistics )
5773  {
5774  std::cout << "previous statistics file cannot open : file name = " << previousStatisticsFileName << std::endl;
5775  exit(1);
5776  }
5777 
5778  /* read and write solver statistics */
5779  for( int i = 0; i < nSolverStatistics; i++ )
5780  {
5782  if( !psts->read(paraComm, solverStatisticsStream) )
5783  {
5784  std::cout << "checkpoint SolverStatistics file cannot read: file name = " << solverStatisticsFileName << std::endl;
5785  exit(1);
5786  }
5787  ofsStatistics << psts->toString(paraInitiator);
5788  delete psts;
5789  }
5790 
5791  /* write LoadCoordinator statistics */
5792  ofsStatistics << prevLcts->toString();
5793 
5794  /* update warm start counter */
5795  lcts.nWarmStart = prevLcts->nWarmStart + 1;
5798  delete prevLcts;
5799 
5800  /* close solver statistics file and output file */
5801  solverStatisticsStream.close();
5802  ofsStatistics.close();
5803 }
5804 
5805 #endif // End of UG_WITH_ZLIB
5806 
5807 void
5809  ParaTask *paraNode
5810  )
5811 {
5813  {
5814  outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
5815  }
5816 
5817  assert(!paraRacingSolverPool);
5818  // without consideration of keeping nodes in checkpoint file
5819  double globalBestDualBoundValueLocal =
5820  std::max (
5821  std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
5823 
5825  {
5826  int destination = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activateSolver(
5827  dynamic_cast<BbParaNode *>(paraNode),
5829  paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains );
5830  lcts.nSent++;
5833  )
5834  {
5835  int nCollect = -1;
5837  paraComm->send( &nCollect, 1, ParaINT, destination, TagCollectAllNodes )
5838  );
5839  }
5841  {
5842  int token[2];
5843  token[0] = 1;
5844  token[1] = -1;
5846  paraComm->send( token, 2, ParaINT, token[0], TagToken )
5847  );
5848  }
5849  writeTransferLog(destination);
5850 
5851  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5852 
5853  if( logSolvingStatusFlag )
5854  {
5856  << " S." << destination << " < "
5857  << bbParaInitiator->convertToExternalValue(
5858  dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() );
5859  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
5860  {
5861  if( bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) > displayInfOverThisValue )
5862  {
5863  *osLogSolvingStatus << " ( Inf )";
5864  }
5865  else
5866  {
5867  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) * 100 << "% )";
5868  }
5869  }
5874  {
5875  *osLogSolvingStatus << " L";
5876  }
5877  *osLogSolvingStatus << std::endl;
5878  }
5879 #ifdef DEBUG_LB
5880  std::cout << paraTimer->getElapsedTime()
5881  << " S." << destination << " > "
5882  << paraInitiator->convertToExternalValue(
5883  paraNode->getDualBoundValue() );
5884  if( paraInitiator->getGlobalBestIncumbentSolution() )
5885  {
5886  if( paraInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
5887  {
5888  std::cout << " ( Inf )";
5889  }
5890  else
5891  {
5892  std::cout << " ( " << paraInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
5893  }
5894  }
5899  {
5900  std::cout << " L";
5901  }
5902  std::cout << std::endl;
5903 #endif
5904  }
5905  else // self-split ramp-up
5906  {
5907  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5908  DEF_BB_PARA_COMM(bbParaComm, paraComm);
5909  delete paraNode;
5910  for( unsigned int i = 0; i < paraSolverPool->getNSolvers(); i++ )
5911  {
5912  paraNode = bbParaComm->createParaNode(
5913  TaskId(), TaskId(), 0, -DBL_MAX, -DBL_MAX, -DBL_MAX,
5914  bbParaInitiator->makeRootNodeDiffSubproblem()
5915  );
5916  int destination = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activateSolver(
5917  dynamic_cast<BbParaNode *>(paraNode),
5919  paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains );
5920  lcts.nSent++;
5921  writeTransferLog(destination);
5922 
5923  if( logSolvingStatusFlag )
5924  {
5926  << " S." << destination << " < "
5927  << bbParaInitiator->convertToExternalValue(
5928  dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() );
5929  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
5930  {
5931  if( bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) > displayInfOverThisValue )
5932  {
5933  *osLogSolvingStatus << " ( Inf )";
5934  }
5935  else
5936  {
5937  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) * 100 << "% )";
5938  }
5939  }
5940  *osLogSolvingStatus << std::endl;
5941  }
5943  {
5944  int token[2];
5945  token[0] = 1;
5946  token[1] = -1;
5948  paraComm->send( token, 2, ParaINT, token[0], TagToken )
5949  );
5950  }
5951  }
5952  }
5953 
5954  run();
5955 }
5956 
5957 int
5959  int source,
5960  int tag
5961  )
5962 {
5963 
5964  BbParaSolverState *solverState = dynamic_cast<BbParaSolverState *>(paraComm->createParaSolverState());
5965  solverState->receive(paraComm, source, tag);
5966 
5967 #ifdef _DEBUG_DET
5968  if( paraDetTimer )
5969  {
5970  std::cout << "Rank " << source << ": ET = " << paraDetTimer->getElapsedTime() << ", Det time = " << solverState->getDeterministicTime() << std::endl;
5971  }
5972 #endif
5973 
5974  if( paraDetTimer
5975  && paraDetTimer->getElapsedTime() < solverState->getDeterministicTime() )
5976 
5977  {
5979  }
5980 
5981  assert(solverState->isRacingStage());
5982  if( !restartingRacing ) // restartingRacing means that LC is terminating racing solvers.
5983  {
5984  dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->updateSolverStatus(source,
5985  solverState->getNNodesSolved(),
5986  solverState->getNNodesLeft(),
5987  solverState->getSolverLocalBestDualBoundValue());
5988  assert( dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNumNodesLeft(source) == solverState->getNNodesLeft() );
5989  }
5990 
5991  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5992 
5993  if( logSolvingStatusFlag )
5994  {
5996  << " S." << source << " | "
5997  << bbParaInitiator->convertToExternalValue(
5998  solverState->getSolverLocalBestDualBoundValue()
5999  );
6000  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6001  bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) > displayInfOverThisValue
6002  || solverState->getNNodesLeft() == 0 )
6003  {
6004  *osLogSolvingStatus << " ( Inf )";
6005  }
6006  else
6007  {
6008  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
6009  }
6010  *osLogSolvingStatus << " [ " << solverState->getNNodesLeft() << " ]";
6011  double globalBestDualBoundValue = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue();
6012  if( paraNodePool->getNumOfNodes() > 0 )
6013  {
6014  globalBestDualBoundValue = std::min( globalBestDualBoundValue, paraNodePool->getBestDualBoundValue() );
6015  }
6016  *osLogSolvingStatus << " ** G.B.: " << bbParaInitiator->convertToExternalValue(globalBestDualBoundValue);
6017  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6018  bbParaInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
6019  {
6020  *osLogSolvingStatus << " ( Inf ) ";
6021  }
6022  else
6023  {
6024  *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
6025  }
6026  *osLogSolvingStatus << "[ " << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver()
6027  // <<" ] ** RR" << std::endl;
6028  <<" ] ** RR " << solverState->getDeterministicTime() << std::endl; // for debug
6029  }
6030 #ifdef _DEBUG_LB
6031  std::cout << paraTimer->getElapsedTime()
6032  << " S." << source << " | "
6033  << bbParaInitiator->convertToExternalValue(
6034  solverState->getSolverLocalBestDualBoundValue()
6035  );
6036  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6037  bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) > displayInfOverThisValue
6038  || solverState->getNNodesLeft() == 0 )
6039  {
6040  std::cout << " ( Inf )";
6041  }
6042  else
6043  {
6044  std::cout << " ( " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
6045  }
6046  std::cout << " [ " << solverState->getNNodesLeft() << " ]";
6047  double globalBestDualBoundValue = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue();
6048  std::cout << " ** G.B.: " << paraInitiator->convertToExternalValue(globalBestDualBoundValue);
6049  if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6050  bbParaInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
6051  {
6052  std::cout << " ( Inf ) ";
6053  }
6054  else
6055  {
6056  std::cout << " ( " << bbParaInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
6057  }
6058  std::cout << "[ " << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver()
6059  <<" ] ** RR" << std::endl;
6060 #endif
6061 
6063  {
6064  /** the following should be before noticationId back to the source solver */
6066  {
6067  if( bbParaInitiator->getGlobalBestIncumbentSolution() &&
6068  bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue()
6069  < solverState->getGlobalBestPrimalBoundValue() )
6070  {
6071  bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, source);
6072  }
6073  }
6074  }
6075 
6076  // if( paraParams->getBoolParamValue(CheckGapInLC) )
6077  if( !givenGapIsReached )
6078  {
6079  if( bbParaInitiator->getAbsgap(solverState->getSolverLocalBestDualBoundValue() ) <
6080  bbParaInitiator->getAbsgapValue() ||
6081  bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) <
6082  bbParaInitiator->getGapValue()
6083  )
6084  {
6085  for( unsigned int i = 1; i <= paraRacingSolverPool->getNSolvers(); i++ )
6086  {
6088  {
6090  paraComm->send( NULL, 0, ParaBYTE, i, TagGivenGapIsReached )
6091  );
6093  }
6094  }
6095  // std::cout << "current dual = " << paraInitiator->convertToExternalValue(solverState->getSolverLocalBestDualBoundValue()) <<std::endl;
6096  // std::cout << "pool best dual = " << paraInitiator->convertToExternalValue(dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue()) << std::endl;
6097  // std::cout << "current gap = " << paraInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) <<std::endl;
6098  givenGapIsReached = true;
6099  }
6100  }
6101 
6102  double lcBestDualBoundValue = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue();
6103 
6105  paraComm->send( &lcBestDualBoundValue, 1, ParaDOUBLE, source, TagLCBestBoundValue)
6106  );
6107  unsigned int notificationId = solverState->getNotificaionId();
6109  paraComm->send( &notificationId, 1, ParaUNSIGNED, source, TagNotificationId)
6110  );
6111 
6112  if( lcts.globalBestDualBoundValue < lcBestDualBoundValue )
6113  {
6114  if( paraNodePool->getNumOfNodes() > 0 )
6115  {
6116  lcts.globalBestDualBoundValue = std::min( lcBestDualBoundValue, paraNodePool->getBestDualBoundValue() );
6117  }
6118  else
6119  {
6120  lcts.globalBestDualBoundValue = lcBestDualBoundValue;
6121  }
6122 
6123  lcts.externalGlobalBestDualBoundValue = bbParaInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
6124  }
6125  delete solverState;
6126  return 0;
6127 }
6128 
6129 int
6131  int source,
6132  int tag
6133  )
6134 {
6136  calcState->receive(paraComm, source, tag);
6137  writeTransferLogInRacing(source, calcState);
6138 
6139  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6140 
6141  if( logSolvingStatusFlag )
6142  {
6143  switch ( calcState->getTerminationState() )
6144  {
6146  {
6148  << " S." << source << " >(TERMINATED_IN_RACING_STAGE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6149  break;
6150  }
6153  {
6155  << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT or INTERRUPTED_BY_SOME_SOLVER_TERMINATED_IN_RACING_STAGE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6156  break;
6157  }
6159  {
6161  << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6162  break;
6163  }
6165  {
6167  << " S." << source << " >(INTERRUPTED_BY_MEMORY_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6168  break;
6169  }
6170  default:
6173  {
6175  << " S." << source << " >(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6176  break;
6177  }
6178  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
6179  }
6180  *osLogSolvingStatus << ", ct:" << calcState->getCompTime()
6181  << ", nr:" << calcState->getNRestarts()
6182  << ", n:" << calcState->getNSolved()
6183  << ", rt:" << calcState->getRootTime()
6184  << ", avt:" << calcState->getAverageNodeCompTimeExcpetRoot()
6185  << std::endl;
6186  }
6187 #ifdef _DEBUG_LB
6188  switch ( calcState->getTerminationState() )
6189  {
6191  {
6192  std::cout << paraTimer->getElapsedTime()
6193  << " S." << source << " >(TERMINATED_IN_RACING_STAGE)";
6194  break;
6195  }
6198  {
6199  std::cout << paraTimer->getElapsedTime()
6200  << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT or INTERRUPTED_BY_SOME_SOLVER_TERMINATED_IN_RACING_STAGE)";
6201  break;
6202  }
6203  default:
6204  THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
6205  }
6206  std::cout << std::endl;
6207 #endif
6208 
6209  if( calcState->getTerminationState() == CompTerminatedInRacingStage )
6210  {
6211  racingTermination = true; // even if interruptIsRequested,
6212  // solver should have been terminated before receiveing it
6214  {
6215  *osStatisticsRacingRampUp << "######### Solver Rank = " <<
6216  source << " is terminated in racing stage #########" << std::endl;
6217  }
6218 
6219  if( (dynamic_cast<UG::BbParaInitiator *>(paraInitiator)->getNSolutions() >=
6221  )
6222  {
6223  nSolvedRacingTermination = calcState->getNSolved();
6224  if( !EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, bbParaInitiator->getEpsilon() ) &&
6225  EPSEQ( minmalDualBoundNormalTermSolvers, DBL_MAX, bbParaInitiator->getEpsilon() ) )
6226  {
6227  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
6228  {
6230  }
6231  else
6232  {
6234  }
6235  }
6236  if( EPSLE(lcts.globalBestDualBoundValue, calcState->getDualBoundValue(), bbParaInitiator->getEpsilon()) &&
6237  minmalDualBoundNormalTermSolvers < calcState->getDualBoundValue() )
6238  {
6239  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
6240  {
6242  }
6243  else
6244  {
6246  }
6247  }
6248  if( bbParaInitiator->getGlobalBestIncumbentSolution() && (!givenGapIsReached) &&
6250  EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, paraInitiator->getEpsilon() ) ||
6251  EPSEQ( calcState->getDualBoundValue(), DBL_MAX, paraInitiator->getEpsilon() ) ||
6253  // distributed domain propagation could causes the following situation
6254  bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() < calcState->getDualBoundValue() ) ||
6255  ( calcState->getNSolved() == 0 ) ) )
6256  {
6258  if( paraNodePool->getNumOfNodes() > 0 )
6259  {
6261  }
6263  if( bbParaInitiator->getGlobalBestIncumbentSolution() )
6264  {
6266  }
6267  else
6268  {
6270  }
6271  }
6272  /*
6273  if( paraInitiator->getGlobalBestIncumbentSolution() &&
6274  paraParamSet->getBoolParamValue(UG::CommunicateTighterBoundsInRacing) &&
6275  // distributed domain propagation could causes the following situation
6276  paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue() < calcState->getDualBoundValue() &&
6277  EPSGE( paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue(), lcts.globalBestDualBoundValue, paraInitiator->getEpsilon() ) )
6278  {
6279  lcts.globalBestDualBoundValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
6280  lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
6281  minmalDualBoundNormalTermSolvers = lcts.globalBestDualBoundValue;
6282  }
6283  */
6284  assert( paraNodePool->getNumOfNodes() > 0 || !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6285  ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
6288  {
6289  dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->updateSolverStatus(source,
6290  calcState->getNSolved(), 0, minmalDualBoundNormalTermSolvers);
6292  {
6294  }
6295  }
6296  }
6297  }
6298 
6299  if( calcState->getTerminationState() == CompTerminatedByTimeLimit )
6300  {
6301  hardTimeLimitIsReached = true;
6302  // std::cout << "####### Rank " << paraComm->getRank() << " solver terminated with timelimit in solver side. #######" << std::endl;
6303  // std::cout << "####### Final statistics may be messed up!" << std::endl;
6304  }
6305  if( calcState->getTerminationState() == CompTerminatedByMemoryLimit )
6306  {
6307  memoryLimitIsReached = true;
6308  }
6309 
6310  delete calcState;
6311 
6312  // if( !warmStartNodeTransferring || ( warmStartNodeTransferring && paraNodePool->isEmpty() ) )
6313  // {
6315  termState->receive(paraComm, source, TagTermStateForInterruption);
6316 
6317  if( paraDetTimer )
6318  {
6319  if( paraDetTimer->getElapsedTime() < termState->getDeterministicTime() )
6320  {
6322  }
6324  paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
6325  );
6326  }
6327 
6329  {
6331  }
6332 
6334  {
6335  std::cout << termState->toString(paraInitiator) << std::endl;
6336  }
6337 
6338  delete termState;
6339  // }
6340  // else
6341  // {
6342  // if( paraDetTimer )
6343  // {
6344  // PARA_COMM_CALL(
6345  // paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
6346  // );
6347  // }
6348  // }
6349  // nTerminated++; We should not count this, We should always send Term from LC!
6351 
6352  if( racingTermination &&
6354  (!bbParaInitiator->getGlobalBestIncumbentSolution()) ) ||
6355  (dynamic_cast<UG::BbParaInitiator *>(paraInitiator)->getNSolutions() <
6357  )
6358  {
6359  racingTermination = false;
6360  }
6361 
6363  {
6364  // racingTermination = false;
6365  // nTerminated++;
6367  {
6368  newRacing();
6369  }
6370  }
6371  else
6372  {
6373 #ifndef _COMM_MPI_WORLD
6375  {
6377  {
6378  // nTerminated = 1;
6380  delete this;
6381 #ifdef _COMM_PTH
6382  _exit(0);
6383 #else
6384  exit(0);
6385 #endif
6386  }
6387  }
6388 #endif
6389  }
6390 
6391  return 0;
6392 }
6393 
6394 
6395 void
6397  ParaTask *paraNode,
6398  int nRacingSolvers,
6399  ParaRacingRampUpParamSet **racingRampUpParams
6400  )
6401 {
6403  {
6404  outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
6405  }
6406 
6407  /** creates racing solver pool */
6409  nRacingSolvers, // the number of racing solvers
6410  1, // paraSolver origin rank
6412 
6413  BbParaRacingSolverPool *bbParaRacingSolverPool = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool);
6414 
6415  /** activate racing solver with root node */
6416  /// NOTE that paraComm->getSize() - 1 is not always nRacingSolvers, that it other type of solvers can be working with
6418  paraNode->bcast(paraComm, 0)
6419  );
6420  bbParaRacingSolverPool->activate(dynamic_cast<BbParaNode *>(paraNode));
6421  lcts.nSent++;
6423  {
6424  int token[2];
6425  token[0] = 1;
6426  token[1] = -1;
6428  paraComm->send( token, 2, ParaINT, token[0], TagToken )
6429  );
6430  }
6431  if( logTasksTransferFlag )
6432  {
6433  for(int i = 1; i < paraComm->getSize(); i++ )
6434  {
6436  }
6437  }
6438 
6439  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6440 
6441  /** output start racing to log file, if it is necessary */
6442  if( logSolvingStatusFlag )
6443  {
6445  << " All Solvers starts racing "
6446  << bbParaInitiator->convertToExternalValue(
6447  dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() )
6448  << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
6449  << std::endl;
6450  }
6451 #ifdef _DEBUG_LB
6452  std::cout << paraTimer->getElapsedTime()
6453  << " All Solvers starts racing "
6454  << paraInitiator->convertToExternalValue(
6455  paraNode->getDualBoundValue() )
6456  << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
6457  << std::endl;
6458 #endif
6459 
6460  int source;
6461  int tag;
6462 
6463  for(;;)
6464  {
6465  /*******************************************
6466  * waiting for any message form anywhere *
6467  *******************************************/
6468  double inIdleTime = paraTimer->getElapsedTime();
6469  (void)paraComm->probe(&source, &tag);
6470  lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
6471  if( racingRampUpMessageHandler[tag] )
6472  {
6473  int status = (this->*racingRampUpMessageHandler[tag])(source, tag);
6474  if( status )
6475  {
6476  std::ostringstream s;
6477  s << "[ERROR RETURN form Racing Ramp-up Message Hander]:" << __FILE__ << "] func = "
6478  << __func__ << ", line = " << __LINE__ << " - "
6479  << "process tag = " << tag << std::endl;
6480  abort();
6481  }
6482  }
6483  else
6484  {
6485  THROW_LOGICAL_ERROR3( "No racing ramp-up message hander for ", tag, " is not registered" );
6486  }
6487 
6488 #ifdef UG_WITH_UGS
6489  if( commUgs ) checkAndReadIncumbent();
6490 #endif
6491 
6492  /** output tabular solving status */
6493  if( outputTabularSolvingStatusFlag && // (!racingTermination) &&
6502  {
6505  {
6507  {
6509  }
6510  else
6511  {
6513  }
6514  }
6515  else
6516  {
6518  }
6519  }
6520 
6522  break;
6523 
6524  if( restartingRacing )
6525  {
6527  {
6528  if( restartRacing() )
6529  {
6530  return; // solved
6531  }
6532  }
6533  continue;
6534  }
6535 
6536  switch ( runningPhase )
6537  {
6538  case RampUpPhase:
6539  {
6540  if( !paraRacingSolverPool )
6541  {
6542  warmStartNodeTransferring = false;
6543  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activate();
6544  run();
6545  return;
6546  }
6547  if( racingTermination )
6548  {
6549  if( paraNodePool->isEmpty()
6551  {
6552  warmStartNodeTransferring = false;
6553  delete paraRacingSolverPool;
6555  run();
6556  return;
6557  }
6558  if( paraNodePool->isEmpty()
6560  {
6561  if( source < static_cast<int>(paraSolverPool->getNSolvers()) + 1 && !paraSolverPool->isInterruptRequested(source) )
6562  {
6564 // std::cout << "sendInterrruptRequest1 13" << std::endl;
6565  }
6566  }
6567  break;
6568  }
6569 
6570  // if( paraParams->getRealParamValue(TimeLimit) > 0.0 &&
6571  // paraTimer->getElapsedTime() > paraParams->getRealParamValue(TimeLimit) )
6573  {
6574  warmStartNodeTransferring = false;
6575  // hardTimeLimitIsReached = true;
6576  // sendInterruptRequest();
6577  // runningPhase = TerminationPhase; waits until paraRacingSolverPool becomes empty
6578  break;
6579  }
6580 
6582  // paraTimer->getElapsedTime() > paraParams->getRealParamValue(FinalCheckpointGeneratingTime) )
6583  {
6584  warmStartNodeTransferring = false;
6585  // hardTimeLimitIsReached = true;
6586  std::cout << "** Program is still in racing stage. FinalCheckpointGeneratingTime is sppecifid, but the checkpoint files would not be generated." << std::endl;
6587  // sendInterruptRequest();
6588  // runningPhase = TerminationPhase; waits until paraRacingSolverPool becomes empty
6589  break;
6590  }
6591 
6592  if( bbParaRacingSolverPool->isWinnerDecided(
6593  ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
6595  {
6596  warmStartNodeTransferring = false;
6599  )
6600  {
6601  if( !restartingRacing )
6602  {
6603  for(int i = 1; i < paraComm->getSize(); i++)
6604  {
6607  );
6608  }
6609  // primalUpdated = false;
6610  restartingRacing = true;
6611  }
6612  }
6613  else
6614  {
6616  warmStartNodeTransferring = false;
6617  racingTermination = false;
6618  assert( racingWinner >0 );
6619  int numNodesLeft = bbParaRacingSolverPool->getNumNodesLeft(racingWinner);
6621  bbParaSolverPool->activateSolver(
6622  racingWinner, bbParaRacingSolverPool->extractNode(), numNodesLeft );
6623  bbParaRacingSolverPool->inactivateSolver(racingWinner);
6624 
6625  // assert(paraRacingSolverPool->getNumActiveSolvers() >= 0);
6628  );
6629 
6630  if( numNodesLeft >
6632  ||
6634  )
6635  {
6641  std::cout << "Warning: Ramp-Up Phase Process is switched to 1. CollectOnce, MergeNodesAtRestart and RacingStatBranching are switched to FALSE." << std::endl;
6642  std::cout << "You should check the following parameter values: StopRacingNumberOfNodesLeft, StopRacingNumberOfNodesLeftMultiplier, ProhibitCollectOnceMultiplier" << std::endl;
6643  }
6644 
6645  if( numNodesLeft > (signed)paraSolverPool->getNSolvers()
6646  ||
6648  )
6649  {
6651  {
6652  int nCollect = paraParams->getIntParamValue(NCollectOnce);
6653  if( nCollect == 0 )
6654  {
6655  nCollect = ( paraSolverPool->getNSolvers() * 5 );
6656  }
6659  );
6660  }
6662  {
6663  merging = true;
6664  if( nodesMerger ) delete nodesMerger;
6665  nodesMerger = new BbParaNodesMerger(dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance())->getVarIndexRange(),
6666  nBoundChangesOfBestNode,paraTimer,dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance()),paraParams);
6667  }
6668  }
6669  else
6670  {
6671  winnerSolverNodesCollected = true; // do not wait until all nodes are collected
6672  }
6673  racingWinnerParams = racingRampUpParams[racingWinner - 1];
6674  // racingWinnerParams->setWinnerRank(racingWinner);
6675  racingRampUpParams[racingWinner - 1] = 0;
6676  for(int i = 1; i < paraComm->getSize(); i++)
6677  {
6678  if( racingRampUpParams[i - 1] )
6679  {
6682  );
6683  }
6684  int noKeep = 0;
6686  paraComm->send( &noKeep, 1, ParaINT,i, TagKeepRacing)
6687  );
6688  }
6689  /** output winner to log file, if it is necessary */
6690  if( logSolvingStatusFlag )
6691  {
6693  << " S." << racingWinner << " is the racing winner!"
6694  << " Selected strategy " << racingWinnerParams->getStrategy()
6695  << "." << std::endl;
6696  }
6697  #ifdef _DEBUG_LB
6698  std::cout << paraTimer->getElapsedTime()
6699  << " S." << racingWinner << " is the racing winner!"
6700  << " Selected strategy " << racingWinnerParams->getStrategy()
6701  << "." << std::endl;
6702  #endif
6704  {
6706  "Racing ramp-up finished after " <<
6707  paraTimer->getElapsedTime() << " seconds." <<
6708  " Selected strategy " << racingWinnerParams->getStrategy() <<
6709  "." << std::endl;
6710  }
6711  // runningPhase = NormalRunningPhase;
6712  // Keep running as RampUpPhase, but in the run() switching into RampUpPhase in normal running mode
6713  // delete paraRacingSolverPool;
6714  run();
6715  return;
6716  }
6717  }
6718 
6721  && paraNodePool->getNumOfNodes() > 0
6722  )
6723  {
6724  newRacing();
6725  }
6726  break;
6727  }
6728  default:
6729  {
6730  THROW_LOGICAL_ERROR2( "Undefined running phase: ", static_cast<int>(runningPhase) );
6731  }
6732  }
6733  }
6734  return;
6735 }
6736 
6737 void
6739  )
6740 {
6741  for( int i = 1; i < paraComm->getSize(); i++ )
6742  {
6744  paraComm->send( NULL, 0, ParaBYTE, i, TagRetryRampUp )
6745  );
6746  }
6747 }
6748 
6749 void
6751  )
6752 {
6753  int exitSolverRequest = 0; // do nothing
6756  (!paraRacingSolverPool) &&
6759  (signed)nCollectedSolvers < paraParams->getIntParamValue(UG::FinalCheckpointNSolvers) )
6760  ) )
6761  {
6763  {
6765  "Start collecting the final check-point data after " <<
6766  paraTimer->getElapsedTime() << " seconds. " << std::endl;
6767  }
6768 
6769  if( paraSolverPool->getNumActiveSolvers() > 0 )
6770  {
6771  int bestSolverRank = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGoodSolverSolvingEssentialNode();
6772  if( bestSolverRank > 0 ) // bestSolverRank exits
6773  {
6774  BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(bestSolverRank));
6775  assert( !solvingNode->getAncestor() );
6776  solvingNode->collectsNodes();
6777  exitSolverRequest = 1; // collect all nodes
6779  paraComm->send( &exitSolverRequest, 1, ParaINT, bestSolverRank, TagInterruptRequest )
6780  );
6781  if( logSolvingStatusFlag )
6782  {
6784  << " S." << bestSolverRank << " TagInterruptRequest with collecting is sent"
6785  << std::endl;
6786  }
6787  }
6788  else
6789  {
6790  if( logSolvingStatusFlag )
6791  {
6793  << " S." << bestSolverRank << " TagInterruptRequest with collecting could not be sent (No best solvers)"
6794  << std::endl;
6795  }
6796  }
6797  }
6798  else
6799  {
6800  if( logSolvingStatusFlag )
6801  {
6803  << " S." << 0 << " TagInterruptRequest with collecting could not be sent (No active solvers)"
6804  << std::endl;
6805  }
6806  }
6807  }
6808  else
6809  {
6812  {
6813  for( int i = 1; i < paraComm->getSize(); i++ )
6814  {
6816  {
6818  paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
6819  );
6821  }
6822  else
6823  {
6825  paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
6826  );
6829  {
6830  int token[2];
6831  token[0] = i;
6832  token[1] = -2;
6834  paraComm->send( token, 2, ParaINT, token[0], TagToken )
6835  );
6836  }
6837  // nTerminated++;
6838  }
6839  }
6840 // std::cout << "TagTerminateRequest 4" << std::endl;
6841  }
6842  else
6843  {
6844  // normal TimeLimit
6845  if( interruptIsRequested ) return;
6846  if( paraSolverPool->getNumActiveSolvers() > 0 )
6847  {
6848  for( int i = 1; i < paraComm->getSize(); i++ )
6849  {
6851  {
6853  paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
6854  );
6856  }
6857  else
6858  {
6860  paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
6861  );
6864  {
6865  int token[2];
6866  token[0] = i;
6867  token[1] = -2;
6869  paraComm->send( token, 2, ParaINT, token[0], TagToken )
6870  );
6871  }
6872  }
6873  }
6874 // hardTimeLimitIsReached = true;
6875 // std::cout << "TagTerminateRequest 5" << std::endl;
6876  }
6878  {
6879  for( int i = 1; i < static_cast<int>(paraRacingSolverPool->getNSolvers()) + 1; i++ )
6880  {
6882  {
6884  paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
6885  );
6887  }
6888  else
6889  {
6891  paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
6892  );
6895  {
6896  int token[2];
6897  token[0] = i;
6898  token[1] = -2;
6900  paraComm->send( token, 2, ParaINT, token[0], TagToken )
6901  );
6902  }
6903  }
6904  }
6905 // hardTimeLimitIsReached = true;
6906 // std::cout << "TagTerminateRequest 6" << std::endl;
6907 // std::cout << "racingTermination = " << racingTermination << std::endl;
6908  }
6909  }
6910  }
6911 
6912  interruptIsRequested = true;
6913 }
6914 
6915 bool
6917  BbParaSolution *sol
6918  )
6919 {
6920 
6921  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6922 
6923  if( !bbParaInitiator->getGlobalBestIncumbentSolution() )
6924  return bbParaInitiator->tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(sol->clone(paraComm)),false);
6925  if( sol->getObjectiveFunctionValue()
6927  return bbParaInitiator->tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(sol->clone(paraComm)),false);
6928  else
6929  return false;
6930 }
6931 
6932 void
6934  int receivedRank
6935  )
6936 {
6937 
6938  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6939 
6940  double globalBestIncumbentValue = bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue();
6942  {
6943  for( int i = 1; i < paraComm->getSize(); i++ )
6944  {
6945  if( i != receivedRank )
6946  {
6948  paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
6949  );
6950  }
6951 
6952  }
6953  }
6954  lcts.nDeletedInLc += paraNodePool->removeBoundedNodes(globalBestIncumbentValue);
6955  /*
6956  if( paraParams->getIntParamValue(RampUpPhaseProcess) == 3 )
6957  {
6958  lcts.nDeletedInLc += dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->removeBoundedNodes(globalBestIncumbentValue);
6959  }
6960  */
6961 }
6962 
6963 void
6965  int receivedRank
6966  )
6967 {
6968 
6969  BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6970 
6971  double globalBestCutOffValue = bbParaInitiator->getGlobalBestIncumbentSolution()->getCutOffValue();
6973  {
6974  for( int i = 1; i < paraComm->getSize(); i++ )
6975  {
6976  if( i != receivedRank )
6977  {
6979  paraComm->send( &globalBestCutOffValue, 1, ParaDOUBLE, i, TagCutOffValue )
6980  );
6981  }
6982 
6983  }
6984  }
6985  lcts.nDeletedInLc += paraNodePool->removeBoundedNodes(globalBestCutOffValue);
6986 }
6987 
6988 void
6990  int rank
6991  )
6992 {
6993  nSolvedInInterruptedRacingSolvers = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver();
6994  nTasksLeftInInterruptedRacingSolvers = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver();
6995  if( paraRacingSolverPool->isSolverActive(rank) ) // if rank is the winner, it should be inactive
6996  {
6997  dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->inactivateSolver(rank);
6998  }
6999  if( paraSolverPool->isSolverActive(rank) )
7000  {
7001  /*
7002  * special timining problem
7003  *
7004  * 1113.58 S.4 I.SOL 0
7005  * 1113.58 S.3 is the racing winner! Selected strategy 2.
7006  * 1113.58 S.4 >(TERMINATED_IN_RACING_STAGE)
7007  *
7008  */
7009  if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isSolverInCollectingMode(rank) )
7010  {
7011  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(rank, -1, paraNodePool);
7012  // reschedule collecting mode
7014  {
7015  double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
7016  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
7017  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
7018  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
7019  }
7020  }
7021  else
7022  {
7023  dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(rank, -1, paraNodePool);
7024  }
7025  }
7026 
7027  if ( (!interruptIsRequested) &&
7028  (!restartingRacing )&&
7030  {
7031  /** if the computation is interrupted,
7032  * paraRacingSolverPool is needed to output statistics */
7034  {
7035  delete paraRacingSolverPool;
7037  }
7038  }
7039 
7040 }
7041 
7042 void
7044  int source,
7045  ParaCalculationState *calcState
7046  )
7047 {
7048  if( logSubtreeInfoFlag )
7049  {
7050  ParaTask *node = paraSolverPool->getCurrentTask(source);
7052  << ", "
7053  << source
7054  << ", "
7055  << node->toSimpleString()
7056  << ", "
7057  << calcState->toSimpleString()
7058  << std::endl;
7059  }
7060 }
7061 
7062 int
7064  )
7065 {
7066  // RESTART RACING MAY NOT WORK WITH DETERMINSTIC MODE: NOT DEBUGGED
7067 
7069  {
7070  restartingRacing = false;
7071  return 1;
7072  }
7073 
7074  ParaInstance *paraInstance = paraInitiator->getParaInstance();
7076 
7077  BbParaNode *rootNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->extractNode());
7078  rootNode->setDualBoundValue(-DBL_MAX);
7079  rootNode->setInitialDualBoundValue(-DBL_MAX);
7080  rootNode->setEstimatedValue(-DBL_MAX);
7081 
7082  /** recreate racing solver pool */
7083  delete paraRacingSolverPool;
7085  1, // paraSolver origin rank
7087 
7088  /** activate racing solver with root node */
7090  rootNode->bcast(paraComm, 0)
7091  );
7092  dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->activate(rootNode);
7093  lcts.nSent++;
7094 
7095  nRestartedRacing++;
7096 
7098  {
7099  *osStatisticsRacingRampUp << "##################################" << std::endl;
7100  *osStatisticsRacingRampUp << "### Racing restarted " << nRestartedRacing << " times" << std::endl;
7101  *osStatisticsRacingRampUp << "##################################" << std::endl;
7102  }
7103 
7105  {
7106  if( logSolvingStatusFlag )
7107  {
7109  << " Racing Ramp-up restarted." << std::endl;
7110  }
7111  }
7112 
7114  {
7115  *osTabularSolvingStatus << "Racing Ramp-up restarted." << std::endl;
7116  }
7117 
7118  primalUpdated = false;
7119  restartingRacing = false;
7120 
7121  lcts.globalBestDualBoundValue = -DBL_MAX;
7123  interruptIsRequested = false;
7124 
7125  return 0;
7126 }
7127 
7128 void
7130  )
7131 {
7132  racingTermination = false;
7133  // assert( nTerminated == paraRacingSolverPool->getNumInactiveSolvers() );
7134  BbParaNode *paraNode = paraNodePool->extractNode();
7135  if( paraNodePool->isEmpty() )
7136  {
7137  for( int i = 1; i < paraComm->getSize(); i++ )
7138  {
7139  int noKeep = 0;
7141  paraComm->send( &noKeep, 1, ParaINT,i, TagKeepRacing)
7142  );
7144  paraNode->send(paraComm, i)
7145  );
7146  }
7147  }
7148  else
7149  {
7150  for( int i = 1; i < paraComm->getSize(); i++ )
7151  {
7152  int keep = 1;
7154  paraComm->send( &keep, 1, ParaINT, i, TagKeepRacing)
7155  );
7156 // PARA_COMM_CALL(
7157 // paraComm->send( NULL, 0, ParaBYTE,i, TagTerminateSolvingToRestart)
7158 // );
7160  paraNode->send(paraComm, i)
7161  );
7162  }
7163  }
7164 
7165  /** activate racing solver with root node */
7166  BbParaRacingSolverPool *bbParaRacingSolverPool = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool);
7167  bbParaRacingSolverPool->reset();
7168  bbParaRacingSolverPool->activate(paraNode);
7169  lcts.nSent++;
7171  {
7172  int token[2];
7173  token[0] = 1;
7174  token[1] = -1;
7176  paraComm->send( token, 2, ParaINT, token[0], TagToken )
7177  );
7178  }
7179  if( logTasksTransferFlag )
7180  {
7181  for(int i = 1; i < paraComm->getSize(); i++ )
7182  {
7184  }
7185  }
7186 
7187  /** output start racing to log file, if it is necessary */
7188  if( logSolvingStatusFlag )
7189  {
7191  << " All Solvers starts racing "
7192  << dynamic_cast<BbParaInitiator *>(paraInitiator)->convertToExternalValue(
7193  dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() )
7194  << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
7195  << std::endl;
7196  }
7197 #ifdef _DEBUG_LB
7198  std::cout << paraTimer->getElapsedTime()
7199  << " All Solvers starts racing "
7200  << paraInitiator->convertToExternalValue(
7201  paraNode->getDualBoundValue() )
7202  << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
7203  << std::endl;
7204 #endif
7205  // nTerminated = 0;
7206  interruptIsRequested = false;
7207 }
7208 
7209 void
7211  )
7212 {
7213  /* Not implemented yet
7214  int bestBoundSearch = 1;
7215  for( int i = 1; i < paraComm->getSize(); i++ )
7216  {
7217  PARA_COMM_CALL(
7218  paraComm->send( &bestBoundSearch, 1, ParaINT, i, TagChangeSearchStrategy )
7219  );
7220  }
7221  */
7222 }
7223 
7224 void
7226  )
7227 {
7228  /* Not implemented yet
7229  int originalSearch = 0;
7230  for( int i = 1; i < paraComm->getSize(); i++ )
7231  {
7232  PARA_COMM_CALL(
7233  paraComm->send( &originalSearch, 1, ParaINT, i, TagChangeSearchStrategy )
7234  );
7235  }
7236  */
7237 }
7238 
7239 
7240 #ifdef UG_WITH_UGS
7241 int
7242 BbParaLoadCoordinator::checkAndReadIncumbent(
7243  )
7244 {
7245  int source = -1;
7246  int tag = TagAny;
7247 
7248  assert(commUgs);
7249 
7250  while( commUgs->iProbe(&source, &tag) )
7251  {
7252  if( source == 0 && tag == UGS::TagUpdateIncumbent )
7253  {
7254  if( paraInitiator->readUgsIncumbentSolution(commUgs, source) )
7255  {
7256  double globalBestIncumbentValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue();
7258  {
7259  if( paraInitiator->canGenerateSpecialCutOffValue() )
7260  {
7261  for( int i = 1; i < paraComm->getSize(); i++ )
7262  {
7263  sendCutOffValue(i);
7265  paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
7266  );
7267  }
7268  }
7269  else
7270  {
7271  for( int i = 1; i < paraComm->getSize(); i++ )
7272  {
7274  paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
7275  );
7276  }
7277  }
7278 
7279  }
7280  lcts.nDeletedInLc += paraNodePool->removeBoundedNodes(globalBestIncumbentValue);
7281 
7282  primalUpdated = true;
7284  if( logSolvingStatusFlag )
7285  {
7287  << " S." << source << " I.SOL "
7288  << paraInitiator->convertToExternalValue(
7289  paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue()
7290  ) << std::endl;
7291  }
7292 #ifdef _DEBUG_LB
7293  std::cout << paraTimer->getElapsedTime()
7294  << " S." << source << " I.SOL "
7295  << paraInitiator->convertToExternalValue(
7296  paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue()
7297  ) << std::endl;
7298 #endif
7299  /** output tabular solving status */
7301  {
7303  }
7304 #ifdef UG_WITH_ZLIB
7305  /* Do not have to remove ParaNodes from NodePool. It is checked and removed before sending them */
7306  /** save incumbent solution */
7307  char solutionFileNameTemp[MaxStrLen];
7308  char solutionFileName[MaxStrLen];
7310  {
7311  snprintf(solutionFileNameTemp, MaxStrLen, "%s%s_after_checkpointing_solution_t.gz",
7314  paraInitiator->writeCheckpointSolution(std::string(solutionFileNameTemp));
7315  snprintf(solutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
7318  if ( rename(solutionFileNameTemp, solutionFileName) )
7319  {
7320  std::cout << "after checkpointing solution file cannot be renamed: errno = " << strerror(errno) << std::endl;
7321  exit(1);
7322  }
7323  }
7324 #endif
7325  }
7326  }
7327  else if ( source == 0 && tag == TagTerminated )
7328  {
7329  return 1;
7330  }
7331  else
7332  {
7333  THROW_LOGICAL_ERROR5("Invalid Tag = ", tag, ", from source = ", source, " received.");
7334  }
7335  }
7336  return 0;
7337 
7338 }
7339 #endif
virtual void inactivateRacingSolverPool(int rank)
inactivate racing solver pool
static const int RestartInRampDownThresholdTime
std::ostream * osTabularSolvingStatus
ostream for solving status in tabular form to switch output location
virtual ParaSolution * clone(ParaComm *comm)=0
create clone of this object
virtual void generateRacingRampUpParameterSets(int nParamSets, ParaRacingRampUpParamSet **racingRampUpParamSets)=0
generate racing ramp-up parameter sets TODO: this function may be in inherited class ...
#define DEF_BB_PARA_COMM(para_comm, comm)
ramp-up phase
MessageHandlerFunctionPointer * messageHandler
message handlers table for primary phase
static const int MultiplierForBreakingTargetBound
double generateMergeNodesCandidatesTime
time when merge ParaNode candidates are generated
BbParaNodePool * paraNodePoolBufferToGenerateCPF
This is used for GenerateReducedCheckpointFiles.
void terminateAllSolvers()
terminate all solvers
static const int CleanUp
std::string toString()
stringfy ParaCalculationState
double averageDualBoundGain
average dual bound gain: could be negative value at restart
static const int NNodesTransferLogging
void regenerateMergeNodesCandidates(BbParaNode *node, ParaComm *paraComm, ParaInitiator *paraInitiator)
regenerate merge nodes candidates
virtual void send(ParaComm *comm, int destination)=0
send solution data
virtual BbParaDiffSubproblem * makeRootNodeDiffSubproblem()=0
make DiffSubproblem object for root node
static const int TagNotificationId
Definition: paraTagDef.h:55
bool memoryLimitIsReached
indicate if memory limit is reached or not in a solver, when base solver has memory management featur...
initial nodes were generated
virtual int restartRacing()
restart racing
static const int NCollectOnce
static const int CompTerminatedByInterruptRequest
Definition: paraDef.h:184
#define THROW_LOGICAL_ERROR4(msg1, msg2, msg3, msg4)
Definition: paraDef.h:103
ParaTimer * paraTimer
Timers for LoadCoordinator.
static const int TagReassignSelfSplitSubtreeRootNode
Definition: bbParaTagDef.h:75
std::ostream * osStatisticsFinalRun
ostream for statistics of the final run
std::deque< double > lastSeveralDualBoundGains
keep last several dual bound gains
virtual ParaSolverTerminationState * createParaSolverTerminationState()=0
create ParaSolverTerminationState object by default constructor
virtual void outputTabularSolvingStatus(char incumbent)
output solving status in tabular form
static const int TagNewSubtreeRootNode
Definition: bbParaTagDef.h:72
ParaSolverPool * paraSolverPool
Pools in LoadCorrdinator.
std::ostream * osStatisticsRacingRampUp
ostream for statistics for racing solvers to switch output location
static const int CompTerminatedByTimeLimit
Definition: paraDef.h:188
static const int TagIncumbentValue
Definition: paraTagDef.h:52
virtual std::string toString(ParaInitiator *initiator)=0
stringfy ParaSolverTerminationState object
virtual double getCutOffValue()
get cutoff value
virtual ParaTask * getCurrentTask(int rank)=0
get current solving ParaTask in the Solver specified by rank
virtual void interruptRequested(int rank)=0
set the Solver specified by rank is interrupt requested
static const int FinalCheckpointNSolvers
static const int LogSolvingStatusFilePath
Definition: paraParamSet.h:127
void collectsNodes()
set all nodes are collected TODO: this function has to be investigated
Definition: bbParaNode.h:698
static const int TagCutOffValue
Definition: bbParaTagDef.h:66
static const int GenerateReducedCheckpointFiles
static const double displayInfOverThisValue
if gap is over this value, Inf is displayed at gap TODO: this would move to inherited class ...
int nMergedNodes
the number of merged nodes with this node.
int breakingSolverId
all nodes collecting solver Id: -1: no collecting
int mergeNodes(BbParaNode *node, BbParaNodePool *paraNodePool)
make a merge node
virtual BbParaSolution * getGlobalBestIncumbentSolution()=0
get global best incumbent solution
BbParaMergeNodeInfo * getMergeNodeInfo()
get merge node information struct
Definition: bbParaNode.h:658
int getInterruptedMode()
getter of interrupted flag
virtual int processTagAllowToBeInCollectingMode(int source, int tag)
function to process TagAllowToBeInCollectingMode message
#define DEFAULT_NUM_EPSILON
Definition: paraDef.h:49
long long nSolvedInInterruptedRacingSolvers
number of tasks solved of the winner solver in the racing solvers
enum UG::BbParaMergeNodeInfo_::@0 status
status of this ParaMargeNodeInfo
Class for LoadCoordinator termination state which contains calculation state in a ParaLoadCoordinator...
virtual void writeTransferLogInRacing(int rank, ParaCalculationState *state)
write transfer log in racing
virtual int processTagLbBoundTightened(int source, int tag)
function to process TagLbBoundTightened message
size_t nCollectedSolvers
counter to check if all solvers are terminated or not
static const int FinalCheckpointGeneratingTime
Definition: paraParamSet.h:108
int racingWinner
racing winner information
static const int CompTerminatedByMemoryLimit
Definition: paraDef.h:189
static const int CollectOnce
BbParaNodePool * paraNodePool
Pools in LoadCorrdinator.
static const int HugeImbalanceThresholdTime
static const int ProhibitCollectOnceMultiplier
virtual double getElapsedTime()=0
get elapsed time
static const int CompInterruptedInMerging
Definition: paraDef.h:187
bool isBreakingFinised
indicate that breaking is finished or not if bootstrap ramp-up is not specified, this flag should be ...
virtual double getEpsilon()=0
get epsilon specified
double tNodesOutputLog
keep time for next logging of the number of transferred ParaNodes
int nAverageDualBoundGain
number of nodes whose dual bound gain are counted
virtual bool probe(int *source, int *tag)=0
No need to take action for fault tolerant, when the functions return. So, they do not rerun status va...
void setBoolParamValue(int param, bool value)
set bool parameter value
static const int TagTerminateRequest
Definition: paraTagDef.h:56
bool restarted
indicates that this run is restarted from checkpoint files
static const int InitialNodesGeneration
static const int NumberOfInitialNodes
unsigned long long nSentBackImmediately
Counters related to this ParaLoadCoordinator TODO: The numbers should be classified depending on solv...
static const int DeterministicTabularSolvingStatus
BbParaNodePool * paraNodeToKeepCheckpointFileNodes
The first n nodes may always keep in checkpoint file, that is, the n nodes are not processed in this ...
void setDiffSubproblem(BbParaDiffSubproblem *inDiffSubproblem)
setter of diffSubproblem */
Definition: bbParaNode.h:362
virtual void setInitialStatOnDiffSubproblem(int minDepth, int maxDepth, BbParaDiffSubproblem *diffSubproblem)
set initial status on DiffSubproblem
double getSolverLocalBestDualBoundValue()
gettter of best dual bound value
static const int CompTerminatedByAnotherTask
Definition: paraDef.h:183
double getRegenerateMergeNodesCandidatesTime()
getter of regenerateMergeNodesCandidatesTime
int(UG::ParaLoadCoordinator::* MessageHandlerFunctionPointer)(int, int)
virtual int processTagSelfSplitTermStateForInterruption(int source, int tag)
function to process TagSelfSplitTermStateForInterruption message
unsigned long long nDeletedInLc
number of ParaNodes deleted in LC
static const int EnhancedCheckpointStartTime
static const int RatioToApplyLightWeightRootProcess
virtual bool tryToSetIncumbentSolution(BbParaSolution *sol, bool checksol)=0
try to set incumbent solution
double getDeterministicTime()
getter of deterministic time
double regenerateMergeNodesCandidatesTime
time when merge ParaNode candidates are regenerated
virtual ParaRacingRampUpParamSet * createParaRacingRampUpParamSet()=0
create ParaRacingRampUpParamSet object
#define ABORT_LOGICAL_ERROR1(msg1)
Definition: paraDef.h:61
virtual bool isSolverActive(int rank)=0
check if the Solver specified by rank is active or not
std::size_t getNSolvers()
get number of Solvers in this Solver pool
static const int TagSubtreeRootNodeToBeRemoved
Definition: bbParaTagDef.h:74
virtual int processTagAnotherNodeRequest(int source, int tag)
function to process TagAnotherNodeRequest message
virtual int removeBoundedNodes(double incumbentValue)=0
remove bounded BbParaNodes by given incumbnet value
static const int TagAny
Definition: paraTagDef.h:44
virtual int bcast(ParaComm *comm, int rank, int method)=0
broadcast function to all solvers
ParaInitiator * paraInitiator
initiator
static const int BgapStopSolvingMode
Base class of Calculation state in a ParaSolver.
static const int TagHardTimeLimit
Definition: paraTagDef.h:61
class for solution
int nSolvedRacingTermination
number of tasks solved at the racing termination solver
class BbParaSolverPoolForMinimization (Solver Pool for Minimization Problems)
unsigned long long nFailedToSendBackAnotherNode
number of ParaNodes failed to send back after AnotherNode request
virtual void insert(BbParaNodePtr node)=0
insert BbParaNode to this pool
static const int NSolverNodesStartBreaking
std::ostream * osLogSolvingStatus
ostram for solving status to switch output location
virtual int bcast(ParaComm *comm, int root)=0
broadcast this object
double addingNodeToMergeStructTime
time when a ParaNode is added to merge struct
static const int NChangeIntoCollectingModeNSolvers
virtual double getAbsgap(double dualBoundValue)=0
get absolute gap of dual bound value
size_t getMaxUsageOfPool()
get maximum usage of this pool
double runningTime
this ParaLoadCoordinator running time
bool interruptedFromControlTerminal
interrupted from control terminal
bool isRootTask()
check if root task or not
Definition: paraTask.h:624
static const int NNodesToKeepInCheckpointFile
long long nTasksLeftInInterruptedRacingSolvers
number of of tasks remains of the the winner solver in the racing solvers
static const int TagLCBestBoundValue
Definition: bbParaTagDef.h:53
unsigned long long nNodesOutputLog
count for next logging of the number of transferred ParaNodes
bool isSameParetntTaskSubtaskIdAs(const TaskId &inTaskId)
check if this task&#39;s parent subtree id is the same as that of argument ParaTask&#39;s task id ...
Definition: paraTask.h:663
Base class of Calculation state in a ParaSolver.
static const int Checkpoint
Definition: paraParamSet.h:75
virtual void setNumberOfNodesSolved(long long n)=0
set number of nodes solved
virtual int receiveSubtreeRootNodeId(ParaComm *comm, int source, int tag)=0
receive this object node Id
double getNSelfSplitNodesLeft()
getter of the number of self-split nodes left
static const int LightWeightRootNodeProcess
bool outputTabularSolvingStatusFlag
output streams and flags which indicate the output is specified or not
static const int NChangeIntoCollectingMode
bool aSolverTerminatedWithOptimality
indicate if a solver terminated with proving optimality of the problem
virtual void sendInterruptRequest()
send interrupt request to all solvers
double externalGlobalBestDualBoundValue
global best dual bound value (external value)
int minDepthInWinnerSolverNodes
racing winner information
virtual const std::string toSimpleString()
stringfy ParaTask as simple string
Definition: paraTask.h:1015
static const int TagGivenGapIsReached
Definition: bbParaTagDef.h:56
static const int CompInterruptedInRacingStage
Definition: paraDef.h:186
virtual ParaSolverState * createParaSolverState()=0
create ParaSolverState object by default constructor
virtual int send(ParaComm *comm, int destination)=0
send this object
virtual int processTagTerminated(int source, int tag)
function to process TagTerminated message
virtual int receiveNewSubtreeRoot(ParaComm *comm, int source)=0
receive this object
int getTerminationState()
getter of the termination state for solving the subproblem
virtual void receive(ParaComm *comm, int source, int tag)=0
receive this object
int maxDepthInWinnerSolverNodes
maximum depth of open nodes in the winner solver tree
bool hugeImbalance
indicate that a huge imbalance in solvers is detected
int nBoundChangesOfBestNode
the number of fixed variables of the best node The followings are used temporary to generate merge no...
virtual bool isSolverActive(int rank)=0
check if the specified Solver is active or not
bool * racingSolversExist
indicate if racing solver exits or not, true: exists
class BbParaRacingSolverPool (Racing Solver Pool)
virtual std::size_t getNumActiveSolvers()=0
get number of active Solvers
BbParaNodePool * paraNodePoolBufferToRestart
ParaNode pool for buffering ParaNodes in huge imbalance situation.
unsigned long long nNodesInNodePool
number of nodes in ParaNodePool
virtual int reInit(int nRestartedRacing)=0
reinitizalie initiator TODO: this function should be in inherited class
double getAddingNodeToMergeStructTime()
getter of addingNodeToMergeStructTime
virtual void deleteCurrentSubtreeRootNode(int rank)
delete current self-split subtree root node from the active solver with the specified rank ...
virtual double getBestDualBoundValue()=0
get best dual bound value of BbParaNode object in this pool
ParaRacingSolverPool * paraRacingSolverPool
racing solver pool
#define REALABS(x)
Definition: paraDef.h:165
ParaDeterministicTimer * paraDetTimer
deterministic timer used in case of deterministic mode this timer need to be created in case of deter...
double getDualBoundValue()
getter of the final dual bound value
static const int TagLbBoundTightenedBound
Definition: bbParaTagDef.h:63
double starvingTime
start time of starving active solvers
double globalBestDualBoundValue
global best dual bound value (internal value)
Class for initiator.
Definition: paraInitiator.h:62
TaskId class.
Definition: paraTask.h:222
class for deterministic timer
bool logSubtreeInfoFlag
indicate if subtree info. is logged or not
virtual std::size_t getNumActiveSolvers()=0
get number of active Solvers
static const int TransferLocalCuts
requested subproblem was solved
static const int ParaUNSIGNED
Definition: paraComm.h:72
Base class for initial statistics collecting class.
virtual void resetCountersInSolver(int rank, long long numOfNodesSolved, int numOfSelfSplitNodesLeft, BbParaNodePool *paraNodePool)
reset counters in the Solver specified by rank
class BbParaSolverPool (Solver Pool base class)
bool warmStartNodeTransferring
indicate that the first node transferring at warm start (restart)
void setGlobalSubtaskId(int lcId, int subtaskId)
setter of global subtask id
Definition: paraTask.h:761
double getAverageDualBoundGain()
getter of average dual bound gain received
double previousCheckpointTime
For checkpoint.
virtual const char * getProbName()=0
get problem name
virtual void addTotalNodesSolved(unsigned long long num)
add number of nodes solved in all Solvers
static const int TimeToIncreaseCMS
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
virtual void receive(ParaComm *comm, int source, int tag)=0
send this object to destination
bool isCheckpointState
indicate if this state is at checkpoint or not
static const int Deterministic
Definition: paraParamSet.h:76
virtual int getRank()=0
get rank of this process or this thread depending on run-time environment
virtual void setDualBound(double bound)=0
set final dual bound
int(UG::BbParaLoadCoordinator::* BbMessageHandlerFunctionPointer)(int, int)
static const int StopRacingNumberOfNodesLeftMultiplier
virtual ~BbParaLoadCoordinator()
destructor
static const int TagCollectAllNodes
Definition: bbParaTagDef.h:51
int getNSent()
getter of the number of nodes transferred from the subproblem solving
static const int TagSelfSlpitNodeCalcuationState
Definition: bbParaTagDef.h:76
Class for initiator.
BbParaNodePool * paraNodePoolToRestart
ParaNode pool to restart in ramp-down phase.
static const int TagRestart
Definition: bbParaTagDef.h:61
virtual int processRacingRampUpTagSolverState(int source, int tag)
message handlers specialized for racing ramp-up
unsigned long long nFailedToSendBack
number of ParaNodes failed to send back
double getRootTime()
getter of root node computing time
virtual void receive(ParaComm *comm, int source, int tag)=0
receive this object
int getWinner()
get winner Solver rank
virtual double convertToExternalValue(double internalValue)=0
convert objective function value to external value TODO: this function may be in inherited class ...
TaskId getTaskId()
getter of task id
Definition: paraTask.h:794
static const int ParaDOUBLE
Definition: paraComm.h:76
BbParaNode * next
this pointer is used in case of self-split ramp-up in LC this field is not transferred ...
Definition: bbParaNode.h:83
int nNormalSelection
number of normal node selection to a random node selection
virtual double getElapsedTime()=0
getter of the deterministic time
int getNNodesLeft()
getter of number of nodes left by the notification Solver
static const int EnhancedFinalCheckpoint
int getNSolvedWithNoPreprocesses()
getter of the number of solved nodes in the case that a node is solved without presolving. This is an experimental routine only used for SCIP parallelization
virtual int processTagReassignSelfSplitSubtreeRootNode(int source, int tag)
function to process TagReassignSelfSplitSubtreeRootNode message
static const int NStopBreaking
void generateMergeNodesCandidates(ParaComm *paraComm, ParaInitiator *paraInitiator)
generate merge nodes candidates
virtual bool sendParaTasksToIdleSolvers()
send ParaNodes to idle solvers
static const int NMergingNodesAtRestart
virtual void updateDualBoundsForSavingNodes()=0
update dual bound values for saving BbParaNodes to checkpoint file
static const int CheckEffectOfRootNodePreprocesses
BbParaLoadCoordinatorTerminationState lcts
LoadCoordinatorTerminationState: counters and times.
static const int TagTaskReceived
Definition: paraTagDef.h:48
virtual void reset()
reset racing solver pool
virtual void activate(BbParaNode *node)
activate racing ramp-up Solver pool with root BbParaNode object
virtual void changeSearchStrategyOfAllSolversToOriginalSearch()
change search strategy of all solvers to original search strategy
virtual void receive(ParaComm *comm, int source)=0
receive solution data
double getRealParamValue(int param)
for real parameters
unsigned long long nMaxUsageOfNodePool
maximum number of ParaNodes in ParaNodePool
static const int TagSolverState
Definition: paraTagDef.h:53
virtual void outputFinalSolverStatistics(std::ostream *os, double time)=0
output final solver statistics
unsigned long long nSent
number of ParaTasks sent from LC
static const int RandomNodeSelectionRatio
BbParaDiffSubproblem * origDiffSubproblem
original DiffSubproblem */
bool interruptIsRequested
indicate that all solver interrupt message is requested or not
virtual void sendIncumbentValue(int receivedRank)
send incumbent value
static const int NEagerToSolveAtRestart
bool allCompInfeasibleAfterSolution
indicate that all computations are infeasible after a feasible solution
std::ofstream ofsTabularSolvingStatus
ofstream for solving status in tabular form
static const int TagTermStateForInterruption
Definition: bbParaTagDef.h:77
static const int TagSolution
Definition: paraTagDef.h:51
virtual std::size_t getNumInactiveSolvers()=0
get number of inactive Solvers
#define EPSEQ(x, y, eps)
Definition: paraDef.h:166
ParaParamSet * paraParams
UG parameter set.
virtual int processTagTermStateForInterruption(int source, int tag)
function to process TagTermStateForInterruption message
double getInitialDualBoundValue()
getter of initial dual bound value
Definition: bbParaNode.h:314
virtual size_t getNumOfNodes()=0
get number of BbParaNodes in this pool
virtual int bcast(ParaComm *comm, int root)=0
broadcast this object
problem was solved
bool restartingRacing
indicate that racing ramp-up is restarting
std::set< int > * selfSplitFinisedSolvers
indicate selfSplit finished solvers
static const int TNodesTransferLogging
virtual double getAbsgapValue()=0
get absgap value specified
virtual int processTagToken(int source, int tag)
function to process TagToken message
virtual void writeSubtreeInfo(int source, ParaCalculationState *calcState)
write subtree info.
static const int NoUpperBoundTransferInRacing
hard time limit is reached
bool merging
for merging nodes
virtual unsigned long long getTotalNodesSolved()
get number of nodes solved in all Solvers: updated at termination of subtree computation ...
virtual void terminateRequested(int rank)=0
set the Solver specified by rank is terminate requested
static const int TagToken
Definition: paraTagDef.h:63
int createNewGlobalSubtreeId()
create a new global subtree Id
double getAverageNodeCompTimeExcpetRoot()
getter of average computing time of a node except root node
virtual int processTagTask(int source, int tag)
Message handlers.
unsigned int getNotificaionId()
getter of notification id
static const int OmitInfeasibleTerminationInRacing
void addNodeToMergeNodeStructs(BbParaNode *node)
add a node to nodes merger
virtual void setSwichOutTime(double time)
set time of switching out collecting mode
int firstCollectingModeState
status of first collecting mode -1 : have not been in collecting mode 0 : once in collecting mode 1 :...
bool givenGapIsReached
shows if specified gap is reached or not
virtual bool isSolverInCollectingMode(int rank)
get collecting mode of the Solver specified by rank
const char * getPrefixWarm()
get prefix of warm start (restart) files
static const int TagGlobalBestDualBoundValueAtWarmStart
Definition: bbParaTagDef.h:47
static const int TagAnotherNodeRequest
Definition: bbParaTagDef.h:48
static const int ABgapForSwitchingToBestSolver
static const int DualBoundGainBranchRatio
virtual void sendCutOffValue(int receivedRank)
send cut off value
given gap is reached for the computation
static const int LightWeightNodePenartyInCollecting
class ParaSolverTerminationState (Solver termination state in a ParaSolver)
virtual int processTagHardTimeLimit(int source, int tag)
function to process TagHardTimeLimit message
class BbParaNodePoolForMinimization
virtual int processTagSolution(int source, int tag)
function to process TagSolution message
#define EPSLT(x, y, eps)
Definition: paraDef.h:167
virtual void outputTabularSolvingStatusHeader()
output tabular solving status header
virtual void setFinalSolverStatus(FinalSolverState status)=0
set final solver status
virtual int receive(void *bufer, int count, const int datatypeId, int source, const int tag)=0
receive function for standard ParaData types
Class for the difference between instance and subproblem.
static const int TagUbBoundTightenedIndex
Definition: bbParaTagDef.h:64
#define ABORT_LOGICAL_ERROR3(msg1, msg2, msg3)
Definition: paraDef.h:95
static const int MergeNodesAtRestart
static const int TagRetryRampUp
Definition: bbParaTagDef.h:46
virtual void run()
run function to start main process
static const int TagBreaking
Definition: bbParaTagDef.h:55
virtual ParaSolution * createParaSolution()=0
create ParaSolution object by default constructor
ParaComm * paraComm
communicator used
memory limit is reached in a solver
static const int TransferConflictCuts
virtual BbParaNodePtr extractNodeRandomly()=0
extract a BbParaNode object randomly from this pool
void setMergingStatus(int status)
set merging status
Definition: bbParaNode.h:667
bool logTasksTransferFlag
indicate if task transfer info. is logged or not
class ParaParamSet
Definition: paraParamSet.h:850
BbParaDiffSubproblem * mergedDiffSubproblem
merged DiffSubproblem, in case this node is merged and this is the head */
int getNRestarts()
getter of the number of restart occurred in solving a subproblem
const std::string toString()
stringfy BbParaNode
Definition: bbParaNode.h:600
virtual double getGapValue()=0
get gap value specified
std::ostream * osLogTasksTransfer
ostream for task transfer info. to switch output location
int getDepth()
getter of depth
Definition: bbParaNode.h:283
static const int TagAllowToBeInCollectingMode
Definition: bbParaTagDef.h:57
class for instance data
Definition: paraInstance.h:50
void setMergeNodeInfo(BbParaMergeNodeInfo *mNode)
set merge node information to this BbParaNode object
Definition: bbParaNode.h:646
#define THROW_LOGICAL_ERROR5(msg1, msg2, msg3, msg4, msg5)
Definition: paraDef.h:112
virtual int processTagSelfSlpitNodeCalcuationState(int source, int tag)
function to process TagSelfSlpitNodeCalcuationState message
const std::string toSimpleString()
stringfy BbParaNode as simple string
Definition: bbParaNode.h:619
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
virtual bool isEmpty()=0
check if this pool is empty or not
static const int InstanceTransferMethod
static const int CompTerminatedNormally
Definition: paraDef.h:182
unsigned long long nNodesLeftInAllSolvers
number of nodes left in all Solvers
computing was interrupted
static const int DistributeBestPrimalSolution
void setEstimatedValue(double inEstimatedValue)
setter of estimated value
Definition: paraTask.h:843
Class for LoadCoordinator.
virtual ParaTask * createParaTask()=0
create ParaTask object by default constructor
const char * getStringParamValue(int param)
for char parameters
bool isRacingStage()
getter of isRacingStage
virtual int getNumNodesLeft(int rank)
get number of nodes left in the Solver specified by rank
class ParaTaskGenealogicalLocalPtr
Definition: paraTask.h:414
static const int TagTerminateSolvingToRestart
Definition: bbParaTagDef.h:70
static const int RestartInRampDownActiveSolverRatio
static const int HugeImbalanceActiveSolverRatio
static const int ParaBYTE
Definition: paraComm.h:79
static const int TagTerminated
Definition: paraTagDef.h:58
bool winnerSolverNodesCollected
indicate that all winner solver nodes has been collected
virtual ParaTask * getCurrentTask(int rank)
get current solving BbParaNode in the Solver specified by rank */
class BbParaNode
Definition: bbParaNode.h:61
static const int CheckpointInterval
Definition: paraParamSet.h:107
virtual int processTagSolverState(int source, int tag)
function to process TagSolverState message
bool computationIsInterrupted
indicate that current computation is interrupted or not
void setDualBoundValue(double inDualBoundValue)
setter of dual bound value
Definition: bbParaNode.h:323
static const int OmitTerminationNSolutionsInRacing
static const int TagSelfSplitTermStateForInterruption
Definition: bbParaTagDef.h:78
static const int BgapCollectingMode
termination phase, includes interrupting phase
virtual bool isTerminateRequested(int rank)=0
check if the Solver specified by rank is terminate requested or not
virtual void changeSearchStrategyOfAllSolversToBestBoundSearch()
change search strategy of all solvers to best bound bound search strategy
static const int Quiet
Definition: paraParamSet.h:71
bool hardTimeLimitIsReached
indicate that hard time limit is reached or not
virtual unsigned int getNumOfGoodNodes(double globalBestBound)=0
get number of good (heavy) BbParaNodes in this pool
static const int TagNoNodes
Definition: bbParaTagDef.h:49
#define EPSGT(x, y, eps)
Definition: paraDef.h:169
virtual bool isWinnerDecided(bool feasibleSol)
check racing termination criteria
virtual void sendRetryRampUpToAllSolvers()
notify retry ramp-up to all solvers
bool racingTermination
racing termination information
static const int StopRacingNumberOfNodesLeft
double getDualBoundValue()
getter of dual bound value
Definition: bbParaNode.h:303
virtual double getGlobalBestDualBoundValue()
get global best dual bound value
BbParaDiffSubproblem * getDiffSubproblem()
getter of diffSubproblem
Definition: bbParaNode.h:353
virtual bool isInterruptRequested(int rank)=0
check if the Solver specified by rank is interrupt requested or not
unsigned long long mMaxCollectingNodes
maximum multiplier for the number of collecting nodes
normal running phase (primary phase)
void setRealParamValue(int param, double value)
set real parameter value
unsigned long long nWarmStart
number of warm starts (restarts)
class for instance data
static const int OutputTabularSolvingStatus
unsigned long long nReceived
number of ParaTasks received from Solvers
RunningPhase runningPhase
status of LoadCoordinator
BbParaLoadCoordinator(int inNhanders, ParaComm *inComm, ParaParamSet *inParaParamSet, ParaInitiator *paraInitiator, bool *racingSolversExist, ParaTimer *paraTimer, ParaDeterministicTimer *detTimer)
constructor
static const int MultiplierForBgapCollectingMode
static const int RampUpPhaseProcess
virtual int processTagUbBoundTightened(int source, int tag)
function to process TagUbBoundTightened message
BbParaNodePool * unprocessedParaNodes
The last n nodes may always keep in checkpoint file, that is, the n nodes are not processed in this r...
virtual int processTagSubtreeRootNodeToBeRemoved(int source, int tag)
function to process TagSubtreeRootNodeToBeRemoved message
static const int TabularSolvingStatusInterval
static const int TagInterruptRequest
Definition: paraTagDef.h:57
static const int RestartRacing
virtual int receive(ParaComm *comm, int source)=0
receive this object
virtual void writeTransferLog(int rank, ParaCalculationState *state)
write transfer log
int getNSolved()
geeter of the number of tasks solved in a subproblem
double getDeterministicTime()
getter of deterministic time
double minmalDualBoundNormalTermSolvers
minimal dual bound for normal termination solvers
virtual void activateSolver(int rank, BbParaNode *node, int nGoodNodesInNodePool, double averageDualBoundGain)
activate the Solver specified by rank with specified node which has been sent
void setAncestor(ParaTaskGenealogicalPtr *inAncestor)
setter of ancestor
Definition: bbParaNode.h:382
MessageHandlerFunctionPointer * racingRampUpMessageHandler
message handlers table for racing stage
void addDescendant(ParaTaskGenealogicalPtr *inDescendant)
add a descendant
Definition: paraTask.h:939
virtual std::string toSimpleString()=0
stringfy ParaCalculationState (simple string version)
static const int CommunicateTighterBoundsInRacing
double getMergeNodeTime()
getter of mergeNodeTime
virtual ParaCalculationState * createParaCalculationState()=0
transfer object factory
static const int WaitTerminationOfThreads
virtual BbParaNode * extractNode()
extract racing root BbParaNode
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)=0
send function for standard ParaData types
virtual void sendRampUpToAllSolvers()
notify ramp-up to all solvers
static const int TagLbBoundTightenedIndex
Definition: bbParaTagDef.h:62
class BbParaNodePoolForCleanUp
ParaRacingRampUpParamSet * racingWinnerParams
racing winner parameter set
virtual double getObjectiveFunctionValue()=0
get objective function value
static const int TagSubtreeRootNodeStartComputation
Definition: bbParaTagDef.h:73
static const int TagSelfSplitFinished
Definition: bbParaTagDef.h:71
virtual int processTagSelfSplitFinished(int source, int tag)
function to process TagSelfSplitFinished message
#define EPSLE(x, y, eps)
Definition: paraDef.h:168
virtual BbParaNodePtr extractNode()=0
extract a BbParaNode object from this pool
static const int TimeLimit
Definition: paraParamSet.h:106
double getCompTime()
getter of computing time of a subproblem
virtual int getSize()=0
get number of UG processes or UG threads depending on run-time environment
static const int MaxStrLen
Definition: paraDef.h:179
virtual std::size_t getNumInactiveSolvers()=0
get number of inactive Solvers
virtual int send(ParaComm *comm, int destination)=0
send ParaRacingRampUpParamSet
static const int RacingStatBranching
static const int TagUbBoundTightenedBound
Definition: bbParaTagDef.h:65
virtual void inactivateSolver(int rank)
inactivate the Solver specified by rank
bool logSolvingStatusFlag
output streams and flags which indicate the output is specified or not
virtual double getSwichOutTime()
the following functions are to omit rebooting collecting mode process
static const int LogSubtreeInfo
virtual int processRacingRampUpTagCompletionOfCalculation(int source, int tag)
function to process TagCompletionOfCalculation message in racing ramp-up stage
unsigned long long nInitialP
initial p value, which indicates the number of good ParaNodes try to keep in LC
virtual ParaInstance * getParaInstance()=0
get instance object
static const int TagKeepRacing
Definition: bbParaTagDef.h:69
std::ofstream ofsLogSubtreeInfo
ofstream for subtree info.
virtual int getStrategy()=0
get strategy
#define MINEPSILON
Definition: paraDef.h:50
long long getNNodesSolved()
getter of number of nodes solved by the notification Solver
Merge node information struct.
static const int ParaINT
Definition: paraComm.h:66
virtual void writeSolution(const std::string &message)=0
write solution
bool isCollectingModeRestarted
this flag indicate if a collecting mode is restarted or not
virtual void newRacing()
start a new racing
double statEmptyNodePoolTime
To measure how long does node pool stay in empty situation.
static const int StatisticsToStdout
Definition: paraParamSet.h:77
virtual int processTagNewSubtreeRootNode(int source, int tag)
function to process TagNewSubtreeRootNode message
double averageLastSeveralDualBoundGains
average dual bound gains of last several ones
double getGlobalBestPrimalBoundValue()
get global best primal bound value that the notification Solver has
virtual bool isRacingStage()
check if current stage is in racing or not
int getIntParamValue(int param)
for int parameters
bool isHeaderPrinted
indicate if heeader is printed or not
static const int CompTerminatedInRacingStage
Definition: paraDef.h:185
class ParaTimer
Definition: paraTimer.h:48
BbParaMergeNodeInfo * mergedTo
pointer to merge node info to which this node is merged */
int nHandlers
number of valid handlers
bool terminationIssued
indicate termination request is issued
unsigned long long nSentBackImmediatelyAnotherNode
number of ParaNodes sent back immediately after AnotherNode request from LC
static const int MultiplierForCollectingMode
virtual bool updateSolution(BbParaSolution *)
update incumbent solution
std::size_t getNSolvers()
get number of Solvers in this Solver pool
size_t nTerminated
counter to check if all solvers are terminated or not
virtual void update(double value)=0
update function of the deterministic time. the deterministic time is a kind of counter ...
virtual bool canGenerateSpecialCutOffValue()
check if solver can generate special cut off value or not
class ParaRacingRampUpParamSet (parameter set for racing ramp-up)
static const int NTransferLimitForBreaking
bool areNodesCollected()
check if nodes are collected or not
Definition: bbParaNode.h:688
double getGenerateMergeNodesCandidatesTime()
getter of generateMergeNodesCandidatesTime
static const int NBoundChangesOfMergeNode
static const int TagCompletionOfCalculation
Definition: paraTagDef.h:54
static const int DualBoundGainTest
void deleteMergeNodeInfo(BbParaMergeNodeInfo *mNode)
delete merge node info
void setInitialDualBoundValue(double inTrueDualBoundValue)
setter of initial dual bound value
Definition: bbParaNode.h:333
virtual double getGap(double dualBoundValue)=0
get relative gap of dual bound value
class BbParaSolverState (ParaSolver state object for notification message)
class BbParaSolverTerminationState (Solver termination state in a ParaSolver)
static const int EnhancedCheckpointInterval
BbParaNodesMerger * nodesMerger
pointer to nodes merger object, which merges nodes
virtual BbParaNode * getSelfSplitSubtreeRootNodes(int rank)
get self-split subtree root node from the active solver with the specified rank
char lastCheckpointTimeStr[26]
lastCheckpointTimeStr[0] == &#39; &#39; means no checkpoint
void setIntParamValue(int param, int value)
set int parameter value
Base class of communicator object.
Definition: paraComm.h:101
bool primalUpdated
indicate that primal solution was updated or not
virtual int processTagCompletionOfCalculation(int source, int tag)
function to process TagCompletionOfCalculation message
virtual bool isObjIntegral()
check if objective function value is always integral or not
virtual void switchOutCollectingMode()
switch out collecting mode
static const int NIdleSolversToTerminate
double previousTabularOutputTime
to keep tabular solving status output time
std::ostream * osLogSubtreeInfo
ostram for subtree info. to switch output location
static const int TagWinner
Definition: paraTagDef.h:60
#define THROW_LOGICAL_ERROR3(msg1, msg2, msg3)
Definition: paraDef.h:86
bool initialNodesGenerated
indicates that initial nodes have been generated
static const int TagAckCompletion
Definition: paraTagDef.h:62
virtual void switchInCollectingMode(BbParaNodePool *paraNodePool)=0
switch in collecting mode
class ParaTask
Definition: paraTask.h:541
ParaTaskGenealogicalPtr * getAncestor()
getter of ancestor
Definition: bbParaNode.h:373
bool getBoolParamValue(int param)
for bool parameters
double hugeImbalanceTime
start time of huge imbalance situation
virtual int processTagSubtreeRootNodeStartComputation(int source, int tag)
function to process TagSubtreeRootNodeStartComputation message
int nRestartedRacing
number of racing stages restarted
static const int CheckpointFilePath
Definition: paraParamSet.h:130