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-2024 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 bbParaLoadCoordinator.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"
56#include "bbParaNode.h"
57#include "bbParaNodesMerger.h"
58
59using namespace UG;
60
61BbParaLoadCoordinator::BbParaLoadCoordinator(
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
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
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
322 {
324 }
325 else
326 {
328 }
329
332 {
333 isBreakingFinised = true;
334 }
335 else
336 {
337 isBreakingFinised = false;
338 }
339
341 {
343 }
344
346 {
347 nNormalSelection = -1;
348 }
349
352 {
354 }
355
357 {
358 if( !( paraInitiator->getPrefixWarm() &&
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
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 }
451 }
452 else
453 {
456 {
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 {
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
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 }
590 }
591 else
592 {
594 {
596 {
598 }
599 else
600 {
602 }
604 {
606 }
607 if( !givenGapIsReached )
608 {
610 {
612 }
613 }
614 if( paraNodePool->getNumOfNodes() > 0 )
615 {
617 }
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 }
643 }
644 else
645 {
647 {
648 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
649 {
652 }
653 else
654 {
656 }
657 }
658 if( paraNodePool->getNumOfNodes() > 0 )
659 {
661 }
664 }
665 }
666 else
667 {
668 if( paraNodePool->getNumOfNodes() > 0 )
669 {
671 }
673 {
675 {
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 }
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
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 {
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
792void
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 {
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
830int
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;
990 if( runningPhase != RampUpPhase && !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isInCollectingMode()) &&
993 { // inactive solver exists but cannot send a ParaNode to it
994 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
996 }
997 }
998
1000 paraComm->send( NULL, 0, ParaBYTE, source, TagTaskReceived);
1001 );
1002
1003 return 0;
1004}
1005
1006int
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
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;
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
1097int
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 */
1129 {
1131 << " S." << source << " | "
1132 << bbParaInitiator->convertToExternalValue(
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(
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();
1213 {
1215 << " S." << source << " G " << paraSolverPool->getCurrentTask(source)->toSimpleString()
1216 << ", a:" << averageDualBoundGain
1218 << ", g:" << solverDualBoundGain;
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(),
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(
1286 }
1287 else
1288 {
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
1310 {
1312 << " S." << source << " | "
1313 << bbParaInitiator->convertToExternalValue(
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 <<" ) ] **";
1341 {
1342 *osLogSolvingStatus << " C";
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;
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(
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";
1435 {
1436 std::cout << " C";
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 {
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
1518 {
1519 for(unsigned int i = 1; i <= paraSolverPool->getNSolvers(); i++ )
1520 {
1521 int nCollect = -1;
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;
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);
1553 {
1555 << " Collecting mode is restarted with " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers()
1556 << std::endl;
1557 }
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
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);
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);
1626 {
1628 << " Collecting mode is restarted with " << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNLimitCollectingModeSolvers()
1629 << std::endl;
1630 }
1631 }
1633 {
1635 statEmptyNodePoolTime = DBL_MAX;
1636 }
1637 }
1638 }
1639
1640 if( !( solverState->isRacingStage() ) &&
1643 globalBestDualBoundValueLocal
1645 &&
1646 (signed)paraNodePool->getNumOfNodes(
1649 ) )
1650 {
1651 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
1653 }
1654
1655 if( !isBreakingFinised )
1656 {
1657 if( (!solverState->isRacingStage()) && runningPhase == NormalRunningPhase )
1658 {
1661 {
1662 isBreakingFinised = true;
1663 }
1664 else
1665 {
1666 if( breakingSolverId == -1 )
1667 {
1670 {
1671 breakingSolverId = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getBestSolver();
1672 assert( breakingSolverId != -1 );
1673 double targetBound = ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue()*
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() ) &&
1690 solverState->getNNodesLeft() > ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()*0.5 ) )
1691 {
1692 breakingSolverId = source;
1693 double targetBound = ( solverState->getSolverLocalBestDualBoundValue()*
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 {
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
1729int
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
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 {
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 {
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 {
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() -
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() -
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 {
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 {
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);
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() -
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 {
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 {
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);
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 {
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 {
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
2380 {
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
2387 {
2388 memoryLimitIsReached = true;
2389 }
2390
2391 delete calcState;
2392
2393 return 0;
2394}
2395
2396int
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
2439 dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByMemoryLimit )
2440 {
2441 if( paraNodePool->isEmpty() )
2442 {
2445 {
2446 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
2448 }
2449 }
2450 else
2451 {
2453 {
2455 }
2456 }
2457 }
2459 {
2461 }
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
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 */
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);
2498 }
2499 }
2500 else
2501 {
2503 {
2505 }
2506 }
2507 }
2509 {
2511 }
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
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
2568int
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;
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);
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
2701int
2703 int source,
2704 int tag
2705 )
2706{
2707
2710 );
2711 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setCollectingIsAllowed(source);
2712
2713 return 0;
2714}
2715
2716int
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
2756int
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
2796int
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
2814int
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
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
2861int
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);
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
2892int
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
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 }
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
2943int
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
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
2995int
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);
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() -
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 {
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);
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 {
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);
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);
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
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);
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;
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);
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() -
3364 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
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 {
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 {
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);
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
3441#endif
3442 paraNodePool->insert(solvingNode);
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.
3468 {
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;
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);
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() -
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);
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
3579#endif
3580 paraNodePool->insert(solvingNode);
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.
3608 {
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;
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);
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
3696int
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
3732 dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByMemoryLimit )
3733 {
3734 if( paraNodePool->isEmpty() )
3735 {
3738 {
3739 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
3741 }
3742 }
3743 else
3744 {
3746 {
3748 }
3749 }
3750 }
3752 {
3754 }
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
3769void
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
3799void
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();
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()
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 }
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 {
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 }
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 {
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
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 }
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
4117void
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 {
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 {
4175 {
4177 {
4180#ifdef UG_WITH_ZLIB
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
4208 )
4209 {
4211 {
4214#ifdef UG_WITH_ZLIB
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 {
4228 {
4230 {
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
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 {
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 }
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 {
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 &&
4479 {
4480 hugeImbalance = false;
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 &&
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 }
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 {
4556 }
4557 }
4558#endif
4559 }
4560}
4561
4562#ifdef UG_WITH_ZLIB
4563void
4565 )
4566{
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
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 {
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
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
4682 {
4684 << " Restart"
4685 << std::endl;
4687 {
4689 "Restart after "
4690 << paraTimer->getElapsedTime() << " seconds." << std::endl;
4691 }
4692 }
4693
4695}
4696#endif
4697
4698bool
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;
4808 {
4809 if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4810 {
4811 nNormalSelection = 0;
4812 }
4813 else
4814 {
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;
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 {
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,
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 }
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
4991void
4993 )
4994{
4995 time_t timer;
4996 char timeStr[30];
4997
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 {
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();
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
5222void
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
5256void
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 */
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
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 }
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
5730void
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
5807void
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
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
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
5957int
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
5994 {
5996 << " S." << source << " | "
5997 << bbParaInitiator->convertToExternalValue(
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(
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() &&
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 {
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
6124 }
6125 delete solverState;
6126 return 0;
6127}
6128
6129int
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
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
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,
6292 {
6294 }
6295 }
6296 }
6297 }
6298
6300 {
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 }
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
6395void
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 }
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 */
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 );
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 {
6541 {
6543 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activate();
6544 run();
6545 return;
6546 }
6547 if( racingTermination )
6548 {
6549 if( paraNodePool->isEmpty()
6551 {
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 {
6575 // hardTimeLimitIsReached = true;
6576 // sendInterruptRequest();
6577 // runningPhase = TerminationPhase; waits until paraRacingSolverPool becomes empty
6578 break;
6579 }
6580
6582 // paraTimer->getElapsedTime() > paraParams->getRealParamValue(FinalCheckpointGeneratingTime) )
6583 {
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 {
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 {
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 */
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
6737void
6739 )
6740{
6741 for( int i = 1; i < paraComm->getSize(); i++ )
6742 {
6744 paraComm->send( NULL, 0, ParaBYTE, i, TagRetryRampUp )
6745 );
6746 }
6747}
6748
6749void
6751 )
6752{
6753 int exitSolverRequest = 0; // do nothing
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
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 );
6782 {
6784 << " S." << bestSolverRank << " TagInterruptRequest with collecting is sent"
6785 << std::endl;
6786 }
6787 }
6788 else
6789 {
6791 {
6793 << " S." << bestSolverRank << " TagInterruptRequest with collecting could not be sent (No best solvers)"
6794 << std::endl;
6795 }
6796 }
6797 }
6798 else
6799 {
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;
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
6915bool
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
6932void
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
6963void
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
6988void
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 */
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
7042void
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
7062int
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
7096
7098 {
7099 *osStatisticsRacingRampUp << "##################################" << std::endl;
7100 *osStatisticsRacingRampUp << "### Racing restarted " << nRestartedRacing << " times" << std::endl;
7101 *osStatisticsRacingRampUp << "##################################" << std::endl;
7102 }
7103
7105 {
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
7128void
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 }
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 */
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
7209void
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
7224void
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
7241int
7242BbParaLoadCoordinator::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;
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
#define DEF_BB_PARA_COMM(para_comm, comm)
Load Coordinator.
Base class for BbParaNode.
Structs used for merging nodes.
Base class of Calculation state in a ParaSolver.
int getNSent()
getter of the number of nodes transferred from the subproblem solving
double getRootTime()
getter of root node computing time
int getNSolvedWithNoPreprocesses()
getter of the number of solved nodes in the case that a node is solved without presolving....
double getAverageNodeCompTimeExcpetRoot()
getter of average computing time of a node except root node
int getNRestarts()
getter of the number of restart occurred in solving a subproblem
double getDualBoundValue()
getter of the final dual bound value
double getNSelfSplitNodesLeft()
getter of the number of self-split nodes left
int getTerminationState()
getter of the termination state for solving the subproblem
Class for the difference between instance and subproblem.
Class for initiator.
virtual void setFinalSolverStatus(FinalSolverState status)=0
set final solver status
virtual int getNSolutions()=0
get the number of incumbent solutions
virtual double getGap(double dualBoundValue)=0
get relative gap of dual bound value
virtual bool tryToSetIncumbentSolution(BbParaSolution *sol, bool checksol)=0
try to set incumbent solution
virtual double getAbsgap(double dualBoundValue)=0
get absolute gap of dual bound value
virtual double getAbsgapValue()=0
get absgap value specified
virtual void setNumberOfNodesSolved(long long n)=0
set number of nodes solved
virtual void setDualBound(double bound)=0
set final dual bound
virtual bool isObjIntegral()
check if objective function value is always integral or not
virtual double getGapValue()=0
get gap value specified
virtual BbParaDiffSubproblem * makeRootNodeDiffSubproblem()=0
make DiffSubproblem object for root node
BbParaNode * readParaNodeFromCheckpointFile(bool onlyBoundChanges)
read a ParaNode from checkpoint file
virtual double convertToExternalValue(double internalValue)=0
convert objective function value to external value TODO: this function may be in inherited class
virtual bool canGenerateSpecialCutOffValue()
check if solver can generate special cut off value or not
virtual void setInitialStatOnDiffSubproblem(int minDepth, int maxDepth, BbParaDiffSubproblem *diffSubproblem)
set initial status on DiffSubproblem
virtual BbParaSolution * getGlobalBestIncumbentSolution()=0
get global best incumbent solution
class for instance data
virtual int getVarIndexRange()=0
get variable index range TODO: this function should be in inherited class
Class for LoadCoordinator termination state which contains calculation state in a ParaLoadCoordinator...
bool read(ParaComm *comm, gzstream::igzstream &in)
read from checkpoint file
double generateMergeNodesCandidatesTime
time when merge ParaNode candidates are generated
unsigned long long nNodesInNodePool
number of nodes in ParaNodePool
unsigned long long nNodesLeftInAllSolvers
number of nodes left in all Solvers
double runningTime
this ParaLoadCoordinator running time
unsigned long long nFailedToSendBackAnotherNode
number of ParaNodes failed to send back after AnotherNode request
unsigned long long nNodesOutputLog
count for next logging of the number of transferred ParaNodes
double regenerateMergeNodesCandidatesTime
time when merge ParaNode candidates are regenerated
unsigned long long mMaxCollectingNodes
maximum multiplier for the number of collecting nodes
unsigned long long nFailedToSendBack
number of ParaNodes failed to send back
unsigned long long nDeletedInLc
number of ParaNodes deleted in LC
double tNodesOutputLog
keep time for next logging of the number of transferred ParaNodes
double externalGlobalBestDualBoundValue
global best dual bound value (external value)
unsigned long long nMaxUsageOfNodePool
maximum number of ParaNodes in ParaNodePool
unsigned long long nSentBackImmediately
Counters related to this ParaLoadCoordinator TODO: The numbers should be classified depending on solv...
void write(gzstream::ogzstream &out)
write to checkpoint file
unsigned long long nInitialP
initial p value, which indicates the number of good ParaNodes try to keep in LC
double addingNodeToMergeStructTime
time when a ParaNode is added to merge struct
double globalBestDualBoundValue
global best dual bound value (internal value)
unsigned long long nSentBackImmediatelyAnotherNode
number of ParaNodes sent back immediately after AnotherNode request from LC
bool winnerSolverNodesCollected
indicate that all winner solver nodes has been collected
bool hugeImbalance
indicate that a huge imbalance in solvers is detected
bool givenGapIsReached
shows if specified gap is reached or not
bool merging
for merging nodes
std::ofstream ofsTabularSolvingStatus
ofstream for solving status in tabular form
virtual int processTagSolution(int source, int tag)
function to process TagSolution message
bool restartingRacing
indicate that racing ramp-up is restarting
virtual int processRacingRampUpTagCompletionOfCalculation(int source, int tag)
function to process TagCompletionOfCalculation message in racing ramp-up stage
virtual void run()
run function to start main process
bool isBreakingFinised
indicate that breaking is finished or not if bootstrap ramp-up is not specified, this flag should be ...
BbParaNodesMerger * nodesMerger
pointer to nodes merger object, which merges nodes
virtual int processTagCompletionOfCalculation(int source, int tag)
function to process TagCompletionOfCalculation message
void terminateAllSolvers()
terminate all solvers
size_t nCollectedSolvers
counter to check if all solvers are terminated or not
int nBoundChangesOfBestNode
the number of fixed variables of the best node The followings are used temporary to generate merge no...
bool logSubtreeInfoFlag
indicate if subtree info. is logged or not
virtual int processTagSubtreeRootNodeStartComputation(int source, int tag)
function to process TagSubtreeRootNodeStartComputation message
bool warmStartNodeTransferring
indicate that the first node transferring at warm start (restart)
virtual void sendRetryRampUpToAllSolvers()
notify retry ramp-up to all solvers
std::ostream * osLogSubtreeInfo
ostram for subtree info. to switch output location
double minmalDualBoundNormalTermSolvers
minimal dual bound for normal termination solvers
bool aSolverTerminatedWithOptimality
indicate if a solver terminated with proving optimality of the problem
virtual int processTagSelfSplitFinished(int source, int tag)
function to process TagSelfSplitFinished message
virtual void inactivateRacingSolverPool(int rank)
inactivate racing solver pool
int nRestartedRacing
number of racing stages restarted
virtual int processTagAnotherNodeRequest(int source, int tag)
function to process TagAnotherNodeRequest message
BbParaNodePool * paraNodeToKeepCheckpointFileNodes
The first n nodes may always keep in checkpoint file, that is, the n nodes are not processed in this ...
virtual int processTagReassignSelfSplitSubtreeRootNode(int source, int tag)
function to process TagReassignSelfSplitSubtreeRootNode message
virtual void warmStart()
warm start (restart)
virtual int processTagNewSubtreeRootNode(int source, int tag)
function to process TagNewSubtreeRootNode message
bool outputTabularSolvingStatusFlag
output streams and flags which indicate the output is specified or not
virtual int restartRacing()
restart racing
BbParaNodePool * paraNodePoolBufferToGenerateCPF
This is used for GenerateReducedCheckpointFiles.
BbParaNodePool * unprocessedParaNodes
The last n nodes may always keep in checkpoint file, that is, the n nodes are not processed in this r...
virtual void sendCutOffValue(int receivedRank)
send cut off value
BbParaNodePool * paraNodePoolBufferToRestart
ParaNode pool for buffering ParaNodes in huge imbalance situation.
virtual bool sendParaTasksToIdleSolvers()
send ParaNodes to idle solvers
std::ostream * osTabularSolvingStatus
ostream for solving status in tabular form to switch output location
bool allCompInfeasibleAfterSolution
indicate that all computations are infeasible after a feasible solution
virtual void writeLoadCoordinatorStatisticsToCheckpointFile(gzstream::ogzstream &loadCoordinatorStatisticsStream, int nSolverInfo, double globalBestDualBoundValue, double externalGlobalBestDualBoundValue)
write LoadCorrdinator statistics to checkpoint file
virtual int processTagUbBoundTightened(int source, int tag)
function to process TagUbBoundTightened message
int minDepthInWinnerSolverNodes
racing winner information
virtual int processTagAllowToBeInCollectingMode(int source, int tag)
function to process TagAllowToBeInCollectingMode message
double statEmptyNodePoolTime
To measure how long does node pool stay in empty situation.
virtual void updateCheckpointFiles()
function to update checkpoint files
virtual int processTagSelfSplitTermStateForInterruption(int source, int tag)
function to process TagSelfSplitTermStateForInterruption message
virtual void changeSearchStrategyOfAllSolversToOriginalSearch()
change search strategy of all solvers to original search strategy
bool initialNodesGenerated
indicates that initial nodes have been generated
virtual int processTagLbBoundTightened(int source, int tag)
function to process TagLbBoundTightened message
virtual void writePreviousStatisticsInformation()
write previous run's statistics information
virtual bool isRacingStage()
check if current stage is in racing or not
virtual int processTagSolverState(int source, int tag)
function to process TagSolverState message
virtual void changeSearchStrategyOfAllSolversToBestBoundSearch()
change search strategy of all solvers to best bound bound search strategy
virtual void outputTabularSolvingStatusHeader()
output tabular solving status header
virtual void sendIncumbentValue(int receivedRank)
send incumbent value
double starvingTime
start time of starving active solvers
virtual int processTagTermStateForInterruption(int source, int tag)
function to process TagTermStateForInterruption message
double averageLastSeveralDualBoundGains
average dual bound gains of last several ones
int(UG::BbParaLoadCoordinator::* BbMessageHandlerFunctionPointer)(int, int)
virtual void writeSubtreeInfo(int source, ParaCalculationState *calcState)
write subtree info.
int nNormalSelection
number of normal node selection to a random node selection
double previousTabularOutputTime
to keep tabular solving status output time
std::ofstream ofsLogSubtreeInfo
ofstream for subtree info.
virtual int processTagTask(int source, int tag)
Message handlers.
double hugeImbalanceTime
start time of huge imbalance situation
int breakingSolverId
all nodes collecting solver Id: -1: no collecting
virtual void outputTabularSolvingStatus(char incumbent)
output solving status in tabular form
bool isCollectingModeRestarted
this flag indicate if a collecting mode is restarted or not
virtual void restartInRampDownPhase()
restart in ramp-down phase
virtual ~BbParaLoadCoordinator()
destructor
int maxDepthInWinnerSolverNodes
maximum depth of open nodes in the winner solver tree
BbParaNodePool * paraNodePoolToRestart
ParaNode pool to restart in ramp-down phase.
virtual int processRacingRampUpTagSolverState(int source, int tag)
message handlers specialized for racing ramp-up
double averageDualBoundGain
average dual bound gain: could be negative value at restart
virtual void newRacing()
start a new racing
virtual int processTagSubtreeRootNodeToBeRemoved(int source, int tag)
function to process TagSubtreeRootNodeToBeRemoved message
std::set< int > * selfSplitFinisedSolvers
indicate selfSplit finished solvers
std::deque< double > lastSeveralDualBoundGains
keep last several dual bound gains
int firstCollectingModeState
status of first collecting mode -1 : have not been in collecting mode 0 : once in collecting mode 1 :...
virtual bool updateSolution(BbParaSolution *)
update incumbent solution
virtual void sendInterruptRequest()
send interrupt request to all solvers
int nAverageDualBoundGain
number of nodes whose dual bound gain are counted
virtual int processTagSelfSlpitNodeCalcuationState(int source, int tag)
function to process TagSelfSlpitNodeCalcuationState message
BbParaLoadCoordinatorTerminationState lcts
LoadCoordinatorTerminationState: counters and times.
bool isHeaderPrinted
indicate if heeader is printed or not
bool primalUpdated
indicate that primal solution was updated or not
BbParaNodePool * paraNodePool
Pools in LoadCorrdinator.
class BbParaNodePoolForCleanUp
class BbParaNodePoolForMinimization
size_t getNumOfNodes()
get number of BbParaNodes in this pool
BbParaNodePtr extractNode()
extract a BbParaNode from this pool
void insert(BbParaNodePtr paraNode)
insert a BbParaNode object to this pool
virtual void insert(BbParaNodePtr node)=0
insert BbParaNode to this pool
virtual BbParaNodePtr extractNode()=0
extract a BbParaNode object from this pool
virtual double getBestDualBoundValue()=0
get best dual bound value of BbParaNode object in this pool
virtual bool isEmpty()=0
check if this pool is empty or not
size_t getMaxUsageOfPool()
get maximum usage of this pool
virtual int removeBoundedNodes(double incumbentValue)=0
remove bounded BbParaNodes by given incumbnet value
virtual int writeBbParaNodesToCheckpointFile(gzstream::ogzstream &out)=0
write BbParaNodes to checkpoint file
virtual void updateDualBoundsForSavingNodes()=0
update dual bound values for saving BbParaNodes to checkpoint file
virtual BbParaNodePtr extractNodeRandomly()=0
extract a BbParaNode object randomly from this pool
virtual size_t getNumOfNodes()=0
get number of BbParaNodes in this pool
virtual unsigned int getNumOfGoodNodes(double globalBestBound)=0
get number of good (heavy) BbParaNodes in this pool
class BbParaNode
Definition: bbParaNode.h:62
virtual int bcast(ParaComm *comm, int root)=0
broadcast this object
virtual int receiveSubtreeRootNodeId(ParaComm *comm, int source, int tag)=0
receive this object node Id
const std::string toString()
stringfy BbParaNode
Definition: bbParaNode.h:600
double getInitialDualBoundValue()
getter of initial dual bound value
Definition: bbParaNode.h:314
virtual int receiveNewSubtreeRoot(ParaComm *comm, int source)=0
receive this object
BbParaMergeNodeInfo * getMergeNodeInfo()
get merge node information struct
Definition: bbParaNode.h:658
void setDiffSubproblem(BbParaDiffSubproblem *inDiffSubproblem)
setter of diffSubproblem *‍/
Definition: bbParaNode.h:362
BbParaDiffSubproblem * getDiffSubproblem()
getter of diffSubproblem
Definition: bbParaNode.h:353
void setDualBoundValue(double inDualBoundValue)
setter of dual bound value
Definition: bbParaNode.h:323
int getDepth()
getter of depth
Definition: bbParaNode.h:283
virtual int send(ParaComm *comm, int destination)=0
send this object
const std::string toSimpleString()
stringfy BbParaNode as simple string
Definition: bbParaNode.h:619
void collectsNodes()
set all nodes are collected TODO: this function has to be investigated
Definition: bbParaNode.h:698
virtual int receive(ParaComm *comm, int source)=0
receive this object
void setMergeNodeInfo(BbParaMergeNodeInfo *mNode)
set merge node information to this BbParaNode object
Definition: bbParaNode.h:646
void setAncestor(ParaTaskGenealogicalPtr *inAncestor)
setter of ancestor
Definition: bbParaNode.h:382
bool areNodesCollected()
check if nodes are collected or not
Definition: bbParaNode.h:688
ParaTaskGenealogicalPtr * getAncestor()
getter of ancestor
Definition: bbParaNode.h:373
void setMergingStatus(int status)
set merging status
Definition: bbParaNode.h:667
BbParaNode * next
this pointer is used in case of self-split ramp-up in LC this field is not transferred
Definition: bbParaNode.h:83
double getDualBoundValue()
getter of dual bound value
Definition: bbParaNode.h:303
void setInitialDualBoundValue(double inTrueDualBoundValue)
setter of initial dual bound value
Definition: bbParaNode.h:333
double getMergeNodeTime()
getter of mergeNodeTime
double getGenerateMergeNodesCandidatesTime()
getter of generateMergeNodesCandidatesTime
double getAddingNodeToMergeStructTime()
getter of addingNodeToMergeStructTime
void deleteMergeNodeInfo(BbParaMergeNodeInfo *mNode)
delete merge node info
int mergeNodes(BbParaNode *node, BbParaNodePool *paraNodePool)
make a merge node
void generateMergeNodesCandidates(ParaComm *paraComm, ParaInitiator *paraInitiator)
generate merge nodes candidates
double getRegenerateMergeNodesCandidatesTime()
getter of regenerateMergeNodesCandidatesTime
void regenerateMergeNodesCandidates(BbParaNode *node, ParaComm *paraComm, ParaInitiator *paraInitiator)
regenerate merge nodes candidates
void addNodeToMergeNodeStructs(BbParaNode *node)
add a node to nodes merger
class BbParaRacingSolverPool (Racing Solver Pool)
virtual std::size_t getNumInactiveSolvers()
get number of inactive Solvers
virtual long long getNnodesSolvedInBestSolver()
get winner Solver rank
virtual int getNumNodesLeft(int rank)
get number of nodes left in the Solver specified by rank
virtual void reset()
reset racing solver pool
virtual void activate(BbParaNode *node)
activate racing ramp-up Solver pool with root BbParaNode object
virtual BbParaNode * extractNode()
extract racing root BbParaNode
virtual bool isWinnerDecided(bool feasibleSol)
check racing termination criteria
virtual void inactivateSolver(int rank)
inactivate the Solver specified by rank
class for solution
virtual double getCutOffValue()
get cutoff value
virtual double getObjectiveFunctionValue()=0
get objective function value
class BbParaSolverPoolForMinimization (Solver Pool for Minimization Problems)
virtual double getGlobalBestDualBoundValue()
get global best dual bound value
class BbParaSolverPool (Solver Pool base class)
virtual void activateSolver(int rank, BbParaNode *node, int nGoodNodesInNodePool, double averageDualBoundGain)
activate the Solver specified by rank with specified node which has been sent
virtual void switchInCollectingMode(BbParaNodePool *paraNodePool)=0
switch in collecting mode
virtual void deleteCurrentSubtreeRootNode(int rank)
delete current self-split subtree root node from the active solver with the specified rank
virtual int getMCollectingNodes()
get multiplier of collecting BbParaNodes
virtual void switchOutCollectingMode()
switch out collecting mode
virtual bool isSolverActive(int rank)
check if the Solver specified by rank is active or not
virtual unsigned long long getNnodesInSolvers()
get number of nodes in all Solvers
virtual bool isDualBounGainTesting(int rank)
check if dual bound gain testing is proceeding or not in the Solver specified
virtual bool isInCollectingMode()
check if this system is in collecting mode or not
virtual void setSwichOutTime(double time)
set time of switching out collecting mode
virtual bool isActive()
check if this Solver pool is active or not
virtual bool isSolverInCollectingMode(int rank)
get collecting mode of the Solver specified by rank
virtual bool isTerminateRequested(int rank)
check if the Solver specified by rank is terminate requested or not
virtual void resetCountersInSolver(int rank, long long numOfNodesSolved, int numOfSelfSplitNodesLeft, BbParaNodePool *paraNodePool)
reset counters in the Solver specified by rank
virtual BbParaNode * getSelfSplitSubtreeRootNodes(int rank)
get self-split subtree root node from the active solver with the specified rank
virtual int getNumOfNodesLeftInBestSolver()
get the number of nodes left in the Solver which has the best dual bound value
virtual ParaTask * getCurrentTask(int rank)
get current solving BbParaNode in the Solver specified by rank *‍/
virtual double getSwichOutTime()
the following functions are to omit rebooting collecting mode process
virtual void addTotalNodesSolved(unsigned long long num)
add number of nodes solved in all Solvers
virtual unsigned long long getNnodesSolvedInSolvers()
get number of nodes solved in current running Solvers
virtual long long getNumOfNodesSolved(int rank)
get the number of nodes solved by the Solver specified
class BbParaSolverState (ParaSolver state object for notification message)
int getNNodesLeft()
getter of number of nodes left by the notification Solver
unsigned int getNotificaionId()
getter of notification id
double getSolverLocalBestDualBoundValue()
gettter of best dual bound value
double getGlobalBestPrimalBoundValue()
get global best primal bound value that the notification Solver has
double getDeterministicTime()
getter of deterministic time
double getAverageDualBoundGain()
getter of average dual bound gain received
bool isRacingStage()
getter of isRacingStage
long long getNNodesSolved()
getter of number of nodes solved by the notification Solver
class BbParaSolverTerminationState (Solver termination state in a ParaSolver)
int getCalcTerminationState()
getter of calcTermination state
Base class of Calculation state in a ParaSolver.
virtual std::string toSimpleString()=0
stringfy ParaCalculationState (simple string version)
int getNSolved()
geeter of the number of tasks solved in a subproblem
double getCompTime()
getter of computing time of a subproblem
virtual void receive(ParaComm *comm, int source, int tag)=0
send this object to destination
Base class of communicator object.
Definition: paraComm.h:102
virtual ParaRacingRampUpParamSet * createParaRacingRampUpParamSet()=0
create ParaRacingRampUpParamSet object
virtual ParaSolverState * createParaSolverState()=0
create ParaSolverState object by default constructor
virtual ParaSolution * createParaSolution()=0
create ParaSolution object by default constructor
virtual int getSize()=0
get number of UG processes or UG threads depending on run-time environment
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...
virtual ParaTask * createParaTask()=0
create ParaTask object by default constructor
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)=0
send function for standard ParaData types
virtual ParaSolverTerminationState * createParaSolverTerminationState()=0
create ParaSolverTerminationState object by default constructor
virtual int receive(void *bufer, int count, const int datatypeId, int source, const int tag)=0
receive function for standard ParaData types
virtual int getRank()=0
get rank of this process or this thread depending on run-time environment
virtual ParaCalculationState * createParaCalculationState()=0
transfer object factory
class for deterministic timer
virtual void update(double value)=0
update function of the deterministic time. the deterministic time is a kind of counter
virtual double getElapsedTime()=0
getter of the deterministic time
Class for initiator.
Definition: paraInitiator.h:63
virtual int reInit(int nRestartedRacing)=0
reinitizalie initiator TODO: this function should be in inherited class
virtual double readSolutionFromCheckpointFile(char *afterCheckpointingSolutionFileName)=0
read solution from checkpoint file
virtual void writeCheckpointSolution(const std::string &filename)=0
write checkpoint solution
virtual void writeSolution(const std::string &message)=0
write solution
virtual void generateRacingRampUpParameterSets(int nParamSets, ParaRacingRampUpParamSet **racingRampUpParamSets)=0
generate racing ramp-up parameter sets TODO: this function may be in inherited class
const char * getPrefixWarm()
get prefix of warm start (restart) files
virtual ParaInstance * getParaInstance()=0
get instance object
virtual double getEpsilon()=0
get epsilon specified
virtual void outputFinalSolverStatistics(std::ostream *os, double time)=0
output final solver statistics
class for instance data
Definition: paraInstance.h:51
virtual int bcast(ParaComm *comm, int rank, int method)=0
broadcast function to all solvers
virtual const char * getProbName()=0
get problem name
bool isCheckpointState
indicate if this state is at checkpoint or not
unsigned long long nWarmStart
number of warm starts (restarts)
unsigned long long nSent
number of ParaTasks sent from LC
unsigned long long nReceived
number of ParaTasks received from Solvers
Class for LoadCoordinator.
ParaParamSet * paraParams
UG parameter set.
bool hardTimeLimitIsReached
indicate that hard time limit is reached or not
ParaComm * paraComm
communicator used
char lastCheckpointTimeStr[26]
lastCheckpointTimeStr[0] == ' ' means no checkpoint
virtual int processTagTerminated(int source, int tag)
function to process TagTerminated message
MessageHandlerFunctionPointer * racingRampUpMessageHandler
message handlers table for racing stage
bool restarted
indicates that this run is restarted from checkpoint files
long long nTasksLeftInInterruptedRacingSolvers
number of of tasks remains of the the winner solver in the racing solvers
bool * racingSolversExist
indicate if racing solver exits or not, true: exists
bool terminationIssued
indicate termination request is issued
std::ostream * osLogTasksTransfer
ostream for task transfer info. to switch output location
virtual void writeTransferLog(int rank, ParaCalculationState *state)
write transfer log
size_t nTerminated
counter to check if all solvers are terminated or not
ParaSolverPool * paraSolverPool
Pools in LoadCorrdinator.
int nSolvedRacingTermination
number of tasks solved at the racing termination solver
virtual void sendRampUpToAllSolvers()
notify ramp-up to all solvers
bool memoryLimitIsReached
indicate if memory limit is reached or not in a solver, when base solver has memory management featur...
ParaRacingSolverPool * paraRacingSolverPool
racing solver pool
long long nSolvedInInterruptedRacingSolvers
number of tasks solved of the winner solver in the racing solvers
int(UG::ParaLoadCoordinator::* MessageHandlerFunctionPointer)(int, int)
double previousCheckpointTime
For checkpoint.
ParaInitiator * paraInitiator
initiator
int createNewGlobalSubtreeId()
create a new global subtree Id
int racingWinner
racing winner information
ParaTimer * paraTimer
Timers for LoadCoordinator.
RunningPhase runningPhase
status of LoadCoordinator
bool interruptIsRequested
indicate that all solver interrupt message is requested or not
std::ostream * osStatisticsFinalRun
ostream for statistics of the final run
bool interruptedFromControlTerminal
interrupted from control terminal
virtual int processTagToken(int source, int tag)
function to process TagToken message
std::ostream * osStatisticsRacingRampUp
ostream for statistics for racing solvers to switch output location
std::ostream * osLogSolvingStatus
ostram for solving status to switch output location
virtual void writeTransferLogInRacing(int rank, ParaCalculationState *state)
write transfer log in racing
bool logTasksTransferFlag
indicate if task transfer info. is logged or not
ParaDeterministicTimer * paraDetTimer
deterministic timer used in case of deterministic mode this timer need to be created in case of deter...
ParaRacingRampUpParamSet * racingWinnerParams
racing winner parameter set
virtual int processTagHardTimeLimit(int source, int tag)
function to process TagHardTimeLimit message
bool logSolvingStatusFlag
output streams and flags which indicate the output is specified or not
int nHandlers
number of valid handlers
MessageHandlerFunctionPointer * messageHandler
message handlers table for primary phase
bool computationIsInterrupted
indicate that current computation is interrupted or not
bool racingTermination
racing termination information
class ParaParamSet
Definition: paraParamSet.h:850
bool getBoolParamValue(int param)
get bool parameter value
void setBoolParamValue(int param, bool value)
set bool parameter value
void setIntParamValue(int param, int value)
set int parameter value
double getRealParamValue(int param)
get real parameter value
int getIntParamValue(int param)
get int parameter value
const char * getStringParamValue(int param)
get string parameter value
void setRealParamValue(int param, double value)
set real parameter value
class ParaRacingRampUpParamSet (parameter set for racing ramp-up)
virtual bool read(ParaComm *comm, gzstream::igzstream &in)=0
read from checkpoint file
virtual void write(gzstream::ogzstream &out)=0
write to checkpoint file
virtual int send(ParaComm *comm, int destination)=0
send ParaRacingRampUpParamSet
virtual int getStrategy()=0
get strategy
int getWinner()
get winner Solver rank
virtual bool isSolverActive(int rank)=0
check if the specified Solver is active or not
std::size_t getNSolvers()
get number of Solvers in this Solver pool
virtual std::size_t getNumInactiveSolvers()=0
get number of inactive Solvers
virtual std::size_t getNumActiveSolvers()=0
get number of active Solvers
virtual ParaSolution * clone(ParaComm *comm)=0
create clone of this object
virtual void send(ParaComm *comm, int destination)=0
send solution data
virtual void receive(ParaComm *comm, int source)=0
receive solution data
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
virtual bool isInterruptRequested(int rank)=0
check if the Solver specified by rank is interrupt requested or not
virtual bool isTerminateRequested(int rank)=0
check if the Solver specified by rank is terminate requested or not
virtual void terminateRequested(int rank)=0
set the Solver specified by rank is terminate requested
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
virtual std::size_t getNumInactiveSolvers()=0
get number of inactive Solvers
virtual std::size_t getNumActiveSolvers()=0
get number of active Solvers
virtual void receive(ParaComm *comm, int source, int tag)=0
receive this object
class ParaSolverTerminationState (Solver termination state in a ParaSolver)
virtual bool read(ParaComm *comm, gzstream::igzstream &in)=0
read ParaSolverTerminationState from checkpoint file
int getInterruptedMode()
getter of interrupted flag
double getDeterministicTime()
getter of deterministic time
virtual std::string toString(ParaInitiator *initiator)=0
stringfy ParaSolverTerminationState object
virtual void receive(ParaComm *comm, int source, int tag)=0
receive this object
class ParaTaskGenealogicalLocalPtr
Definition: paraTask.h:415
class ParaTask
Definition: paraTask.h:542
bool isRootTask()
check if root task or not
Definition: paraTask.h:624
void setEstimatedValue(double inEstimatedValue)
setter of estimated value
Definition: paraTask.h:843
virtual int bcast(ParaComm *comm, int root)=0
broadcast this object
bool isSameParetntTaskSubtaskIdAs(const TaskId &inTaskId)
check if this task's parent subtree id is the same as that of argument ParaTask's task id
Definition: paraTask.h:663
void addDescendant(ParaTaskGenealogicalPtr *inDescendant)
add a descendant
Definition: paraTask.h:939
void setGlobalSubtaskId(int lcId, int subtaskId)
setter of global subtask id
Definition: paraTask.h:761
TaskId getTaskId()
getter of task id
Definition: paraTask.h:794
virtual const std::string toSimpleString()
stringfy ParaTask as simple string
Definition: paraTask.h:1015
class ParaTimer
Definition: paraTimer.h:49
virtual double getElapsedTime()=0
get elapsed time
TaskId class.
Definition: paraTask.h:223
Utilities for handling gzipped input and output streams.
static const int CleanUp
static const int TagLCBestBoundValue
Definition: bbParaTagDef.h:53
static const int TagAckCompletion
Definition: paraTagDef.h:62
static const int ProhibitCollectOnceMultiplier
static const int NEagerToSolveAtRestart
static const int DualBoundGainTest
static const int TagAnotherNodeRequest
Definition: bbParaTagDef.h:48
static const int TagCompletionOfCalculation
Definition: paraTagDef.h:54
static const int CompTerminatedByInterruptRequest
Definition: paraDef.h:184
static const int TagCutOffValue
Definition: bbParaTagDef.h:66
static const int MaxStrLen
Definition: paraDef.h:179
static const int TagWinner
Definition: paraTagDef.h:60
static const int LightWeightRootNodeProcess
static const int TagLbBoundTightenedBound
Definition: bbParaTagDef.h:63
static const int CompInterruptedInRacingStage
Definition: paraDef.h:186
static const int NTransferLimitForBreaking
static const int CompTerminatedByAnotherTask
Definition: paraDef.h:183
static const int MergeNodesAtRestart
static const int TagAllowToBeInCollectingMode
Definition: bbParaTagDef.h:57
static const int TagTerminateSolvingToRestart
Definition: bbParaTagDef.h:70
static const int NStopBreaking
static const int CheckpointInterval
Definition: paraParamSet.h:107
static const int NSolverNodesStartBreaking
static const int TagSolution
Definition: paraTagDef.h:51
static const int FinalCheckpointGeneratingTime
Definition: paraParamSet.h:108
static const int TagToken
Definition: paraTagDef.h:63
static const double displayInfOverThisValue
if gap is over this value, Inf is displayed at gap TODO: this would move to inherited class
static const int TagTaskReceived
Definition: paraTagDef.h:48
static const int NoUpperBoundTransferInRacing
static const int CompTerminatedByMemoryLimit
Definition: paraDef.h:189
static const int TagInterruptRequest
Definition: paraTagDef.h:57
static const int TagSelfSplitFinished
Definition: bbParaTagDef.h:71
static const int InitialNodesGeneration
static const int TNodesTransferLogging
static const int TagNotificationId
Definition: paraTagDef.h:55
@ MemoryLimitIsReached
memory limit is reached in a solver
@ ComputingWasInterrupted
computing was interrupted
@ GivenGapIsReached
given gap is reached for the computation
@ ProblemWasSolved
problem was solved
@ HardTimeLimitIsReached
hard time limit is reached
@ RequestedSubProblemsWereSolved
requested subproblem was solved
@ InitialNodesGenerated
initial nodes were generated
static const int LogSubtreeInfo
static const int HugeImbalanceThresholdTime
static const int EnhancedCheckpointStartTime
static const int ABgapForSwitchingToBestSolver
static const int TagIncumbentValue
Definition: paraTagDef.h:52
static const int MultiplierForBreakingTargetBound
static const int FinalCheckpointNSolvers
static const int TagLbBoundTightenedIndex
Definition: bbParaTagDef.h:62
static const int TagCollectAllNodes
Definition: bbParaTagDef.h:51
static const int ParaINT
Definition: paraComm.h:66
static const int NNodesToKeepInCheckpointFile
static const int TagRestart
Definition: bbParaTagDef.h:61
static const int InstanceTransferMethod
static const int CollectOnce
static const int TagGivenGapIsReached
Definition: bbParaTagDef.h:56
static const int TagTerminated
Definition: paraTagDef.h:58
static const int NBoundChangesOfMergeNode
static const int TagGlobalBestDualBoundValueAtWarmStart
Definition: bbParaTagDef.h:47
static const int CheckpointFilePath
Definition: paraParamSet.h:130
static const int TagUbBoundTightenedIndex
Definition: bbParaTagDef.h:64
static const int TagSubtreeRootNodeToBeRemoved
Definition: bbParaTagDef.h:74
static const int TransferConflictCuts
static const int LogSolvingStatusFilePath
Definition: paraParamSet.h:127
static const int CheckEffectOfRootNodePreprocesses
static const int RatioToApplyLightWeightRootProcess
static const int NChangeIntoCollectingModeNSolvers
static const int TagTerminateRequest
Definition: paraTagDef.h:56
static const int RestartInRampDownThresholdTime
static const int RandomNodeSelectionRatio
static const int TransferLocalCuts
static const int TimeLimit
Definition: paraParamSet.h:106
static const int CompTerminatedByTimeLimit
Definition: paraDef.h:188
static const int TagAny
Definition: paraTagDef.h:44
static const int ParaBYTE
Definition: paraComm.h:79
static const int GenerateReducedCheckpointFiles
static const int ParaUNSIGNED
Definition: paraComm.h:72
static const int OmitInfeasibleTerminationInRacing
static const int TagSolverState
Definition: paraTagDef.h:53
static const int TagTermStateForInterruption
Definition: bbParaTagDef.h:77
static const int Checkpoint
Definition: paraParamSet.h:75
static const int TimeToIncreaseCMS
static const int TagHardTimeLimit
Definition: paraTagDef.h:61
static const int Deterministic
Definition: paraParamSet.h:76
static const int EnhancedCheckpointInterval
static const int RampUpPhaseProcess
static const int TagReassignSelfSplitSubtreeRootNode
Definition: bbParaTagDef.h:75
static const int RestartRacing
static const int NNodesTransferLogging
static const int BgapStopSolvingMode
static const int BgapCollectingMode
static const int CompTerminatedNormally
Definition: paraDef.h:182
static const int CompInterruptedInMerging
Definition: paraDef.h:187
static const int LightWeightNodePenartyInCollecting
static const int NCollectOnce
@ TerminationPhase
termination phase, includes interrupting phase
@ RampUpPhase
ramp-up phase
@ NormalRunningPhase
normal running phase (primary phase)
static const int TagUbBoundTightenedBound
Definition: bbParaTagDef.h:65
static const int StopRacingNumberOfNodesLeftMultiplier
static const int TagBreaking
Definition: bbParaTagDef.h:55
static const int RacingStatBranching
static const int RestartInRampDownActiveSolverRatio
static const int DualBoundGainBranchRatio
static const int TagSelfSplitTermStateForInterruption
Definition: bbParaTagDef.h:78
static const int NIdleSolversToTerminate
static const int NChangeIntoCollectingMode
static const int HugeImbalanceActiveSolverRatio
static const int CompTerminatedInRacingStage
Definition: paraDef.h:185
static const int DeterministicTabularSolvingStatus
static const int TagRetryRampUp
Definition: bbParaTagDef.h:46
static const int OutputTabularSolvingStatus
static const int TagKeepRacing
Definition: bbParaTagDef.h:69
static const int OmitTerminationNSolutionsInRacing
static const int EnhancedFinalCheckpoint
static const int Quiet
Definition: paraParamSet.h:71
static const int TagSubtreeRootNodeStartComputation
Definition: bbParaTagDef.h:73
static const int TabularSolvingStatusInterval
static const int NumberOfInitialNodes
static const int WaitTerminationOfThreads
static const int DistributeBestPrimalSolution
static const int NMergingNodesAtRestart
static const int StopRacingNumberOfNodesLeft
static const int MultiplierForBgapCollectingMode
static const int TagSelfSlpitNodeCalcuationState
Definition: bbParaTagDef.h:76
static const int TagNoNodes
Definition: bbParaTagDef.h:49
static const int ParaDOUBLE
Definition: paraComm.h:76
static const int MultiplierForCollectingMode
static const int TagNewSubtreeRootNode
Definition: bbParaTagDef.h:72
static const int StatisticsToStdout
Definition: paraParamSet.h:77
static const int CommunicateTighterBoundsInRacing
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
#define THROW_LOGICAL_ERROR5(msg1, msg2, msg3, msg4, msg5)
Definition: paraDef.h:112
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
#define ABORT_LOGICAL_ERROR3(msg1, msg2, msg3)
Definition: paraDef.h:95
#define DEFAULT_NUM_EPSILON
Definition: paraDef.h:49
#define EPSLE(x, y, eps)
Definition: paraDef.h:168
#define ABORT_LOGICAL_ERROR1(msg1)
Definition: paraDef.h:61
#define EPSLT(x, y, eps)
Definition: paraDef.h:167
#define THROW_LOGICAL_ERROR4(msg1, msg2, msg3, msg4)
Definition: paraDef.h:103
#define MINEPSILON
Definition: paraDef.h:50
#define EPSEQ(x, y, eps)
Definition: paraDef.h:166
#define REALABS(x)
Definition: paraDef.h:165
#define EPSGT(x, y, eps)
Definition: paraDef.h:169
#define THROW_LOGICAL_ERROR3(msg1, msg2, msg3)
Definition: paraDef.h:86
Base class for initial statistics collecting class.
Merge node information struct.
@ PARA_MERGED_RPRESENTATIVE
representative node for merging
BbParaDiffSubproblem * mergedDiffSubproblem
merged DiffSubproblem, in case this node is merged and this is the head *‍/
BbParaMergeNodeInfo * mergedTo
pointer to merge node info to which this node is merged *‍/
int nMergedNodes
the number of merged nodes with this node.
BbParaDiffSubproblem * origDiffSubproblem
original DiffSubproblem *‍/
enum UG::BbParaMergeNodeInfo_::@0 status
status of this ParaMargeNodeInfo