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-2025 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 << *paraInitiator << "EnhancedCheckpointStartTime mast be greater than 1.0. " << std::endl;
192 std::cout << *paraInitiator << "EnhancedCheckpointStartTime = " << paraParams->getRealParamValue(UG::EnhancedCheckpointStartTime) << std::endl;
193 exit(1);
194 }
196 {
197 std::cout << *paraInitiator << "EnhancedCheckpointStartTime mast be less than FinalCheckpointGeneratingTime. " << std::endl;
198 std::cout << *paraInitiator << "EnhancedCheckpointStartTime = " << paraParams->getRealParamValue(UG::EnhancedCheckpointStartTime) << std::endl;
199 std::cout << *paraInitiator << "FinalCheckpointGeneratingTime = " << paraParams->getRealParamValue(UG::FinalCheckpointGeneratingTime) << std::endl;
200 exit(1);
201 }
203 {
204 std::cout << *paraInitiator << "FinalCheckpointNSolvers mast be less equal than the number of solvers. " << std::endl;
205 std::cout << *paraInitiator << "FinalCheckpointNSolvers = " << paraParams->getIntParamValue(UG::FinalCheckpointNSolvers) << std::endl;
206 std::cout << *paraInitiator << "The number of solvers = " << (paraComm->getSize() - 1) << std::endl;
207 exit(1);
208 }
209 }
211 {
213 std::cout << *paraInitiator << "** FinalCheckpointGeneratingTime is specified, then TimeLimit is omitted. ** " << std::endl;
214 }
215
216 // disply ramp-up mode
218 {
219 std::cout << *paraInitiator << "LC is working with normal ramp-up." << std::endl;
220 }
222 {
223 std::cout << *paraInitiator << "LC is working with racing ramp-up." << std::endl;
224 }
226 {
227 std::cout << *paraInitiator << "LC is working with racing ramp-up and with rebuilding tree after racing." << std::endl;
228 }
230 {
231 std::cout << *paraInitiator << "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 << *paraInitiator << "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 << *paraInitiator << "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 << *paraInitiator << "** -w opttion = " << paraInitiator->getPrefixWarm() << " **" << std::endl;
363 std::cout << *paraInitiator << "** MergeNodesAtRestart = " << paraParams->getBoolParamValue(UG::MergeNodesAtRestart) << std::endl;
364 std::cout << *paraInitiator << "** DualBoundGainTest = " << paraParams->getBoolParamValue(UG::DualBoundGainTest) << std::endl;
365 std::cout << *paraInitiator << "** 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 << *paraInitiator << lcts.toString() << std::endl;
754 }
755
757 {
759 }
760
762 {
763 *osStatisticsFinalRun << *paraInitiator << "***** <<< NOTE >>> "
765 << " active racing ramp-up solvers exist." << std::endl;
766 *osStatisticsFinalRun << *paraInitiator << 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 << *paraInitiator << "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( tightenedIdex >= dynamic_cast<BbParaInstance *>(dynamic_cast<BbParaInitiator *>(paraInitiator)->getParaInstance())->getNVars() ) return 0;
2732 if( EPSLT(dynamic_cast<BbParaInitiator *>(paraInitiator)->getTightenedVarLbs(tightenedIdex), tightenedBound, MINEPSILON ) )
2733 {
2734 // std::cout << "From Rank " << source << ": in initiator LB = " << paraInitiator->getTightenedVarLbs(tightenedIdex) << ", rv = " << tightenedBound << std::endl;
2735 if( dynamic_cast<BbParaInitiator *>(paraInitiator)->setTightenedVarLbs(tightenedIdex, tightenedBound) &&
2737 {
2738 for( size_t i = 1; i <= paraRacingSolverPool->getNumActiveSolvers(); i++ )
2739 {
2740 if( static_cast<int>(i) != source )
2741 {
2743 paraComm->send( (void *)&tightenedIdex, 1, UG::ParaINT, i, UG::TagLbBoundTightenedIndex )
2744 );
2746 paraComm->send( (void *)&tightenedBound, 1, UG::ParaDOUBLE, i, UG::TagLbBoundTightenedBound )
2747 );
2748 }
2749 }
2750 // std::cout << "From Rank " << source << ": broadcast tightened lower bond. idx = " << tightenedIdex << ", bound = " << tightenedBound << std::endl;
2751 }
2752 }
2753
2754 return 0;
2755}
2756
2757int
2759 int source,
2760 int tag
2761 )
2762{
2763
2764 int tightenedIdex;
2765 double tightenedBound;
2767 paraComm->receive( (void *)&tightenedIdex, 1, ParaINT, source, TagUbBoundTightenedIndex )
2768 );
2770 paraComm->receive( (void *)&tightenedBound, 1, ParaDOUBLE, source, TagUbBoundTightenedBound )
2771 );
2772 if( tightenedIdex >= dynamic_cast<BbParaInstance *>(dynamic_cast<BbParaInitiator *>(paraInitiator)->getParaInstance())->getNVars() ) return 0;
2773 if( EPSGT(dynamic_cast<BbParaInitiator *>(paraInitiator)->getTightenedVarUbs(tightenedIdex), tightenedBound, MINEPSILON ) )
2774 {
2775 // std::cout << "From Rank " << source << ": in initiator UB = " << paraInitiator->getTightenedVarUbs(tightenedIdex) << ", rv = " << tightenedBound << std::endl;
2776 if( dynamic_cast<BbParaInitiator *>(paraInitiator)->setTightenedVarUbs(tightenedIdex, tightenedBound) &&
2778 {
2779 for( size_t i = 1; i <= paraRacingSolverPool->getNumActiveSolvers(); i++ )
2780 {
2781 if( static_cast<int>(i) != source )
2782 {
2784 paraComm->send( (void *)&tightenedIdex, 1, UG::ParaINT, i, UG::TagUbBoundTightenedIndex )
2785 );
2787 paraComm->send( (void *)&tightenedBound, 1, UG::ParaDOUBLE, i, UG::TagUbBoundTightenedBound )
2788 );
2789 }
2790 }
2791 // std::cout << "From Rank " << source << ": broadcast tightened upper bond. idx = " << tightenedIdex << ", bound = " << tightenedBound << std::endl;
2792 }
2793 }
2794
2795 return 0;
2796}
2797
2798int
2800 int source,
2801 int tag
2802 )
2803{
2804
2805 assert( tag == TagSelfSplitFinished );
2807 paraComm->receive( NULL, 0, ParaBYTE, source, TagSelfSplitFinished )
2808 );
2809 selfSplitFinisedSolvers->insert(source);
2810// std::cout << "***TagSelfSplitFinished*** R." << source
2811// << ": dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved = "
2812// << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source) << std::endl;
2813 return 0;
2814}
2815
2816int
2818 int source,
2819 int tag
2820 )
2821{
2822
2823 BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2824 paraNode->receiveNewSubtreeRoot(paraComm, source);
2825
2826// std::cout << "S." << source
2827// << ", KEEP: nBoundChanges = " << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges() << std::endl;
2828
2829 assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2830
2832 {
2833 dynamic_cast<BbParaSolverPool *>(paraSolverPool)->addNewSubtreeRootNode(source, paraNode);
2834 }
2835
2836 assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2837
2839 {
2840 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2842 << " S." << source
2843 << " |< "
2844 << bbParaInitiator->convertToExternalValue(
2845 paraNode->getDualBoundValue() )
2846 << " "
2847 << paraNode->toSimpleString();
2848 if( paraNode->getDiffSubproblem() )
2849 {
2851 << ", "
2852 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
2853 << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
2854 }
2855 *osLogSolvingStatus << std::endl;
2856 }
2857// std::cout << "***TagNewSubtreeRootNode*** R." << source
2858// << ": dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved = "
2859// << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source) << std::endl;
2860 return 0;
2861}
2862
2863int
2865 int source,
2866 int tag
2867 )
2868{
2869
2870 BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2871 // BbParaNode *nextNode = 0;
2873 // std::cout << "processTagSubtreeRootNodeToBeRemoved" << paraNode->toSimpleString() << std::endl;
2874
2876 {
2877 dynamic_cast<BbParaSolverPool *>(paraSolverPool)->makeSubtreeRootNodeCurrent(source, paraNode);
2879 {
2880 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2882 << " S." << source
2883 << " |s "
2884 << dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPool *>(paraSolverPool)->getCurrentTask(source))->toSimpleString();
2885 *osLogSolvingStatus << std::endl;
2886 }
2887 }
2888
2889 assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2890
2891 return 0;
2892}
2893
2894int
2896 int source,
2897 int tag
2898 )
2899{
2900
2901 BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2902 // BbParaNode *nextNode = 0;
2904 // std::cout << "processTagSubtreeRootNodeToBeRemoved" << paraNode->toSimpleString() << std::endl;
2905
2906 assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2907
2909 (!dynamic_cast<BbParaSolverPool *>(paraSolverPool)->isSolverActive(source) ) )
2910 {
2911 return 0; // Anyway, the node is going to paraNodePool
2912 }
2913
2915 {
2916 dynamic_cast<BbParaSolverPool *>(paraSolverPool)->removeSubtreeRootNode(source, paraNode);
2917 }
2919 {
2920 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2922 << " S." << source
2923 << " |> "
2924 << bbParaInitiator->convertToExternalValue(
2925 paraNode->getDualBoundValue() )
2926 << " "
2927 << paraNode->toSimpleString();
2928 if( paraNode->getDiffSubproblem() )
2929 {
2931 << ", "
2932 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
2933 << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
2934 }
2935 *osLogSolvingStatus << std::endl;
2936 }
2937
2938 delete paraNode;
2939
2940 lcts.nDeletedInLc++; // this node is deleted without calcutaion
2941
2942 return 0;
2943}
2944
2945int
2947 int source,
2948 int tag
2949 )
2950{
2951
2952 BbParaNode *paraNode = dynamic_cast<BbParaNode *>(paraComm->createParaTask());
2953 // BbParaNode *nextNode = 0;
2955 // std::cout << "processTagReassignSelfSplitSubtreeRootNode" << paraNode->toSimpleString() << std::endl;
2956
2957 assert( hardTimeLimitIsReached || memoryLimitIsReached || givenGapIsReached || dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getCurrentTask(source) != 0 );
2958
2959// if( runningPhase == TerminationPhase )
2960// {
2961// return 0; // Anyway, the node is going to paraNodePool
2962// }
2963
2965 {
2966 BbParaNode *reassignedNode = dynamic_cast<BbParaSolverPool *>(paraSolverPool)->extractSelfSplitSubtreeRootNode(source, paraNode);
2967
2969 {
2970 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
2972 << " S." << source
2973 << " |>p< "
2974 << bbParaInitiator->convertToExternalValue(
2975 reassignedNode->getDualBoundValue() )
2976 << " "
2977 << reassignedNode->toSimpleString();
2978 if( reassignedNode->getDiffSubproblem() )
2979 {
2981 << ", "
2982 // << dynamic_cast<BbParaDiffSubproblem *>(reassignedNode->getDiffSubproblem())->getNBoundChanges()
2983 << dynamic_cast<BbParaDiffSubproblem *>(reassignedNode->getDiffSubproblem())->toStringStat();
2984 }
2985 *osLogSolvingStatus << std::endl;
2986 }
2987
2988 paraNodePool->insert(reassignedNode);
2989
2990 }
2991
2992 delete paraNode;
2993
2994 return 0;
2995}
2996
2997int
2999 int source,
3000 int tag
3001 )
3002{
3003
3005 calcState->receive(paraComm, source, tag);
3006
3007 writeTransferLog(source, calcState);
3008
3009 int calcTerminationState = calcState->getTerminationState();
3010 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3011 BbParaSolverPool *bbParaSolverPool = dynamic_cast<BbParaSolverPool *>(paraSolverPool);
3013 {
3014 switch ( calcTerminationState )
3015 {
3017 {
3018 if( bbParaSolverPool->getSelfSplitSubtreeRootNodes(source) )
3019 {
3021 << " S." << source << " |> " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3022 << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3023 }
3024 else
3025 {
3027 << " S." << source << " > " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3028 << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3029 }
3030 break;
3031 }
3033 {
3034 if( bbParaSolverPool->getSelfSplitSubtreeRootNodes(source) )
3035 {
3036 /** When starts with racing ramp-up, solvers except winner should be terminated in this state */
3038 << " S." << source << " |>(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3039 << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3040 }
3041 else
3042 {
3043 /** When starts with racing ramp-up, solvers except winner should be terminated in this state */
3045 << " S." << source << " |>(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
3046 }
3047 break;
3048 }
3050 {
3052 << " S." << source << " >(INTERRUPTED) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3053 << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3054 break;
3055 }
3057 {
3059 << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3060 << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3061 break;
3062 }
3064 {
3066 << " S." << source << " >(INTERRUPTED_BY_MEMORY_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue())
3067 << ", " << bbParaSolverPool->getCurrentTask(source)->toSimpleString();
3068 break;
3069 }
3070 default:
3071 THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
3072 }
3073 *osLogSolvingStatus << ", ct:" << calcState->getCompTime()
3074 << ", nr:" << calcState->getNRestarts()
3075 << ", n:" << calcState->getNSolved()
3076 << ", rt:" << calcState->getRootTime()
3077 << ", avt:" << calcState->getAverageNodeCompTimeExcpetRoot()
3078 << std::endl;
3079 }
3080
3081 switch ( calcTerminationState )
3082 {
3084 {
3085 writeSubtreeInfo(source, calcState);
3086 // std::cout << "*** R." << source << ", calcState->getNSolved() = " << calcState->getNSolved() << std::endl;
3087 // BbParaNode *node = dynamic_cast<BbParaNode *>(bbParaSolverPool->getCurrentTask(source));
3088 // assert( (node->next) ); // should always has next. node->next == null should be processed in processTagCompletionOfCalculation
3089 // No: can be null, when a node is reassigned
3090 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3091
3092 assert( !paraNodePoolToRestart );
3093
3094 bbParaSolverPool->resetCountersInSolver(source, calcState->getNSolved(), calcState->getNSelfSplitNodesLeft(), paraNodePool);
3095 if( bbParaSolverPool->isSolverInCollectingMode(source) )
3096 {
3097 // reschedule collecting mode
3098 double tempTime = bbParaSolverPool->getSwichOutTime();
3099 bbParaSolverPool->switchOutCollectingMode();
3100 bbParaSolverPool->setSwichOutTime(tempTime);
3101 bbParaSolverPool->switchInCollectingMode(paraNodePool);
3102 }
3103 // delete node; // should not delete
3104 bbParaSolverPool->addTotalNodesSolved(calcState->getNSolved());
3105
3106 // std::cout << "Rank" << source
3107 // << ", lcts.best = " << lcts.externalGlobalBestDualBoundValue
3108 // << ", bound = " << paraInitiator->convertToExternalValue(calcState->getDualBoundValue())
3109 // << ", gap = " << std::setprecision(5) << paraInitiator->getGap(calcState->getDualBoundValue())*100 << "%" << std::endl;
3110 if( !EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, paraInitiator->getEpsilon() ) )
3111 {
3115 {
3116 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3117 {
3119 }
3120 else
3121 {
3123 }
3124 }
3125 }
3126
3127 if( !bbParaSolverPool->getSelfSplitSubtreeRootNodes(source) )
3128 {
3129 // dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, calcState->getNSolved(),paraNodePool);
3130 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(source, -1, paraNodePool); // already updated in above
3131 }
3132 else
3133 {
3134 bbParaSolverPool->deleteCurrentSubtreeRootNode(source);
3135 }
3136
3137 break;
3138 }
3140 {
3141 /** in this case the following two numbers should be different */
3142 /** # Total > # Solved */
3143 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3144 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNumOfNodesSolved(source)) );
3145 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3149 {
3151 {
3153 paraComm->send( NULL, 0, ParaBYTE, source, TagTerminateRequest )
3154 );
3155// std::cout << "TagTerminateRequest 3" << std::endl;
3158 {
3159 int token[2];
3160 token[0] = source;
3161 token[1] = -2;
3163 paraComm->send( token, 2, ParaINT, token[0], TagToken )
3164 );
3165 }
3166 }
3167 }
3168 break;
3169 }
3171 {
3172 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3174 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3178 {
3179 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) );
3180 writeSubtreeInfo(source, calcState);
3181 BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
3182 if( solvingNode->areNodesCollected() )
3183 {
3185 {
3187 << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
3188 }
3189 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3190 while( nodes )
3191 {
3192 BbParaNode *temp = nodes;
3193 nodes = nodes->next;
3194 temp->next = 0;
3195 paraNodePool->insert(temp);
3197 {
3198 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3200 << " S." << source
3201 << " p< "
3202 << bbParaInitiator->convertToExternalValue(
3203 temp->getDualBoundValue() )
3204 << " "
3205 << temp->toSimpleString();
3206 if( temp->getDiffSubproblem() )
3207 {
3209 << ", "
3210 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3211 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3212 }
3213 *osLogSolvingStatus << std::endl;
3214 }
3215 }
3216 if( calcState->getNSolved() > 1 ||
3217 ( calcState->getNSolved() >= 1 && calcState->getNSent() > 0 ) )
3218 {
3219 delete solvingNode;
3220 }
3221 else
3222 {
3223 paraNodePool->insert(solvingNode);
3224 }
3226#ifdef UG_WITH_ZLIB
3228 {
3230 }
3231#endif
3233// std::cout << "sendInterrruptRequest 7" << std::endl;
3234 }
3235 else
3236 {
3237 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3238 while( nodes )
3239 {
3240 BbParaNode *temp = nodes;
3241 nodes = nodes->next;
3242 temp->next = 0;
3243 paraNodePool->insert(temp);
3245 {
3246 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3248 << " S." << source
3249 << " p< "
3250 << bbParaInitiator->convertToExternalValue(
3251 temp->getDualBoundValue() )
3252 << " "
3253 << temp->toSimpleString();
3254 if( temp->getDiffSubproblem() )
3255 {
3257 << ", "
3258 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3259 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3260 }
3261 *osLogSolvingStatus << std::endl;
3262 }
3263 }
3264 paraNodePool->insert(solvingNode);
3266 {
3267 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3269 << " S." << source
3270 << " p< "
3271 << bbParaInitiator->convertToExternalValue(
3272 solvingNode->getDualBoundValue() )
3273 << " "
3274 << solvingNode->toSimpleString();
3275 if( solvingNode->getDiffSubproblem() )
3276 {
3278 << ", "
3279 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3280 << dynamic_cast<BbParaDiffSubproblem *>(solvingNode->getDiffSubproblem())->toStringStat();
3281 }
3282 *osLogSolvingStatus << std::endl;
3283 }
3284#ifdef UG_WITH_ZLIB
3286#endif
3287 }
3288 break;
3289 }
3290 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3291
3292 // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
3293 // BbParaNode *solvingNode = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool);
3295 {
3296 assert( !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool))->getAncestor() );
3297 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3298 while( nodes )
3299 {
3300 BbParaNode *temp = nodes;
3301 nodes = nodes->next;
3302 temp->next = 0;
3305 {
3306 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3308 << " S." << source
3309 << " rp< "
3310 << bbParaInitiator->convertToExternalValue(
3311 temp->getDualBoundValue() )
3312 << " "
3313 << temp->toSimpleString();
3314 if( temp->getDiffSubproblem() )
3315 {
3317 << ", "
3318 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3319 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3320 }
3321 *osLogSolvingStatus << std::endl;
3322 }
3323 }
3324 }
3325 else
3326 {
3327 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3328 while( nodes )
3329 {
3330 BbParaNode *temp = nodes;
3331 nodes = nodes->next;
3332 temp->next = 0;
3333 paraNodePool->insert(temp);
3335 {
3336 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3338 << " S." << source
3339 << " p< "
3340 << bbParaInitiator->convertToExternalValue(
3341 temp->getDualBoundValue() )
3342 << " "
3343 << temp->toSimpleString();
3344 if( temp->getDiffSubproblem() )
3345 {
3347 << ", "
3348 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3349 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3350 }
3351 *osLogSolvingStatus << std::endl;
3352 }
3353 }
3354 }
3355
3356 //
3357 // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
3358 // just use SolerState update
3359 //
3360 break;
3361 }
3363 {
3364 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3366 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3371 {
3372 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) );
3373 writeSubtreeInfo(source, calcState);
3374 BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
3375 if( solvingNode->areNodesCollected() )
3376 {
3378 {
3380 << " Nodes generated by S." << source << " from " << solvingNode->toSimpleString() << " are collected to LC." << std::endl;
3381 }
3382 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3383 while( nodes )
3384 {
3385 BbParaNode *temp = nodes;
3386 nodes = nodes->next;
3387 temp->next = 0;
3388 paraNodePool->insert(temp);
3389 }
3390 if( calcState->getNSolved() > 1 ||
3391 ( calcState->getNSolved() >= 1 && calcState->getNSent() > 0 ) )
3392 {
3393 delete solvingNode;
3394 }
3395 else
3396 {
3397 paraNodePool->insert(solvingNode);
3398 }
3400#ifdef UG_WITH_ZLIB
3405 {
3407 }
3408#endif
3410// std::cout << "sendInterrruptRequest 8" << std::endl;
3411 }
3412 else
3413 {
3414 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3415 while( nodes )
3416 {
3417 BbParaNode *temp = nodes;
3418 nodes = nodes->next;
3419 temp->next = 0;
3420 paraNodePool->insert(temp);
3422 {
3423 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3425 << " S." << source
3426 << " p< "
3427 << bbParaInitiator->convertToExternalValue(
3428 temp->getDualBoundValue() )
3429 << " "
3430 << temp->toSimpleString();
3431 if( temp->getDiffSubproblem() )
3432 {
3434 << ", "
3435 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3436 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3437 }
3438 *osLogSolvingStatus << std::endl;
3439 }
3440 }
3441#ifdef UG_WITH_ZLIB
3443#endif
3444 paraNodePool->insert(solvingNode);
3446 {
3447 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3449 << " S." << source
3450 << " p< "
3451 << bbParaInitiator->convertToExternalValue(
3452 solvingNode->getDualBoundValue() )
3453 << " "
3454 << solvingNode->toSimpleString();
3455 if( solvingNode->getDiffSubproblem() )
3456 {
3458 << ", "
3459 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3460 << dynamic_cast<BbParaDiffSubproblem *>(solvingNode->getDiffSubproblem())->toStringStat();
3461 }
3462 *osLogSolvingStatus << std::endl;
3463 }
3464 }
3465 break;
3466 }
3467 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3468 // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
3470 {
3472 {
3473 assert( !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool))->getAncestor() );
3474 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3475 while( nodes )
3476 {
3477 BbParaNode *temp = nodes;
3478 nodes = nodes->next;
3479 temp->next = 0;
3482 {
3483 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3485 << " S." << source
3486 << " rp< "
3487 << bbParaInitiator->convertToExternalValue(
3488 temp->getDualBoundValue() )
3489 << " "
3490 << temp->toSimpleString();
3491 if( temp->getDiffSubproblem() )
3492 {
3494 << ", "
3495 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3496 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3497 }
3498 *osLogSolvingStatus << std::endl;
3499 }
3500 }
3501 }
3502 }
3503 else
3504 {
3505 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3506 while( nodes )
3507 {
3508 BbParaNode *temp = nodes;
3509 nodes = nodes->next;
3510 temp->next = 0;
3511 paraNodePool->insert(temp);
3513 {
3514 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3516 << " S." << source
3517 << " p< "
3518 << bbParaInitiator->convertToExternalValue(
3519 temp->getDualBoundValue() )
3520 << " "
3521 << temp->toSimpleString();
3522 if( temp->getDiffSubproblem() )
3523 {
3525 << ", "
3526 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3527 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3528 }
3529 *osLogSolvingStatus << std::endl;
3530 }
3531 }
3532 }
3533 //
3534 // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
3535 // just use SolerState update
3536 //
3537 break;
3538 }
3540 {
3541 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addNumNodesSolved( (calcState->getNSolved() -
3543 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->addTotalNodesSolved(calcState->getNSolved());
3544 memoryLimitIsReached = true;
3548 {
3549 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) );
3550 writeSubtreeInfo(source, calcState);
3551 BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool));
3552 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3553 while( nodes )
3554 {
3555 BbParaNode *temp = nodes;
3556 nodes = nodes->next;
3557 temp->next = 0;
3558 paraNodePool->insert(temp);
3560 {
3561 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3563 << " S." << source
3564 << " p< "
3565 << bbParaInitiator->convertToExternalValue(
3566 temp->getDualBoundValue() )
3567 << " "
3568 << temp->toSimpleString();
3569 if( temp->getDiffSubproblem() )
3570 {
3572 << ", "
3573 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3574 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3575 }
3576 *osLogSolvingStatus << std::endl;
3577 }
3578 }
3579#ifdef UG_WITH_ZLIB
3581#endif
3582 paraNodePool->insert(solvingNode);
3584 {
3585 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3587 << " S." << source
3588 << " p< "
3589 << bbParaInitiator->convertToExternalValue(
3590 solvingNode->getDualBoundValue() )
3591 << " "
3592 << solvingNode->toSimpleString();
3593 if( solvingNode->getDiffSubproblem() )
3594 {
3596 << ", "
3597 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3598 << dynamic_cast<BbParaDiffSubproblem *>(solvingNode->getDiffSubproblem())->toStringStat();
3599 }
3600 *osLogSolvingStatus << std::endl;
3601 }
3603// std::cout << "sendInterrruptRequest 9" << std::endl;
3605 break;
3606 }
3607 assert( (!paraRacingSolverPool) || (!paraRacingSolverPool->isSolverActive(source) ) ); // RacingSolverPool is inactivated below
3608 // paraRacingSolverPool entry is inactivated, when it receives ParaSolverTerminationState message in below.
3610 {
3612 {
3613 assert( !(dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractCurrentNodeAndInactivate(source, paraNodePool))->getAncestor() );
3614 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3615 while( nodes )
3616 {
3617 BbParaNode *temp = nodes;
3618 nodes = nodes->next;
3619 temp->next = 0;
3622 {
3623 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3625 << " S." << source
3626 << " rp< "
3627 << bbParaInitiator->convertToExternalValue(
3628 temp->getDualBoundValue() )
3629 << " "
3630 << temp->toSimpleString();
3631 if( temp->getDiffSubproblem() )
3632 {
3634 << ", "
3635 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3636 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3637 }
3638 *osLogSolvingStatus << std::endl;
3639 }
3640 }
3641 }
3642 }
3643 else
3644 {
3645 BbParaNode *nodes = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->extractSelfSplitSubtreeRootNodes(source);
3646 while( nodes )
3647 {
3648 BbParaNode *temp = nodes;
3649 nodes = nodes->next;
3650 temp->next = 0;
3651 paraNodePool->insert(temp);
3653 {
3654 // BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3656 << " S." << source
3657 << " p< "
3658 << bbParaInitiator->convertToExternalValue(
3659 temp->getDualBoundValue() )
3660 << " "
3661 << temp->toSimpleString();
3662 if( temp->getDiffSubproblem() )
3663 {
3665 << ", "
3666 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges()
3667 << dynamic_cast<BbParaDiffSubproblem *>(temp->getDiffSubproblem())->toStringStat();
3668 }
3669 *osLogSolvingStatus << std::endl;
3670 }
3671 }
3672 }
3674// std::cout << "sendInterrruptRequest1 10" << std::endl;
3676 //
3677 // no update lcts.globalBestDualBoundValue and lcts.externalGlobalBestDualBoundValue
3678 // just use SolerState update
3679 //
3680 break;
3681 }
3682 default:
3683 THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
3684 }
3685
3686// if( calcState->getTerminationState() == CompTerminatedByTimeLimit )
3687// {
3688// hardTimeLimitIsReached = true;
3689// // std::cout << "####### Rank " << paraComm->getRank() << " solver terminated with timelimit in solver side. #######" << std::endl;
3690// // std::cout << "####### Final statistics may be messed up!" << std::endl;
3691// }
3692
3693 delete calcState;
3694
3695 return 0;
3696}
3697
3698int
3700 int source,
3701 int tag
3702 )
3703{
3704
3706
3708
3709 if( paraDetTimer )
3710 {
3711 if( paraDetTimer->getElapsedTime() < termState->getDeterministicTime() )
3712 {
3714 }
3715 assert( !paraRacingSolverPool );
3716 if( !paraSolverPool->isTerminateRequested(source) )
3717 {
3719 paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
3720 );
3721 }
3722 }
3723
3724 switch( termState->getInterruptedMode() )
3725 {
3726 case 2: /** checkpoint; This is normal termination */
3727 {
3728 /** in order to save termination status to check point file, keep this information to solver pool */
3729 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setTermState(source, termState);
3730 // don't delete termState! it is saved in paraSolverPool
3734 dynamic_cast<BbParaSolverTerminationState *>(termState)->getCalcTerminationState() != CompTerminatedByMemoryLimit )
3735 {
3736 if( paraNodePool->isEmpty() )
3737 {
3740 {
3741 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
3743 }
3744 }
3745 else
3746 {
3748 {
3750 }
3751 }
3752 }
3754 {
3756 }
3758 {
3759 memoryLimitIsReached = true;
3760 }
3761 break;
3762 }
3763 default: /** unexpected mode */
3764 THROW_LOGICAL_ERROR4("Unexpected termination state received from rank = ", source,
3765 ", interrupted mode = ", termState->getInterruptedMode());
3766 }
3767
3768 return 0;
3769}
3770
3771void
3773 )
3774{
3775 // output title line 1
3777 *osTabularSolvingStatus << std::setw(1) << " ";
3778 *osTabularSolvingStatus << std::setw(8) << std::right << " ";
3779 *osTabularSolvingStatus << std::setw(15) << std::right << " ";
3780 *osTabularSolvingStatus << std::setw(12) << std::right << "Nodes";
3781 *osTabularSolvingStatus << std::setw(10) << std::right << "Active";
3782 *osTabularSolvingStatus << std::setw(17) << std::right << " ";
3783 *osTabularSolvingStatus << std::setw(17) << std::right << " ";
3784 *osTabularSolvingStatus << std::setw(10) << std::right << " ";
3785 *osTabularSolvingStatus << std::endl;
3786 // output title line 2
3788 *osTabularSolvingStatus << std::setw(1) << " ";
3789 *osTabularSolvingStatus << std::setw(8) << std::right << "Time";
3790 *osTabularSolvingStatus << std::setw(15) << std::right << "Nodes";
3791 *osTabularSolvingStatus << std::setw(12) << std::right << "Left";
3792 *osTabularSolvingStatus << std::setw(10) << std::right << "Solvers";
3793 *osTabularSolvingStatus << std::setw(17) << std::right << "Best Integer";
3794 *osTabularSolvingStatus << std::setw(17) << std::right << "Best Node";
3795 *osTabularSolvingStatus << std::setw(11) << std::right << "Gap";
3796 *osTabularSolvingStatus << std::setw(17) << std::right << "Best Node(S)";
3797 *osTabularSolvingStatus << std::setw(11) << std::right << "Gap(S)";
3798 *osTabularSolvingStatus << std::endl;
3799
3800 isHeaderPrinted = true;
3801}
3802
3803void
3805 char incumbent
3806 )
3807{
3808
3809 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
3810
3812 *osTabularSolvingStatus << std::setw(1) << incumbent;
3813 *osTabularSolvingStatus << std::setw(8) << std::right << std::setprecision(0) << std::fixed << paraTimer->getElapsedTime();
3814 if( // !restarted &&
3817 && !racingWinnerParams )
3818 {
3819 /** racing ramp-up stage now */
3821 {
3822 *osTabularSolvingStatus << std::setw(15) << std::right << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver();
3823
3824 if( paraNodePool->getNumOfNodes() > 0 )
3825 {
3826 *osTabularSolvingStatus << std::setw(12) << std::right
3827 << (dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver()
3829 }
3830 else
3831 {
3832 *osTabularSolvingStatus << std::setw(12) << std::right << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver();
3833 }
3834
3835 *osTabularSolvingStatus << std::setw(10) << std::right << paraRacingSolverPool->getNumActiveSolvers();
3836 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3837 {
3838 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3839 bbParaInitiator->convertToExternalValue(
3841 }
3842 else
3843 {
3844 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3845 }
3846 if( dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver() == 0 )
3847 {
3849 {
3850 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3852 }
3853 else
3854 {
3855 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3856 }
3857 }
3858 else
3859 {
3861 {
3862 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3863 }
3864 else
3865 {
3866 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3868 }
3869 }
3870 }
3871 else // One of ParaSolvers terminates in racing stage
3872 {
3873 if( nSolvedRacingTermination > 0 )
3874 {
3875 *osTabularSolvingStatus << std::setw(15) << std::right << nSolvedRacingTermination;
3876 *osTabularSolvingStatus << std::setw(12) << std::right << 0;
3877 *osTabularSolvingStatus << std::setw(10) << std::right << 0;
3878 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3879 {
3880 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3881 bbParaInitiator->convertToExternalValue(
3883 }
3884 else
3885 {
3886 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3887 }
3888 // *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3889 if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
3890 {
3891 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3892 }
3893 else
3894 {
3895 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3897 }
3898 }
3899 else // should be interrupted
3900 {
3901 *osTabularSolvingStatus << std::setw(15) << std::right << nSolvedInInterruptedRacingSolvers;
3902 *osTabularSolvingStatus << std::setw(12) << std::right << nTasksLeftInInterruptedRacingSolvers;
3903 *osTabularSolvingStatus << std::setw(10) << std::right << 0;
3904 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3905 {
3906 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3907 bbParaInitiator->convertToExternalValue(
3909 }
3910 else
3911 {
3912 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3913 }
3914 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3916 }
3917 }
3919 (!bbParaInitiator->getGlobalBestIncumbentSolution() ||
3922 ) )
3923 {
3924 *osTabularSolvingStatus << std::setw(11) << std::right << " -";
3925 }
3926 else
3927 {
3928 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
3929 bbParaInitiator->getGap(lcts.globalBestDualBoundValue) * 100 << "%";
3930 }
3931 }
3932 else
3933 {
3934 *osTabularSolvingStatus << std::setw(15) << std::right << dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesSolvedInSolvers();
3936 {
3937 *osTabularSolvingStatus << std::setw(12) << std::right << ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
3940 }
3942 {
3943 *osTabularSolvingStatus << std::setw(12) << std::right << ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
3946 }
3947 else
3948 {
3949 *osTabularSolvingStatus << std::setw(12) << std::right << ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers()
3951 }
3952 *osTabularSolvingStatus << std::setw(10) << std::right << paraSolverPool->getNumActiveSolvers();
3953 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
3954 {
3955 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3956 bbParaInitiator->convertToExternalValue(
3958 }
3959 else
3960 {
3961 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3962 }
3963
3965 {
3966 // lcts.globalBestDualBoundValue = std::min(std::min( paraNodePool->getBestDualBoundValue(), paraNodePoolForBuffering->getBestDualBoundValue() ),
3967 // dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() );
3968 // lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue( lcts.globalBestDualBoundValue );
3969
3970 // *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) << lcts.externalGlobalBestDualBoundValue;
3971 if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
3972 {
3973 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
3974 }
3975 else
3976 {
3977 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
3979 }
3981 {
3982 *osTabularSolvingStatus << std::setw(11) << std::right << " -";
3983 }
3984 else
3985 {
3986 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
3987 bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
3988 }
3989 }
3990 else
3991 {
3995 || paraNodePool->getNumOfNodes() == 0 )
3996 ) )
3997 {
3998 if( (!givenGapIsReached) && bbParaInitiator->getGlobalBestIncumbentSolution() )
3999 {
4001 /*
4002 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4003 paraInitiator->convertToExternalValue(
4004 paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue());
4005 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4006 paraInitiator->getGap( paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue() ) * 100 << "%";
4007 */
4008 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4010 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4011 bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
4012 }
4013 else
4014 {
4015 if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
4016 {
4017 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4018 }
4019 else
4020 {
4021 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4023 }
4025 {
4026 *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4027 }
4028 else
4029 {
4030 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4031 bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
4032 }
4033 }
4034 // *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4035 }
4036 else
4037 {
4038 //*osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4039 // lcts.externalGlobalBestDualBoundValue;
4040 if( EPSEQ( lcts.globalBestDualBoundValue,-DBL_MAX, bbParaInitiator->getEpsilon() ))
4041 {
4042 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4043 }
4044 else
4045 {
4046 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4048 }
4050 {
4051 double globalBestDualBound = paraNodeToKeepCheckpointFileNodes->getBestDualBoundValue();
4052 if( bbParaInitiator->getGap( globalBestDualBound ) > displayInfOverThisValue )
4053 {
4054 *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4055 }
4056 else
4057 {
4058 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4059 bbParaInitiator->getGap( globalBestDualBound ) * 100 << "%";
4060 }
4061 }
4062 else
4063 {
4065 {
4066 *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4067 }
4068 else
4069 {
4070 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4071 bbParaInitiator->getGap( lcts.globalBestDualBoundValue ) * 100 << "%";
4072 }
4073 }
4074 }
4075 /*
4076 if( !paraNodeToKeepCheckpointFileNodes &&
4077 ( !paraInitiator->getGlobalBestIncumbentSolution() ||
4078 paraInitiator->getGap(lcts.globalBestDualBoundValue) > displayInfOverThisValue ||
4079 ( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() && paraSolverPool->getNumActiveSolvers() == 0 && paraNodePool->getNumOfNodes() == 0 )
4080 ) )
4081 {
4082 *osTabularSolvingStatus << std::setw(10) << std::right << "-";
4083 }
4084 else
4085 {
4086 *osTabularSolvingStatus << std::setw(9) << std::right << std::setprecision(2) <<
4087 paraInitiator->getGap(lcts.globalBestDualBoundValue) * 100 << "%";
4088 }
4089 */
4090 }
4091
4093 {
4094 if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() >= -1e+10 )
4095 {
4096 *osTabularSolvingStatus << std::setw(17) << std::right << std::setprecision(4) <<
4097 bbParaInitiator->convertToExternalValue( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() );
4098 }
4099 else
4100 {
4101 *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4102 }
4104 {
4105 *osTabularSolvingStatus << std::setw(11) << std::right << " -";
4106 }
4107 else
4108 {
4109 *osTabularSolvingStatus << std::setw(10) << std::right << std::setprecision(2) <<
4110 bbParaInitiator->getGap( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue() ) * 100 << "%";
4111 }
4112 }
4113 else
4114 {
4115 // *osTabularSolvingStatus << std::setw(17) << std::right << "-";
4116 }
4117
4118 }
4119 *osTabularSolvingStatus << std::endl;
4120}
4121
4122void
4124 )
4125{
4126
4128 {
4129 outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
4130 }
4131
4132 int source;
4133 int tag;
4134
4135 for(;;)
4136 {
4138 {
4139 if( paraNodePool->isEmpty() ) // paraNodePool has to be checked
4140 // because node cannot send in a parameter settings
4141 {
4143 {
4144 /*
4145 if( !interruptedFromControlTerminal
4146 && !computationIsInterrupted
4147 && !hardTimeLimitIsReached
4148 && paraInitiator->getGlobalBestIncumbentSolution() )
4149 {
4150 lcts.globalBestDualBoundValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
4151 lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
4152 }
4153 */
4154 /* No active solver exists */
4157 /*
4158 if( !racingTermination )
4159 {
4160 lcts.globalBestDualBoundValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
4161 lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
4162 }
4163 */
4164 }
4165 else // runningPhase == TerminationPhase
4166 {
4167 if( ( paraRacingSolverPool &&
4168 // paraSolverPool->getNumInactiveSolvers() == (paraRacingSolverPool->getNumActiveSolvers() + nTerminated ) ) ||
4169 // paraSolverPool->getNumInactiveSolvers() == nTerminated )
4172 {
4173 break;
4174 }
4175 }
4176 }
4177 else
4178 {
4180 {
4182 {
4185#ifdef UG_WITH_ZLIB
4187#endif
4188 /* No active solver exists */
4191 }
4192 else // runningPhase == TerminationPhase
4193 {
4194 // if( paraSolverPool->getNumInactiveSolvers() == nTerminated )
4196 {
4197 break;
4198 }
4199 }
4200 }
4201 }
4205 {
4206 break;
4207 }
4208 }
4209
4213 )
4214 {
4216 {
4219#ifdef UG_WITH_ZLIB
4221#endif
4222 /* No active solver exists */
4224 std::cout << *paraInitiator << "### REACHED TO THE SPECIFIED NUMBER OF IDLER SOLVERS, then EXIT ###" << std::endl;
4225 exit(1); // try to terminate all solvers, but do not have to wait until all solvers have terminated.
4226 // Basically, this procedure is to kill the ug[*,*].
4227 } // if already in TerminaitonPhase, just keep on running.
4228 }
4229
4231 {
4233 {
4235 {
4237 break;
4238 }
4239 if( givenGapIsReached )
4240 break;
4241 // std::cout << "ElapsedTime = " << paraTimer->getElapsedTime() << ", runningPhase = " << static_cast<int>(runningPhase) << std::endl;
4245 {
4246 break;
4247 }
4248 }
4249 else
4250 {
4251 break;
4252 }
4253 }
4254
4258 && paraNodePool->getNumOfNodes() <= 1
4260 {
4261 /*
4262 * special timining problem
4263 *
4264 * 1113.58 S.4 I.SOL 0
4265 * 1113.58 S.3 is the racing winner! Selected strategy 2.
4266 * 1113.58 S.4 >(TERMINATED_IN_RACING_STAGE)
4267 *
4268 */
4269 break;
4270 }
4271
4272 /*******************************************
4273 * waiting for any message form anywhere *
4274 *******************************************/
4275 double inIdleTime = paraTimer->getElapsedTime();
4276 (void)paraComm->probe(&source, &tag);
4277 lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
4278 if( messageHandler[tag] )
4279 {
4280 int status = (this->*messageHandler[tag])(source, tag);
4281 if( status )
4282 {
4283 std::ostringstream s;
4284 s << "[ERROR RETURN form Message Hander]:" << __FILE__ << "] func = "
4285 << __func__ << ", line = " << __LINE__ << " - "
4286 << "process tag = " << tag << std::endl;
4287 abort();
4288 }
4289 }
4290 else
4291 {
4292 THROW_LOGICAL_ERROR3( "No message hander for ", tag, " is not registered" );
4293 }
4294
4295#ifdef UG_WITH_UGS
4296 if( commUgs ) checkAndReadIncumbent();
4297#endif
4298
4299 /** completion message may delay */
4301 {
4302 delete paraRacingSolverPool;
4304 if( racingTermination )
4305 {
4306 break;
4307 }
4308 }
4309
4310 /** output tabular solving status */
4321 {
4324 {
4326 {
4328 }
4329 else
4330 {
4332 }
4333 }
4334 else
4335 {
4337 }
4338 }
4339
4340 switch ( runningPhase )
4341 {
4342 case RampUpPhase:
4343 {
4345 selfSplitFinisedSolvers->size() == (unsigned)(paraComm->getSize() - 1) ) // all solvers have finished self-split
4346 {
4353 {
4355 }
4356 break;
4357 }
4358 if( ( racingTermination && paraNodePool->isEmpty() ) ||
4361 {
4363// std::cout << "sendInterrruptRequest1 11" << std::endl;
4365 }
4366 else
4367 {
4369 {
4370 // without consideration of keeping nodes in checkpoint file
4371 double globalBestDualBoundValueLocal =
4372 std::max (
4373 std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
4376 {
4377 if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() &&
4378 ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
4382 paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
4383 {
4386 }
4387 }
4388 else
4389 {
4391 {
4392 if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() &&
4393 ( (signed)paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
4395 ( (signed)paraNodePool->getNumOfNodes()
4397 paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
4398 {
4401 }
4402 }
4403 }
4404 }
4405 else
4406 {
4408 {
4409 // maybe some solver hard to interrupt in a large scale execution
4410 // without consideration of keeping nodes in checkpoint file
4411 double globalBestDualBoundValueLocal =
4412 std::max (
4413 std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
4415 if( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->isActive() &&
4418 paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) )
4419 {
4422 }
4423 }
4424 }
4426 }
4427 break;
4428 }
4429 case NormalRunningPhase:
4430 {
4431 if( ( racingTermination && paraNodePool->isEmpty() )||
4438 {
4439 if( !paraSolverPool->isInterruptRequested(source) )
4440 {
4442// std::cout << "sendInterrruptRequest1 12" << std::endl;
4443 }
4445 }
4446 else
4447 {
4449 }
4452 {
4457 {
4460 }
4461 }
4462
4463#ifdef UG_WITH_ZLIB
4465 {
4468 {
4469 if( starvingTime < 0.0 )
4470 {
4472 }
4473 }
4474 else
4475 {
4476 starvingTime = -1.0;
4477 }
4478 // std::cout << "active solvers:" << paraSolverPool->getNumActiveSolvers() << std::endl;
4479 if( starvingTime > 0 &&
4484 {
4485 hugeImbalance = false;
4487 }
4488 }
4489#endif
4490
4492 {
4495 {
4496 if( hugeImbalanceTime < 0.0 )
4497 {
4500 }
4501 }
4502 else
4503 {
4505 hugeImbalanceTime = -1.0;
4506 }
4507 // std::cout << "active solvers:" << paraSolverPool->getNumActiveSolvers() << std::endl;
4508 if( hugeImbalanceTime > 0 &&
4512 {
4513 hugeImbalance = true;
4515 {
4517 }
4518 // reschedule collecting mode
4519 double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
4520 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
4521 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
4522 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
4523 }
4524 if( hugeImbalance &&
4526 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers() < paraSolverPool->getNumActiveSolvers() * 5 ||
4528 {
4529 hugeImbalance = false;
4530 hugeImbalanceTime = -1.0;
4532 {
4534 }
4536 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(-1.0); // restart collecting
4537 }
4538 }
4539
4540 break;
4541 }
4542 case TerminationPhase:
4543 {
4544 break;
4545 }
4546 default:
4547 {
4548 THROW_LOGICAL_ERROR2( "Undefined running phase: ", static_cast<int>(runningPhase) );
4549 }
4550 }
4551#ifdef UG_WITH_ZLIB
4555 {
4556 if( !( interruptIsRequested &&
4558 {
4561 }
4562 }
4563#endif
4564 }
4565}
4566
4567#ifdef UG_WITH_ZLIB
4568void
4570 )
4571{
4573 /** send interrupt request */
4574 int stayAlive = 0; // exit!
4575 for( int i = 1; i < paraComm->getSize(); i++ )
4576 {
4578 paraComm->send( &stayAlive, 1, ParaINT, i, TagInterruptRequest )
4579 );
4580 }
4581
4582 /** the pupose of the updateCheckpoitFiles is two
4583 * 1. Can be killed during restaart, for example, in a case that a solver cannot be intterrupted so long time
4584 * 2. To update initial dual bound values
4585 */
4586 // updateCheckpointFiles();
4587
4589 {
4591 << " Interrupt all solvers to restart"
4592 << std::endl;
4594 {
4596 "Interrupt all solvers to restart after "
4597 << paraTimer->getElapsedTime() << " seconds." << std::endl;
4598 }
4599 }
4600
4601 exit(1); // Terminate LoadCoordinator. Restart did not work well over 10,000 solvers.
4602
4604
4605 /** for a timing issue, paraNodePool may not be empty. paraNodes in the pool should be just recived,
4606 * because paraSolverPool was empty. Then, no check for the ancestors.
4607 */
4608 while( !paraNodePool->isEmpty() )
4609 {
4611 delete node;
4612 }
4614 {
4616 delete node;
4617 }
4618
4619 /*******************************************
4620 * waiting for any message form anywhere *
4621 *******************************************/
4622 for(;;)
4623 {
4624 int source;
4625 int tag;
4626 double inIdleTime = paraTimer->getElapsedTime();
4627 (void)paraComm->probe(&source, &tag);
4628 lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
4629 if( messageHandler[tag] )
4630 {
4631 int status = (this->*messageHandler[tag])(source, tag);
4632 if( status )
4633 {
4634 std::ostringstream s;
4635 s << "[ERROR RETURN form Message Hander]:" << __FILE__ << "] func = "
4636 << __func__ << ", line = " << __LINE__ << " - "
4637 << "process tag = " << tag << std::endl;
4638 abort();
4639 }
4640 }
4641 else
4642 {
4643 THROW_LOGICAL_ERROR3( "No message hander for ", tag, " is not registered" );
4644 }
4645
4646#ifdef UG_WITH_UGS
4647 if( commUgs ) checkAndReadIncumbent();
4648#endif
4649
4651 {
4652 break;
4653 }
4654
4655 }
4656
4657 if( !paraNodePool->isEmpty() )
4658 {
4659 std::cout << *paraInitiator << "Logical error occurred during restart in ramp-down phase." << std::endl;
4660 std::cout << *paraInitiator << "You can restart from the chakepoint file." << std::endl;
4661 // exit(1);
4662 abort();
4663 }
4664
4665 while( !paraNodePoolToRestart->isEmpty() )
4666 {
4667 BbParaNode *node = dynamic_cast<BbParaNode *>(paraNodePoolToRestart->extractNode());
4669 paraNodePool->insert(node);
4670 }
4671
4672 delete paraNodePoolToRestart;
4674
4676 /** initialize paraSolerPool */
4677 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->reinitToRestart();
4678
4679 for( int i = 1; i < paraComm->getSize(); i++ )
4680 {
4682 paraComm->send( NULL, 0, ParaBYTE, i, TagRestart )
4683 );
4684 }
4685
4687 {
4689 << " Restart"
4690 << std::endl;
4692 {
4694 "Restart after "
4695 << paraTimer->getElapsedTime() << " seconds." << std::endl;
4696 }
4697 }
4698
4700}
4701#endif
4702
4703bool
4705 )
4706{
4712 ( !restarted &&
4713 // paraParamSet->getBoolParamValue(RacingStatBranching) &&
4717 )
4718 )
4719 )
4720 {
4721 return false;
4722 }
4723
4724 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
4725
4726 bool sentNode = false;
4728 {
4729 BbParaNode *paraNode = 0;
4730 while( !paraNodePool->isEmpty() )
4731 {
4733 {
4734 if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4735 {
4736 paraNode = paraNodePool->extractNodeRandomly();
4737 }
4738 else
4739 {
4740 paraNode = paraNodePool->extractNode();
4741 }
4742 }
4743 else
4744 {
4745 paraNode = paraNodePool->extractNode();
4746 }
4747 if( !paraNode ) break;
4748 assert( !paraNode->getMergeNodeInfo() ||
4749 ( paraNode->getMergeNodeInfo() &&
4751 paraNode->getMergeNodeInfo()->mergedTo == 0 ) );
4752
4754 ( ( !paraNode->getMergeNodeInfo() ) ||
4755 ( paraNode->getMergeNodeInfo() &&
4756 paraNode->getMergeNodeInfo()->nMergedNodes <= 0 ) ) )
4757 {
4758 assert( !paraNode->getMergeNodeInfo() || ( paraNode->getMergeNodeInfo() && paraNode->getMergeNodeInfo()->nMergedNodes == 0 ) );
4759 if( paraNode->getMergeNodeInfo() )
4760 {
4761 BbParaMergeNodeInfo *mNode = paraNode->getMergeNodeInfo();
4762 if( mNode->origDiffSubproblem )
4763 {
4764 paraNode->setDiffSubproblem(mNode->origDiffSubproblem);
4765 delete mNode->mergedDiffSubproblem;
4766 mNode->mergedDiffSubproblem = 0;
4767 mNode->origDiffSubproblem = 0;
4768 }
4769 paraNode->setMergeNodeInfo(0);
4770 paraNode->setMergingStatus(-1);
4771 assert(nodesMerger);
4773 }
4775 /*
4776 if( logSolvingStatusFlag )
4777 {
4778 *osLogSolvingStatus << paraTimer->getElapsedTime()
4779 << " node saved to the buffer. Dual bound:"
4780 << paraInitiator->convertToExternalValue( paraNode->getDualBoundValue() ) << std::endl;
4781 }
4782 */
4783 paraNode = 0;
4784
4785 continue;
4786 }
4787
4788 if( ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
4789 ( paraNode->getDualBoundValue() < bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() ||
4790 ( bbParaInitiator->isObjIntegral() &&
4791 static_cast<int>(ceil( paraNode->getDualBoundValue() ) )
4792 < static_cast<int>(bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() + MINEPSILON ) )
4793 ) ) ||
4794 !( bbParaInitiator->getGlobalBestIncumbentSolution() ) )
4795 {
4796 if( bbParaInitiator->getAbsgap(paraNode->getDualBoundValue() ) > bbParaInitiator->getAbsgapValue() ||
4797 bbParaInitiator->getGap(paraNode->getDualBoundValue()) > bbParaInitiator->getGapValue() )
4798 {
4799 break;
4800 }
4801 else
4802 {
4803#ifdef UG_DEBUG_SOLUTION
4804 if( paraNode->getDiffSubproblem() && paraNode->getDiffSubproblem()->isOptimalSolIncluded() )
4805 {
4806 throw "Optimal solution going to be killed.";
4807 }
4808#endif
4809 delete paraNode;
4810 paraNode = 0;
4813 {
4814 if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4815 {
4816 nNormalSelection = 0;
4817 }
4818 else
4819 {
4821 }
4822 }
4823 /*
4824 std::cout << "dual bound = " << paraNode->getDualBoundValue() << std::endl;
4825 std::cout << "agap(dual bound) = " << paraInitiator->getAbsgap(paraNode->getDualBoundValue())
4826 << ", agap = " << paraInitiator->getAbsgapValue() << std::endl;
4827 std::cout << "gap(dual bound) = " << paraInitiator->getGap(paraNode->getDualBoundValue())
4828 << ", gap = " << paraInitiator->getGapValue() << std::endl;
4829 break;
4830 */
4831 }
4832 }
4833 else
4834 {
4835#ifdef UG_DEBUG_SOLUTION
4836 if( paraNode->getDiffSubproblem() && paraNode->getDiffSubproblem()->isOptimalSolIncluded() )
4837 {
4838 throw "Optimal solution going to be killed.";
4839 }
4840#endif
4841 delete paraNode;
4842 paraNode = 0;
4844 }
4845 }
4846
4847 if( paraNode )
4848 {
4850 {
4851 if( nNormalSelection > static_cast<int>( 1.0 / paraParams->getRealParamValue(RandomNodeSelectionRatio) ) )
4852 {
4853 nNormalSelection = 0;
4854 }
4855 else
4856 {
4858 }
4859 }
4860
4861 if( paraNode->getMergeNodeInfo() && paraNode->getMergeNodeInfo()->nMergedNodes == 0 )
4862 {
4863 BbParaMergeNodeInfo *mNode = paraNode->getMergeNodeInfo();
4864 paraNode->setDiffSubproblem(mNode->origDiffSubproblem);
4865 paraNode->setMergeNodeInfo(0);
4866 paraNode->setMergingStatus(-1);
4867 delete mNode->mergedDiffSubproblem;
4868 mNode->mergedDiffSubproblem = 0;
4869 mNode->origDiffSubproblem = 0;
4870 assert(nodesMerger);
4872 }
4874 paraNode->isSameParetntTaskSubtaskIdAs( TaskId() ) && // if parent is the root node
4875 paraNode->getDiffSubproblem() // paraNode deos not root
4876 )
4877 {
4878 bbParaInitiator->setInitialStatOnDiffSubproblem(
4880 dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem()));
4881 }
4882 // without consideration of keeping nodes in checkpoint file
4884 double globalBestDualBoundValueLocal =
4885 std::max (
4886 std::min( bbParaSolverPool->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
4888 int destination = bbParaSolverPool->activateSolver(paraNode,
4890 paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains );
4891 if( destination < 0 )
4892 {
4893 /** cannot activate */
4894 paraNodePool->insert(paraNode);
4895 return sentNode;
4896 }
4897 else
4898 {
4899 lcts.nSent++;
4900 writeTransferLog(destination);
4901 sentNode = true;
4902 if( runningPhase == RampUpPhase &&
4905 // paraSolverPool->getNumActiveSolvers() < paraSolverPool->getNSolvers()/2
4909 )
4910 {
4911 int nCollect = -1;
4913 paraComm->send( &nCollect, 1, ParaINT, destination, TagCollectAllNodes )
4914 );
4915 }
4917 {
4919 << " S." << destination << " < "
4920 << bbParaInitiator->convertToExternalValue(
4921 paraNode->getDualBoundValue() );
4922 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
4923 {
4924 if( bbParaInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
4925 {
4926 *osLogSolvingStatus << " ( Inf )";
4927 }
4928 else
4929 {
4930 *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
4931 }
4932 }
4937 {
4938 *osLogSolvingStatus << " L";
4939 }
4940 if( paraNode->getMergeNodeInfo() )
4941 {
4942 *osLogSolvingStatus << " M(" << paraNode->getMergeNodeInfo()->nMergedNodes + 1 << ")";
4943 if( paraNode->getMergeNodeInfo()->nMergedNodes < 1 )
4944 {
4945 std::cout << *paraInitiator << "node id = " << (paraNode->getTaskId()).toString() << std::endl;
4946 abort();
4947 }
4948 }
4949 if( paraNode->getDiffSubproblem() )
4950 {
4951 *osLogSolvingStatus << " " << paraNode->toSimpleString()
4952 << ", "
4953 // << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->getNBoundChanges();
4954 << dynamic_cast<BbParaDiffSubproblem *>(paraNode->getDiffSubproblem())->toStringStat();
4955 }
4956 // for debug
4957 // *osLogSolvingStatus << " " << paraNode->toSimpleString();
4958 *osLogSolvingStatus << std::endl;
4959 }
4960#ifdef _DEBUG_LB
4961 std::cout << paraTimer->getElapsedTime()
4962 << " S." << destination << " < "
4963 << paraInitiator->convertToExternalValue(
4964 paraNode->getDualBoundValue() );
4965 if( paraInitiator->getGlobalBestIncumbentSolution() )
4966 {
4967 if( paraInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
4968 {
4969 std::cout << " ( Inf )";
4970 }
4971 else
4972 {
4973 std::cout << " ( " << paraInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
4974 }
4975 }
4980 {
4981 std::cout << " L";
4982 }
4983 std::cout << std::endl;
4984#endif
4985 }
4986 }
4987 else
4988 {
4989 break;
4990 }
4991 }
4992 return sentNode;
4993}
4994
4995#ifdef UG_WITH_ZLIB
4996void
4998 )
4999{
5000 time_t timer;
5001 char timeStr[30];
5002
5004 {
5005 return; // Interrupting all solvers;
5006 }
5007
5009 {
5010 return; // Collecting nodes.
5011 }
5012
5014 {
5015 return;
5016 }
5017
5018 /** get checkpoint time */
5019 time(&timer);
5020 /** make checkpoint time string */
5021#ifdef _MSC_VER
5022 int bufsize = 256;
5023 ctime_s(timeStr, bufsize, &timer);
5024#else
5025 ctime_r(&timer, timeStr);
5026#endif
5027 for( int i = 0; timeStr[i] != '\0' && i < 26; i++ )
5028 {
5029 if( timeStr[i] == ' ') timeStr[i] = '_';
5030 if( timeStr[i] == '\n' ) timeStr[i] = '\0';
5031 }
5032 char *newCheckpointTimeStr = &timeStr[4]; // remove a day of the week
5033 // std::cout << "lstCheckpointTimeStr = " << lastCheckpointTimeStr << std::endl;
5034 // std::cout << "newCheckpointTimeStr = " << newCheckpointTimeStr << std::endl;
5035 if( strcmp(newCheckpointTimeStr,lastCheckpointTimeStr) == 0 )
5036 {
5037 int l = strlen(newCheckpointTimeStr);
5038 newCheckpointTimeStr[l] = 'a';
5039 newCheckpointTimeStr[l+1] = '\0';
5040 }
5041
5042 /** save nodes information */
5043 char nodesFileName[MaxStrLen];
5044 snprintf(nodesFileName, MaxStrLen, "%s%s_%s_nodes_LC%d.gz",
5046 paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr, paraComm->getRank());
5047 gzstream::ogzstream checkpointNodesStream;
5048 checkpointNodesStream.open(nodesFileName, std::ios::out | std::ios::binary);
5049 if( !checkpointNodesStream )
5050 {
5051 std::cout << *paraInitiator << "Checkpoint file for ParaNodes cannot open. file name = " << nodesFileName << std::endl;
5052 exit(1);
5053 }
5054 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->updateDualBoundsForSavingNodes();
5056 int n = 0;
5058 {
5060 }
5061 n += dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->writeParaNodesToCheckpointFile(checkpointNodesStream);
5062 n += paraNodePool->writeBbParaNodesToCheckpointFile(checkpointNodesStream);
5064 {
5065 int nUnprocessedNodes = unprocessedParaNodes->writeBbParaNodesToCheckpointFile(checkpointNodesStream);
5068 {
5069 for(int i = n;
5072 i++ )
5073 {
5074 BbParaNode *tempParaNode = unprocessedParaNodes->extractNode();
5075 paraNodePool->insert(tempParaNode);
5076 }
5077 }
5078 n += nUnprocessedNodes;
5079 }
5080 checkpointNodesStream.close();
5082 {
5084 << " Checkpoint: " << n << " ParaNodes were saved" << std::endl;
5085 }
5086#ifdef _DEBUG_LB
5087 std::cout << paraTimer->getElapsedTime()
5088 << " Checkpoint: " << n << " ParaNodes were saved" << std::endl;
5089#endif
5090
5092 {
5094 "Storing check-point data after " <<
5095 paraTimer->getElapsedTime() << " seconds. " <<
5096 n << " nodes were saved." << std::endl;
5097 }
5098
5099 /** save incumbent solution */
5100 char solutionFileName[MaxStrLen];
5101 if( paraComm->getRank() == 0 )
5102 {
5103 snprintf(solutionFileName, MaxStrLen, "%s%s_%s_solution.gz",
5105 paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr);
5106 paraInitiator->writeCheckpointSolution(std::string(solutionFileName));
5107 }
5108
5109 /** save Solver statistics */
5110 char solverStatisticsFileName[MaxStrLen];
5111 snprintf(solverStatisticsFileName, MaxStrLen, "%s%s_%s_solverStatistics_LC%d.gz",
5113 paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr, paraComm->getRank());
5114 gzstream::ogzstream checkpointSolverStatisticsStream;
5115 checkpointSolverStatisticsStream.open(solverStatisticsFileName, std::ios::out | std::ios::binary);
5116 if( !checkpointSolverStatisticsStream )
5117 {
5118 std::cout << *paraInitiator << "Checkpoint file for SolverStatistics cannot open. file name = " << solverStatisticsFileName << std::endl;
5119 exit(1);
5120 }
5121 int nSolverInfo = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->writeSolverStatisticsToCheckpointFile(checkpointSolverStatisticsStream);
5122 checkpointSolverStatisticsStream.close();
5123
5124 /** save LoadCoordinator statistics */
5125 char loadCoordinatorStatisticsFileName[MaxStrLen];
5126 snprintf(loadCoordinatorStatisticsFileName, MaxStrLen, "%s%s_%s_loadCoordinatorStatistics_LC%d.gz",
5128 paraInitiator->getParaInstance()->getProbName(), newCheckpointTimeStr, paraComm->getRank());
5129 gzstream::ogzstream loadCoordinatorStatisticsStream;
5130 loadCoordinatorStatisticsStream.open(loadCoordinatorStatisticsFileName, std::ios::out | std::ios::binary);
5131 if( !loadCoordinatorStatisticsStream )
5132 {
5133 std::cout << *paraInitiator << "Checkpoint file for SolverStatistics cannot open. file name = " << loadCoordinatorStatisticsFileName << std::endl;
5134 exit(1);
5135 }
5136 // double globalBestDualBoundValue =
5137 // std::max (
5138 // std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
5139 // lcts.globalBestDualBoundValue );
5140 // double externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(globalBestDualBoundValue);
5141 writeLoadCoordinatorStatisticsToCheckpointFile(loadCoordinatorStatisticsStream, nSolverInfo,
5143 loadCoordinatorStatisticsStream.close();
5144
5145 if( lastCheckpointTimeStr[0] == ' ' )
5146 {
5147 /** the first time for checkpointing */
5148 if( racingWinnerParams )
5149 {
5150 /** save racing winner params */
5151 char racingWinnerParamsName[MaxStrLen];
5152 snprintf(racingWinnerParamsName, MaxStrLen, "%s%s_racing_winner_params.gz",
5155 gzstream::ogzstream racingWinnerParamsStream;
5156 racingWinnerParamsStream.open(racingWinnerParamsName, std::ios::out | std::ios::binary);
5157 if( !racingWinnerParamsStream )
5158 {
5159 std::cout << *paraInitiator << "Racing winner parameter file cannot open. file name = " << racingWinnerParamsName << std::endl;
5160 exit(1);
5161 }
5162 racingWinnerParams->write(racingWinnerParamsStream);
5163 racingWinnerParamsStream.close();
5164 }
5165 }
5166 else
5167 {
5168 /** remove old check point files */
5169 snprintf(nodesFileName, MaxStrLen, "%s%s_%s_nodes_LC%d.gz",
5172 if( paraComm->getRank() == 0 )
5173 {
5174 snprintf(solutionFileName, MaxStrLen, "%s%s_%s_solution.gz",
5177 }
5178 snprintf(solverStatisticsFileName, MaxStrLen, "%s%s_%s_solverStatistics_LC%d.gz",
5181 snprintf(loadCoordinatorStatisticsFileName, MaxStrLen, "%s%s_%s_loadCoordinatorStatistics_LC%d.gz",
5184 if( remove(nodesFileName) )
5185 {
5186 std::cout << *paraInitiator << "checkpoint nodes file cannot be removed: errno = " << strerror(errno) << std::endl;
5187 exit(1);
5188 }
5189 if ( remove(solutionFileName) )
5190 {
5191 std::cout << *paraInitiator << "checkpoint solution file cannot be removed: errno = " << strerror(errno) << std::endl;
5192 exit(1);
5193 }
5194 if ( remove(solverStatisticsFileName) )
5195 {
5196 std::cout << *paraInitiator << "checkpoint SolverStatistics file cannot be removed: errno = " << strerror(errno) << std::endl;
5197 exit(1);
5198 }
5199 if ( remove(loadCoordinatorStatisticsFileName) )
5200 {
5201 std::cout << *paraInitiator << "checkpoint LoadCoordinatorStatistics file cannot be removed: errno = " << strerror(errno) << std::endl;
5202 exit(1);
5203 }
5204 }
5205
5206 char afterCheckpointingSolutionFileName[MaxStrLen];
5207 snprintf(afterCheckpointingSolutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
5210 gzstream::igzstream afterCheckpointingSolutionStream;
5211 afterCheckpointingSolutionStream.open(afterCheckpointingSolutionFileName, std::ios::in | std::ios::binary);
5212 if( afterCheckpointingSolutionStream )
5213 {
5214 /** afater checkpointing solution file exists */
5215 afterCheckpointingSolutionStream.close();
5216 if ( remove(afterCheckpointingSolutionFileName) )
5217 {
5218 std::cout << *paraInitiator << "after checkpointing solution file cannot be removed: errno = " << strerror(errno) << std::endl;
5219 exit(1);
5220 }
5221 }
5222
5223 /** update last checkpoint time string */
5224 strcpy(lastCheckpointTimeStr,newCheckpointTimeStr);
5225}
5226
5227void
5229 gzstream::ogzstream &loadCoordinatorStatisticsStream,
5230 int nSolverInfo,
5231 double globalBestDualBoundValue,
5232 double externalGlobalBestDualBoundValue
5233 )
5234{
5235 loadCoordinatorStatisticsStream.write((char *)&nSolverInfo, sizeof(int));
5236 lcts.isCheckpointState = true;
5238 {
5241 }
5242 else
5243 {
5246 }
5247 lcts.nNodesLeftInAllSolvers = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getNnodesInSolvers();
5248 lcts.globalBestDualBoundValue = std::max( globalBestDualBoundValue, lcts.globalBestDualBoundValue );
5251 if( nodesMerger )
5252 {
5257 }
5258 lcts.write(loadCoordinatorStatisticsStream);
5259}
5260
5261void
5263 )
5264{
5265 ///
5266 /// check parameter consistency
5267 ///
5269 {
5271 {
5272 std::cout << *paraInitiator << "*** When warm start with racing is specified, you should specify CollectOnce = TRUE ***" << std::endl;
5274 {
5275 std::cout << *paraInitiator << "*** When warm start with racing is specified, you cannot specify MergeNodesAtRestart = TRUE ***" << std::endl;
5276 }
5277 exit(1);
5278 }
5280 {
5281 std::cout << *paraInitiator << "*** When warm start with racing is specified, you cannot specify MergeNodesAtRestart = TRUE ***" << std::endl;
5282 exit(1);
5283 }
5284 std::cout << *paraInitiator << "*** Warm start with racing ramp-up ***" << std::endl;
5285 }
5286 else
5287 {
5289 {
5291 }
5292 std::cout << *paraInitiator << "*** Warm start with normal ramp-up ***" << std::endl;
5293 }
5294
5295
5296 restarted = true;
5297 /** write previous statistics information */
5299
5300 if( paraParams->getIntParamValue(RampUpPhaseProcess) == 0 ) // if it is not racing ramp-up
5301 {
5302 /** try to read racing winner params */
5303 char racingWinnerParamsName[MaxStrLen];
5304 snprintf(racingWinnerParamsName, MaxStrLen, "%s%s_racing_winner_params.gz",
5307 gzstream::igzstream racingWinnerParamsStream;
5308 racingWinnerParamsStream.open(racingWinnerParamsName, std::ios::in | std::ios::binary);
5309 if( racingWinnerParamsStream )
5310 {
5311 assert(!racingWinnerParams);
5313 racingWinnerParams->read(paraComm, racingWinnerParamsStream);
5314 racingWinnerParamsStream.close();
5315 for( int i = 1; i < paraComm->getSize(); i++ )
5316 {
5317 /** send racing winner params: NOTE: should not broadcast. if we do it, solver routine need to recognize staring process */
5320 );
5321 }
5322 std::cout << *paraInitiator << "*** winner parameter is read from " << racingWinnerParamsName << "***" << std::endl;
5323 }
5324 }
5325
5326 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5327
5328 /** set solution and get internal incumbent value */
5329 char afterCheckpointingSolutionFileName[MaxStrLen];
5330 snprintf(afterCheckpointingSolutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
5333 double incumbentValue = paraInitiator->readSolutionFromCheckpointFile(afterCheckpointingSolutionFileName);
5335 {
5336 bbParaInitiator->writeSolution("[Warm started from "+std::string(bbParaInitiator->getPrefixWarm())+" : the solution from the checkpoint file]");
5337 }
5338
5339 int n = 0;
5340 BbParaNode *paraNode;
5341 bool onlyBoundChanges = false;
5343 {
5344 onlyBoundChanges = true;
5345 }
5347 {
5348 if( nodesMerger ) delete nodesMerger;
5349 nodesMerger = new BbParaNodesMerger(dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance())->getVarIndexRange(),
5350 nBoundChangesOfBestNode,paraTimer,dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance()),paraParams);
5351 }
5352
5354
5355 for(;;)
5356 {
5357 paraNode = bbParaInitiator->readParaNodeFromCheckpointFile(onlyBoundChanges);
5358 // paraParamSet->getBoolParamValue(MergingNodeStatusInCheckpointFile) );
5359 if( paraNode == 0 )
5360 break;
5361#ifdef UG_DEBUG_SOLUTION
5362#ifdef UG_DEBUG_SOLUTION_OPT_PATH
5363 if( paraNode->getDiffSubproblem() && (!paraNode->getDiffSubproblem()->isOptimalSolIncluded()) )
5364 {
5365 delete paraNode;
5366 paraNode = 0;
5367 continue;
5368 }
5369#endif
5370#endif
5371 n++;
5372 if( paraNode->getAncestor() )
5373 {
5374 std::cout << *paraInitiator << "Checkpoint node has ancestor: " << paraNode->toString() << std::endl;
5375 std::cout << *paraInitiator << "Something wrong for this checkpoint file." << std::endl;
5376 exit(1);
5377 }
5378 paraNode->setDualBoundValue(paraNode->getInitialDualBoundValue());
5379 // paraNodePool->insert(paraNode); /** in order to sort ParaNodes, insert paraNodePool once */
5383 {
5384 tempParaNodePool.insert(paraNode); /** in order to sort ParaNodes with new dual value, insert it to tempParaNodePool once */
5385 // addNodeToMergeNodeStructs(paraNode);
5386 }
5387 else
5388 {
5389 paraNodePool->insert(paraNode); /** in order to sort ParaNodes, insert paraNodePool once */
5390 }
5391 }
5392
5394 {
5396 {
5397 std::cout << *paraInitiator << "### NNodesToKeepInCheckpointFile is specified to "
5399 << " and also NEagerToSolveAtRestart is specified to "
5401 << ". The both values should not greater than 0 together." << std::endl;
5402 exit(-1);
5403 }
5405 {
5406 std::cout << *paraInitiator << "### NNodesToKeepInCheckpointFile is specified to "
5408 << " and also MergeNodesAtRestart = TRUE is specified. This combination is not allowed." << std::endl;
5409 exit(-1);
5410 }
5411 if( (signed)tempParaNodePool.getNumOfNodes() <= paraParams->getIntParamValue(NNodesToKeepInCheckpointFile) )
5412 {
5413 std::cout << *paraInitiator << "### NNodesToKeepInCheckpointFile is specified to " << paraParams->getIntParamValue(NNodesToKeepInCheckpointFile) <<
5414 ", but the number of nodes in checkpoint file is " << tempParaNodePool.getNumOfNodes() << ". ###" << std::endl;
5415 exit(-1);
5416 }
5418 {
5419 std::cout << *paraInitiator << "### NEagerToSolveAtRestart is specified to "
5421 << ", but RampUpPhaseProcess != 0 is specified. This combination is not allowed." << std::endl;
5422 exit(-1);
5423 }
5425 for(int i = 0; i < paraParams->getIntParamValue(NNodesToKeepInCheckpointFile); i++ )
5426 {
5427 BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5429 }
5430 while( tempParaNodePool.getNumOfNodes() > 0 )
5431 {
5432 BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5433 paraNodePool->insert(tempParaNode);
5434 }
5435 std::cout << *paraInitiator << "### NNodesToKeepInCheckpointFile is specified to "
5437 << " ###" << std::endl;
5438 std::cout << *paraInitiator << "### The number of no process nodes = " << paraNodeToKeepCheckpointFileNodes->getNumOfNodes()
5439 << " ###" << std::endl;
5440 std::cout << *paraInitiator << "### The number of nodes will be processed = " << paraNodePool->getNumOfNodes()
5441 << " ###" << std::endl;
5442 }
5443
5445 {
5446 if( (signed)tempParaNodePool.getNumOfNodes() < paraParams->getIntParamValue(NEagerToSolveAtRestart) )
5447 {
5448 std::cout << *paraInitiator << "### NEagerToSolveAtRestart is specified to " << paraParams->getIntParamValue(NEagerToSolveAtRestart) <<
5449 ", but the number of nodes in checkpoint file is " << tempParaNodePool.getNumOfNodes() << ". ###" << std::endl;
5450 exit(-1);
5451 }
5453 {
5454 std::cout << *paraInitiator << "### NEagerToSolveAtRestart is specified to "
5456 << " and also MergeNodesAtRestart = TRUE is specified. This combination is not allowed." << std::endl;
5457 exit(-1);
5458 }
5460 {
5461 std::cout << *paraInitiator << "### NEagerToSolveAtRestart is specified to "
5463 << ", but RampUpPhaseProcess != 0 is specified. This combination is not allowed." << std::endl;
5464 exit(-1);
5465 }
5467 for(int i = 0; i < paraParams->getIntParamValue(NEagerToSolveAtRestart); i++ )
5468 {
5469 BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5470 paraNodePool->insert(tempParaNode);
5471 }
5472 while( tempParaNodePool.getNumOfNodes() > 0 )
5473 {
5474 BbParaNode *tempParaNode = tempParaNodePool.extractNode();
5475 unprocessedParaNodes->insert(tempParaNode);
5476 }
5477 std::cout << *paraInitiator << "### NEagerToSolveAtRestart is specified to "
5479 << " ###" << std::endl;
5480 std::cout << *paraInitiator << "### The number of no process nodes in the beginning = " << unprocessedParaNodes->getNumOfNodes()
5481 << " ###" << std::endl;
5482 }
5483
5484 // std::cout << "insrt to node pool: " << paraTimer->getElapsedTime() << std::endl;
5485
5487 {
5488 int nMerge = 0;
5489 BbParaNode *tempNode = 0;
5490 while( ( tempNode = tempParaNodePool.extractNode() ) )
5491 {
5492 if( nBoundChangesOfBestNode < 0 )
5493 {
5494 if( tempNode->getDiffSubproblem() )
5495 {
5496 nBoundChangesOfBestNode = dynamic_cast<BbParaDiffSubproblem *>(tempNode->getDiffSubproblem())->getNBoundChanges();
5497 }
5498 else
5499 {
5501 }
5502 }
5503 paraNodePool->insert(tempNode);
5506 {
5507 assert(nodesMerger);
5509 nMerge++;
5510 }
5511 }
5512 assert(nodesMerger);
5514 }
5515
5518
5519 // std::cout << "merging finished:" << paraTimer->getElapsedTime() << std::endl;
5520
5522 {
5523 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
5524 {
5526 << " Warm started from "
5528 << " : " << n << " ParaNodes read. Current incumbent value = "
5529 << bbParaInitiator->convertToExternalValue(
5531 << std::endl;
5532 }
5533 else
5534 {
5536 << " Warm started from "
5538 << " : " << n << " ParaNodes read. No solution is generated." << std::endl;
5539 }
5540 }
5541#ifdef _DEBUG_LB
5542 std::cout << paraTimer->getElapsedTime()
5543 << " Warm started from "
5545 << " : " << n << " ParaNodes read. Current incumbent value = "
5546 << paraInitiator->convertToExternalValue(
5547 paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() )
5548 << std::endl;
5549#endif
5552 {
5553 for( int i = 1; i < paraComm->getSize(); i++ )
5554 {
5555 /** send internal incumbent value */
5557 paraComm->send( &incumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
5558 );
5560 {
5561 bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, i);
5562 }
5563 /** send internal global dual bound value */
5566 );
5567 }
5572 {
5574 }
5575 else
5576 {
5577 // without consideration of keeping nodes in checkpoint file
5578 double globalBestDualBoundValueLocal =
5579 std::max (
5580 std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
5583 {
5585 {
5586 if( ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
5590 paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
5591 {
5594 }
5595 else
5596 {
5598 }
5599 }
5600 else
5601 {
5602 if( ( (signed)paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
5604 ( (signed)paraNodePool->getNumOfNodes()
5606 paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
5607 {
5610 }
5611 else
5612 {
5614 }
5615 }
5616 }
5617 else
5618 {
5620 {
5621 if( ( paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal )
5625 paraNodePool->getNumOfGoodNodes( globalBestDualBoundValueLocal ) > 0 ) ) )
5626 {
5629 }
5630 else
5631 {
5633 }
5634 }
5635 else
5636 {
5639 }
5640 }
5641 }
5642 // std::cout << "before run:" << paraTimer->getElapsedTime() << std::endl;
5643 // exit(1);
5644 run();
5645 }
5646 else
5647 {
5649 || paraParams->getIntParamValue(RampUpPhaseProcess) == 2 ) // if it isracing ramp-up
5650 {
5651 /// racing ramp-up
5652 assert(!racingWinnerParams);
5653
5654 paraNode = paraNodePool->extractNode();
5657 paraInitiator->generateRacingRampUpParameterSets( (paraComm->getSize()-1), racingRampUpParams );
5658
5659 if( paraNodePool->isEmpty() )
5660 {
5661 for( int i = 1; i < paraComm->getSize(); i++ )
5662 {
5663 int noKeep = 0;
5665 paraComm->send( &noKeep, 1, ParaINT, i, TagKeepRacing)
5666 );
5668 racingRampUpParams[i-1]->send(paraComm, i)
5669 );
5670 }
5671 }
5672 else
5673 {
5674 for( int i = 1; i < paraComm->getSize(); i++ )
5675 {
5676 int keep = 1;
5678 paraComm->send( &keep, 1, ParaINT, i, TagKeepRacing)
5679 );
5681 racingRampUpParams[i-1]->send(paraComm, i)
5682 );
5683 }
5684 }
5685
5686 run(paraNode, (paraComm->getSize()-1), racingRampUpParams );
5687
5688 if( paraNodePool->isEmpty() )
5689 {
5690 for( int i = 1; i < paraComm->getSize(); i++ )
5691 {
5692 /** send internal incumbent value */
5694 paraComm->send( &incumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
5695 );
5697 {
5698 bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, i);
5699 }
5700 /** send internal global dual bound value */
5703 );
5704 if( racingRampUpParams[i-1] ) delete racingRampUpParams[i-1];
5705 }
5706 }
5707 else
5708 {
5709 for( int i = 1; i < paraComm->getSize(); i++ )
5710 {
5711 /** send internal incumbent value */
5713 paraComm->send( &incumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
5714 );
5716 {
5717 bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, i);
5718 }
5719 /** send internal global dual bound value */
5722 );
5724 paraComm->send( NULL, 0, ParaBYTE, i, TagKeepRacing)
5725 );
5726 if( racingRampUpParams[i-1] ) delete racingRampUpParams[i-1];
5727 }
5728 }
5729 delete [] racingRampUpParams;
5730 }
5731 }
5732
5733}
5734
5735void
5737 )
5738{
5739 /* read previous LoadCoordinator statistics */
5740 char loadCoordinatorStatisticsFileName[MaxStrLen];
5741 snprintf(loadCoordinatorStatisticsFileName, MaxStrLen, "%s_loadCoordinatorStatistics_LC0.gz", paraInitiator->getPrefixWarm());
5742 gzstream::igzstream loadCoordinatorStatisticsStream;
5743 loadCoordinatorStatisticsStream.open(loadCoordinatorStatisticsFileName, std::ios::in | std::ios::binary);
5744 if( !loadCoordinatorStatisticsStream )
5745 {
5746 std::cout << *paraInitiator << "checkpoint LoadCoordinatorStatistics file cannot open: file name = " << loadCoordinatorStatisticsFileName << std::endl;
5747 exit(1);
5748 }
5749 int nSolverStatistics;
5750 loadCoordinatorStatisticsStream.read((char *)&nSolverStatistics, sizeof(int));
5752 if( !prevLcts->read(paraComm, loadCoordinatorStatisticsStream) )
5753 {
5754 std::cout << *paraInitiator << "checkpoint LoadCoordinatorStatistics file cannot read: file name = " << loadCoordinatorStatisticsFileName << std::endl;
5755 exit(1);
5756 }
5757 loadCoordinatorStatisticsStream.close();
5758
5759 /* open Solver statistics file */
5760 char solverStatisticsFileName[MaxStrLen];
5761 snprintf(solverStatisticsFileName, MaxStrLen, "%s_solverStatistics_LC0.gz", paraInitiator->getPrefixWarm());
5762 gzstream::igzstream solverStatisticsStream;
5763 solverStatisticsStream.open(solverStatisticsFileName, std::ios::in | std::ios::binary);
5764 if( !solverStatisticsStream )
5765 {
5766 std::cout << *paraInitiator << "checkpoint SolverStatistics file cannot open: file name = " << solverStatisticsFileName << std::endl;
5767 exit(1);
5768 }
5769
5770 /* opne output statistics file */
5771 char previousStatisticsFileName[MaxStrLen];
5772 snprintf(previousStatisticsFileName, MaxStrLen, "%s_statistics_w%05lld_LC0",
5774 prevLcts->nWarmStart);
5775 std::ofstream ofsStatistics;
5776 ofsStatistics.open(previousStatisticsFileName);
5777 if( !ofsStatistics )
5778 {
5779 std::cout << *paraInitiator << "previous statistics file cannot open : file name = " << previousStatisticsFileName << std::endl;
5780 exit(1);
5781 }
5782
5783 /* read and write solver statistics */
5784 for( int i = 0; i < nSolverStatistics; i++ )
5785 {
5787 if( !psts->read(paraComm, solverStatisticsStream) )
5788 {
5789 std::cout << *paraInitiator << "checkpoint SolverStatistics file cannot read: file name = " << solverStatisticsFileName << std::endl;
5790 exit(1);
5791 }
5792 ofsStatistics << psts->toString(paraInitiator);
5793 delete psts;
5794 }
5795
5796 /* write LoadCoordinator statistics */
5797 ofsStatistics << prevLcts->toString();
5798
5799 /* update warm start counter */
5800 lcts.nWarmStart = prevLcts->nWarmStart + 1;
5803 delete prevLcts;
5804
5805 /* close solver statistics file and output file */
5806 solverStatisticsStream.close();
5807 ofsStatistics.close();
5808}
5809
5810#endif // End of UG_WITH_ZLIB
5811
5812void
5814 ParaTask *paraNode
5815 )
5816{
5818 {
5819 outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
5820 }
5821
5822 assert(!paraRacingSolverPool);
5823 // without consideration of keeping nodes in checkpoint file
5824 double globalBestDualBoundValueLocal =
5825 std::max (
5826 std::min( dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGlobalBestDualBoundValue(), paraNodePool->getBestDualBoundValue() ),
5828
5830 {
5831 int destination = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activateSolver(
5832 dynamic_cast<BbParaNode *>(paraNode),
5834 paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains );
5835 lcts.nSent++;
5838 )
5839 {
5840 int nCollect = -1;
5842 paraComm->send( &nCollect, 1, ParaINT, destination, TagCollectAllNodes )
5843 );
5844 }
5846 {
5847 int token[2];
5848 token[0] = 1;
5849 token[1] = -1;
5851 paraComm->send( token, 2, ParaINT, token[0], TagToken )
5852 );
5853 }
5854 writeTransferLog(destination);
5855
5856 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5857
5859 {
5861 << " S." << destination << " < "
5862 << bbParaInitiator->convertToExternalValue(
5863 dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() );
5864 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
5865 {
5866 if( bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) > displayInfOverThisValue )
5867 {
5868 *osLogSolvingStatus << " ( Inf )";
5869 }
5870 else
5871 {
5872 *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) * 100 << "% )";
5873 }
5874 }
5879 {
5880 *osLogSolvingStatus << " L";
5881 }
5882 *osLogSolvingStatus << std::endl;
5883 }
5884#ifdef DEBUG_LB
5885 std::cout << paraTimer->getElapsedTime()
5886 << " S." << destination << " > "
5887 << paraInitiator->convertToExternalValue(
5888 paraNode->getDualBoundValue() );
5889 if( paraInitiator->getGlobalBestIncumbentSolution() )
5890 {
5891 if( paraInitiator->getGap(paraNode->getDualBoundValue()) > displayInfOverThisValue )
5892 {
5893 std::cout << " ( Inf )";
5894 }
5895 else
5896 {
5897 std::cout << " ( " << paraInitiator->getGap(paraNode->getDualBoundValue()) * 100 << "% )";
5898 }
5899 }
5904 {
5905 std::cout << " L";
5906 }
5907 std::cout << std::endl;
5908#endif
5909 }
5910 else // self-split ramp-up
5911 {
5912 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5913 DEF_BB_PARA_COMM(bbParaComm, paraComm);
5914 delete paraNode;
5915 for( unsigned int i = 0; i < paraSolverPool->getNSolvers(); i++ )
5916 {
5917 paraNode = bbParaComm->createParaNode(
5918 TaskId(), TaskId(), 0, -DBL_MAX, -DBL_MAX, -DBL_MAX,
5919 bbParaInitiator->makeRootNodeDiffSubproblem()
5920 );
5921 int destination = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activateSolver(
5922 dynamic_cast<BbParaNode *>(paraNode),
5924 paraNodePool->getNumOfGoodNodes(globalBestDualBoundValueLocal), averageLastSeveralDualBoundGains );
5925 lcts.nSent++;
5926 writeTransferLog(destination);
5927
5929 {
5931 << " S." << destination << " < "
5932 << bbParaInitiator->convertToExternalValue(
5933 dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() );
5934 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
5935 {
5936 if( bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) > displayInfOverThisValue )
5937 {
5938 *osLogSolvingStatus << " ( Inf )";
5939 }
5940 else
5941 {
5942 *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue()) * 100 << "% )";
5943 }
5944 }
5945 *osLogSolvingStatus << std::endl;
5946 }
5948 {
5949 int token[2];
5950 token[0] = 1;
5951 token[1] = -1;
5953 paraComm->send( token, 2, ParaINT, token[0], TagToken )
5954 );
5955 }
5956 }
5957 }
5958
5959 run();
5960}
5961
5962int
5964 int source,
5965 int tag
5966 )
5967{
5968
5969 BbParaSolverState *solverState = dynamic_cast<BbParaSolverState *>(paraComm->createParaSolverState());
5970 solverState->receive(paraComm, source, tag);
5971
5972#ifdef _DEBUG_DET
5973 if( paraDetTimer )
5974 {
5975 std::cout << "Rank " << source << ": ET = " << paraDetTimer->getElapsedTime() << ", Det time = " << solverState->getDeterministicTime() << std::endl;
5976 }
5977#endif
5978
5979 if( paraDetTimer
5980 && paraDetTimer->getElapsedTime() < solverState->getDeterministicTime() )
5981
5982 {
5984 }
5985
5986 assert(solverState->isRacingStage());
5987 if( !restartingRacing ) // restartingRacing means that LC is terminating racing solvers.
5988 {
5989 dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->updateSolverStatus(source,
5990 solverState->getNNodesSolved(),
5991 solverState->getNNodesLeft(),
5992 solverState->getSolverLocalBestDualBoundValue());
5993 assert( dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNumNodesLeft(source) == solverState->getNNodesLeft() );
5994 }
5995
5996 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
5997
5999 {
6001 << " S." << source << " | "
6002 << bbParaInitiator->convertToExternalValue(
6004 );
6005 if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6006 bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) > displayInfOverThisValue
6007 || solverState->getNNodesLeft() == 0 )
6008 {
6009 *osLogSolvingStatus << " ( Inf )";
6010 }
6011 else
6012 {
6013 *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
6014 }
6015 *osLogSolvingStatus << " [ " << solverState->getNNodesLeft() << " ]";
6016 double globalBestDualBoundValue = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue();
6017 if( paraNodePool->getNumOfNodes() > 0 )
6018 {
6019 globalBestDualBoundValue = std::min( globalBestDualBoundValue, paraNodePool->getBestDualBoundValue() );
6020 }
6021 *osLogSolvingStatus << " ** G.B.: " << bbParaInitiator->convertToExternalValue(globalBestDualBoundValue);
6022 if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6023 bbParaInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
6024 {
6025 *osLogSolvingStatus << " ( Inf ) ";
6026 }
6027 else
6028 {
6029 *osLogSolvingStatus << " ( " << bbParaInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
6030 }
6031 *osLogSolvingStatus << "[ " << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver()
6032 // <<" ] ** RR" << std::endl;
6033 <<" ] ** RR " << solverState->getDeterministicTime() << std::endl; // for debug
6034 }
6035#ifdef _DEBUG_LB
6036 std::cout << paraTimer->getElapsedTime()
6037 << " S." << source << " | "
6038 << bbParaInitiator->convertToExternalValue(
6040 );
6041 if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6042 bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) > displayInfOverThisValue
6043 || solverState->getNNodesLeft() == 0 )
6044 {
6045 std::cout << " ( Inf )";
6046 }
6047 else
6048 {
6049 std::cout << " ( " << bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) * 100 << "% )";
6050 }
6051 std::cout << " [ " << solverState->getNNodesLeft() << " ]";
6052 double globalBestDualBoundValue = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue();
6053 std::cout << " ** G.B.: " << paraInitiator->convertToExternalValue(globalBestDualBoundValue);
6054 if( !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6055 bbParaInitiator->getGap(globalBestDualBoundValue) > displayInfOverThisValue )
6056 {
6057 std::cout << " ( Inf ) ";
6058 }
6059 else
6060 {
6061 std::cout << " ( " << bbParaInitiator->getGap(globalBestDualBoundValue) * 100 << "% ) ";
6062 }
6063 std::cout << "[ " << dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver()
6064 <<" ] ** RR" << std::endl;
6065#endif
6066
6068 {
6069 /** the following should be before noticationId back to the source solver */
6071 {
6072 if( bbParaInitiator->getGlobalBestIncumbentSolution() &&
6074 < solverState->getGlobalBestPrimalBoundValue() )
6075 {
6076 bbParaInitiator->getGlobalBestIncumbentSolution()->send(paraComm, source);
6077 }
6078 }
6079 }
6080
6081 // if( paraParams->getBoolParamValue(CheckGapInLC) )
6082 if( !givenGapIsReached )
6083 {
6084 if( bbParaInitiator->getAbsgap(solverState->getSolverLocalBestDualBoundValue() ) <
6085 bbParaInitiator->getAbsgapValue() ||
6086 bbParaInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) <
6087 bbParaInitiator->getGapValue()
6088 )
6089 {
6090 for( unsigned int i = 1; i <= paraRacingSolverPool->getNSolvers(); i++ )
6091 {
6093 {
6096 );
6098 }
6099 }
6100 // std::cout << "current dual = " << paraInitiator->convertToExternalValue(solverState->getSolverLocalBestDualBoundValue()) <<std::endl;
6101 // std::cout << "pool best dual = " << paraInitiator->convertToExternalValue(dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue()) << std::endl;
6102 // std::cout << "current gap = " << paraInitiator->getGap(solverState->getSolverLocalBestDualBoundValue()) <<std::endl;
6103 givenGapIsReached = true;
6104 }
6105 }
6106
6107 double lcBestDualBoundValue = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getGlobalBestDualBoundValue();
6108
6110 paraComm->send( &lcBestDualBoundValue, 1, ParaDOUBLE, source, TagLCBestBoundValue)
6111 );
6112 unsigned int notificationId = solverState->getNotificaionId();
6114 paraComm->send( &notificationId, 1, ParaUNSIGNED, source, TagNotificationId)
6115 );
6116
6117 if( lcts.globalBestDualBoundValue < lcBestDualBoundValue )
6118 {
6119 if( paraNodePool->getNumOfNodes() > 0 )
6120 {
6121 lcts.globalBestDualBoundValue = std::min( lcBestDualBoundValue, paraNodePool->getBestDualBoundValue() );
6122 }
6123 else
6124 {
6125 lcts.globalBestDualBoundValue = lcBestDualBoundValue;
6126 }
6127
6129 }
6130 delete solverState;
6131 return 0;
6132}
6133
6134int
6136 int source,
6137 int tag
6138 )
6139{
6141 calcState->receive(paraComm, source, tag);
6142 writeTransferLogInRacing(source, calcState);
6143
6144 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6145
6147 {
6148 switch ( calcState->getTerminationState() )
6149 {
6151 {
6153 << " S." << source << " >(TERMINATED_IN_RACING_STAGE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6154 break;
6155 }
6158 {
6160 << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT or INTERRUPTED_BY_SOME_SOLVER_TERMINATED_IN_RACING_STAGE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6161 break;
6162 }
6164 {
6166 << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6167 break;
6168 }
6170 {
6172 << " S." << source << " >(INTERRUPTED_BY_MEMORY_LIMIT) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6173 break;
6174 }
6175 default:
6178 {
6180 << " S." << source << " >(INTERRUPTED_BY_ANOTHER_NODE) " << bbParaInitiator->convertToExternalValue(calcState->getDualBoundValue());
6181 break;
6182 }
6183 THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
6184 }
6185 *osLogSolvingStatus << ", ct:" << calcState->getCompTime()
6186 << ", nr:" << calcState->getNRestarts()
6187 << ", n:" << calcState->getNSolved()
6188 << ", rt:" << calcState->getRootTime()
6189 << ", avt:" << calcState->getAverageNodeCompTimeExcpetRoot()
6190 << std::endl;
6191 }
6192#ifdef _DEBUG_LB
6193 switch ( calcState->getTerminationState() )
6194 {
6196 {
6197 std::cout << paraTimer->getElapsedTime()
6198 << " S." << source << " >(TERMINATED_IN_RACING_STAGE)";
6199 break;
6200 }
6203 {
6204 std::cout << paraTimer->getElapsedTime()
6205 << " S." << source << " >(INTERRUPTED_BY_TIME_LIMIT or INTERRUPTED_BY_SOME_SOLVER_TERMINATED_IN_RACING_STAGE)";
6206 break;
6207 }
6208 default:
6209 THROW_LOGICAL_ERROR2("Invalid termination: termination state = ", calcState->getTerminationState() )
6210 }
6211 std::cout << std::endl;
6212#endif
6213
6215 {
6216 racingTermination = true; // even if interruptIsRequested,
6217 // solver should have been terminated before receiveing it
6219 {
6220 *osStatisticsRacingRampUp << "######### Solver Rank = " <<
6221 source << " is terminated in racing stage #########" << std::endl;
6222 }
6223
6224 if( (dynamic_cast<UG::BbParaInitiator *>(paraInitiator)->getNSolutions() >=
6226 )
6227 {
6228 nSolvedRacingTermination = calcState->getNSolved();
6229 if( !EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, bbParaInitiator->getEpsilon() ) &&
6230 EPSEQ( minmalDualBoundNormalTermSolvers, DBL_MAX, bbParaInitiator->getEpsilon() ) )
6231 {
6232 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
6233 {
6235 }
6236 else
6237 {
6239 }
6240 }
6241 if( EPSLE(lcts.globalBestDualBoundValue, calcState->getDualBoundValue(), bbParaInitiator->getEpsilon()) &&
6242 minmalDualBoundNormalTermSolvers < calcState->getDualBoundValue() )
6243 {
6244 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
6245 {
6247 }
6248 else
6249 {
6251 }
6252 }
6253 if( bbParaInitiator->getGlobalBestIncumbentSolution() && (!givenGapIsReached) &&
6255 EPSEQ( calcState->getDualBoundValue(), -DBL_MAX, paraInitiator->getEpsilon() ) ||
6256 EPSEQ( calcState->getDualBoundValue(), DBL_MAX, paraInitiator->getEpsilon() ) ||
6258 // distributed domain propagation could causes the following situation
6259 bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue() < calcState->getDualBoundValue() ) ||
6260 ( calcState->getNSolved() == 0 ) ) )
6261 {
6263 if( paraNodePool->getNumOfNodes() > 0 )
6264 {
6266 }
6268 if( bbParaInitiator->getGlobalBestIncumbentSolution() )
6269 {
6271 }
6272 else
6273 {
6275 }
6276 }
6277 /*
6278 if( paraInitiator->getGlobalBestIncumbentSolution() &&
6279 paraParamSet->getBoolParamValue(UG::CommunicateTighterBoundsInRacing) &&
6280 // distributed domain propagation could causes the following situation
6281 paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue() < calcState->getDualBoundValue() &&
6282 EPSGE( paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue(), lcts.globalBestDualBoundValue, paraInitiator->getEpsilon() ) )
6283 {
6284 lcts.globalBestDualBoundValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFuntionValue();
6285 lcts.externalGlobalBestDualBoundValue = paraInitiator->convertToExternalValue(lcts.globalBestDualBoundValue);
6286 minmalDualBoundNormalTermSolvers = lcts.globalBestDualBoundValue;
6287 }
6288 */
6289 assert( paraNodePool->getNumOfNodes() > 0 || !bbParaInitiator->getGlobalBestIncumbentSolution() ||
6290 ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
6293 {
6294 dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->updateSolverStatus(source,
6297 {
6299 }
6300 }
6301 }
6302 }
6303
6305 {
6307 // std::cout << "####### Rank " << paraComm->getRank() << " solver terminated with timelimit in solver side. #######" << std::endl;
6308 // std::cout << "####### Final statistics may be messed up!" << std::endl;
6309 }
6311 {
6312 memoryLimitIsReached = true;
6313 }
6314
6315 delete calcState;
6316
6317 // if( !warmStartNodeTransferring || ( warmStartNodeTransferring && paraNodePool->isEmpty() ) )
6318 // {
6320 termState->receive(paraComm, source, TagTermStateForInterruption);
6321
6322 if( paraDetTimer )
6323 {
6324 if( paraDetTimer->getElapsedTime() < termState->getDeterministicTime() )
6325 {
6327 }
6329 paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
6330 );
6331 }
6332
6334 {
6336 }
6337
6339 {
6340 std::cout << *paraInitiator << termState->toString(paraInitiator) << std::endl;
6341 }
6342
6343 delete termState;
6344 // }
6345 // else
6346 // {
6347 // if( paraDetTimer )
6348 // {
6349 // PARA_COMM_CALL(
6350 // paraComm->send( NULL, 0, ParaBYTE, source, TagAckCompletion )
6351 // );
6352 // }
6353 // }
6354 // nTerminated++; We should not count this, We should always send Term from LC!
6356
6357 if( racingTermination &&
6359 (!bbParaInitiator->getGlobalBestIncumbentSolution()) ) ||
6360 (dynamic_cast<UG::BbParaInitiator *>(paraInitiator)->getNSolutions() <
6362 )
6363 {
6364 racingTermination = false;
6365 }
6366
6368 {
6369 // racingTermination = false;
6370 // nTerminated++;
6372 {
6373 newRacing();
6374 }
6375 }
6376 else
6377 {
6378#ifndef _COMM_MPI_WORLD
6380 {
6382 {
6383 // nTerminated = 1;
6385 delete this;
6386#ifdef _COMM_PTH
6387 _exit(0);
6388#else
6389 exit(0);
6390#endif
6391 }
6392 }
6393#endif
6394 }
6395
6396 return 0;
6397}
6398
6399
6400void
6402 ParaTask *paraNode,
6403 int nRacingSolvers,
6404 ParaRacingRampUpParamSet **racingRampUpParams
6405 )
6406{
6408 {
6409 outputTabularSolvingStatusHeader(); /// should not call virutal function in constructor
6410 }
6411
6412 /** creates racing solver pool */
6414 nRacingSolvers, // the number of racing solvers
6415 1, // paraSolver origin rank
6417
6418 BbParaRacingSolverPool *bbParaRacingSolverPool = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool);
6419
6420 /** activate racing solver with root node */
6421 /// NOTE that paraComm->getSize() - 1 is not always nRacingSolvers, that it other type of solvers can be working with
6423 paraNode->bcast(paraComm, 0)
6424 );
6425 bbParaRacingSolverPool->activate(dynamic_cast<BbParaNode *>(paraNode));
6426 lcts.nSent++;
6428 {
6429 int token[2];
6430 token[0] = 1;
6431 token[1] = -1;
6433 paraComm->send( token, 2, ParaINT, token[0], TagToken )
6434 );
6435 }
6437 {
6438 for(int i = 1; i < paraComm->getSize(); i++ )
6439 {
6441 }
6442 }
6443
6444 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6445
6446 /** output start racing to log file, if it is necessary */
6448 {
6450 << " All Solvers starts racing "
6451 << bbParaInitiator->convertToExternalValue(
6452 dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() )
6453 << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
6454 << std::endl;
6455 }
6456#ifdef _DEBUG_LB
6457 std::cout << paraTimer->getElapsedTime()
6458 << " All Solvers starts racing "
6459 << paraInitiator->convertToExternalValue(
6460 paraNode->getDualBoundValue() )
6461 << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
6462 << std::endl;
6463#endif
6464
6465 int source;
6466 int tag;
6467
6468 for(;;)
6469 {
6470 /*******************************************
6471 * waiting for any message form anywhere *
6472 *******************************************/
6473 double inIdleTime = paraTimer->getElapsedTime();
6474 (void)paraComm->probe(&source, &tag);
6475 lcts.idleTime += ( paraTimer->getElapsedTime() - inIdleTime );
6477 {
6478 int status = (this->*racingRampUpMessageHandler[tag])(source, tag);
6479 if( status )
6480 {
6481 std::ostringstream s;
6482 s << "[ERROR RETURN form Racing Ramp-up Message Hander]:" << __FILE__ << "] func = "
6483 << __func__ << ", line = " << __LINE__ << " - "
6484 << "process tag = " << tag << std::endl;
6485 abort();
6486 }
6487 }
6488 else
6489 {
6490 THROW_LOGICAL_ERROR3( "No racing ramp-up message hander for ", tag, " is not registered" );
6491 }
6492
6493#ifdef UG_WITH_UGS
6494 if( commUgs ) checkAndReadIncumbent();
6495#endif
6496
6497 /** output tabular solving status */
6498 if( outputTabularSolvingStatusFlag && // (!racingTermination) &&
6507 {
6510 {
6512 {
6514 }
6515 else
6516 {
6518 }
6519 }
6520 else
6521 {
6523 }
6524 }
6525
6527 break;
6528
6529 if( restartingRacing )
6530 {
6532 {
6533 if( restartRacing() )
6534 {
6535 return; // solved
6536 }
6537 }
6538 continue;
6539 }
6540
6541 switch ( runningPhase )
6542 {
6543 case RampUpPhase:
6544 {
6546 {
6548 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->activate();
6549 run();
6550 return;
6551 }
6552 if( racingTermination )
6553 {
6554 if( paraNodePool->isEmpty()
6556 {
6558 delete paraRacingSolverPool;
6560 run();
6561 return;
6562 }
6563 if( paraNodePool->isEmpty()
6565 {
6566 if( source < static_cast<int>(paraSolverPool->getNSolvers()) + 1 && !paraSolverPool->isInterruptRequested(source) )
6567 {
6569// std::cout << "sendInterrruptRequest1 13" << std::endl;
6570 }
6571 }
6572 break;
6573 }
6574
6575 // if( paraParams->getRealParamValue(TimeLimit) > 0.0 &&
6576 // paraTimer->getElapsedTime() > paraParams->getRealParamValue(TimeLimit) )
6578 {
6580 // hardTimeLimitIsReached = true;
6581 // sendInterruptRequest();
6582 // runningPhase = TerminationPhase; waits until paraRacingSolverPool becomes empty
6583 break;
6584 }
6585
6587 // paraTimer->getElapsedTime() > paraParams->getRealParamValue(FinalCheckpointGeneratingTime) )
6588 {
6590 // hardTimeLimitIsReached = true;
6591 std::cout << *paraInitiator << "** Program is still in racing stage. FinalCheckpointGeneratingTime is sppecifid, but the checkpoint files would not be generated." << std::endl;
6592 // sendInterruptRequest();
6593 // runningPhase = TerminationPhase; waits until paraRacingSolverPool becomes empty
6594 break;
6595 }
6596
6597 if( bbParaRacingSolverPool->isWinnerDecided(
6598 ( bbParaInitiator->getGlobalBestIncumbentSolution() &&
6600 {
6604 )
6605 {
6606 if( !restartingRacing )
6607 {
6608 for(int i = 1; i < paraComm->getSize(); i++)
6609 {
6612 );
6613 }
6614 // primalUpdated = false;
6615 restartingRacing = true;
6616 }
6617 }
6618 else
6619 {
6622 racingTermination = false;
6623 assert( racingWinner >0 );
6624 int numNodesLeft = bbParaRacingSolverPool->getNumNodesLeft(racingWinner);
6626 bbParaSolverPool->activateSolver(
6627 racingWinner, bbParaRacingSolverPool->extractNode(), numNodesLeft );
6628 bbParaRacingSolverPool->inactivateSolver(racingWinner);
6629
6630 // assert(paraRacingSolverPool->getNumActiveSolvers() >= 0);
6633 );
6634
6635 if( numNodesLeft >
6637 ||
6639 )
6640 {
6646 std::cout << *paraInitiator << "Warning: Ramp-Up Phase Process is switched to 1. CollectOnce, MergeNodesAtRestart and RacingStatBranching are switched to FALSE." << std::endl;
6647 std::cout << *paraInitiator << "You should check the following parameter values: StopRacingNumberOfNodesLeft, StopRacingNumberOfNodesLeftMultiplier, ProhibitCollectOnceMultiplier" << std::endl;
6648 }
6649
6650 if( numNodesLeft > (signed)paraSolverPool->getNSolvers()
6651 ||
6653 )
6654 {
6656 {
6657 int nCollect = paraParams->getIntParamValue(NCollectOnce);
6658 if( nCollect == 0 )
6659 {
6660 nCollect = ( paraSolverPool->getNSolvers() * 5 );
6661 }
6664 );
6665 }
6667 {
6668 merging = true;
6669 if( nodesMerger ) delete nodesMerger;
6670 nodesMerger = new BbParaNodesMerger(dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance())->getVarIndexRange(),
6671 nBoundChangesOfBestNode,paraTimer,dynamic_cast<BbParaInstance *>(bbParaInitiator->getParaInstance()),paraParams);
6672 }
6673 }
6674 else
6675 {
6676 winnerSolverNodesCollected = true; // do not wait until all nodes are collected
6677 }
6678 racingWinnerParams = racingRampUpParams[racingWinner - 1];
6679 // racingWinnerParams->setWinnerRank(racingWinner);
6680 racingRampUpParams[racingWinner - 1] = 0;
6681 for(int i = 1; i < paraComm->getSize(); i++)
6682 {
6683 if( racingRampUpParams[i - 1] )
6684 {
6687 );
6688 }
6689 int noKeep = 0;
6691 paraComm->send( &noKeep, 1, ParaINT,i, TagKeepRacing)
6692 );
6693 }
6694 /** output winner to log file, if it is necessary */
6696 {
6698 << " S." << racingWinner << " is the racing winner!"
6699 << " Selected strategy " << racingWinnerParams->getStrategy()
6700 << "." << std::endl;
6701 }
6702 #ifdef _DEBUG_LB
6703 std::cout << paraTimer->getElapsedTime()
6704 << " S." << racingWinner << " is the racing winner!"
6705 << " Selected strategy " << racingWinnerParams->getStrategy()
6706 << "." << std::endl;
6707 #endif
6709 {
6711 "Racing ramp-up finished after " <<
6712 paraTimer->getElapsedTime() << " seconds." <<
6713 " Selected strategy " << racingWinnerParams->getStrategy() <<
6714 "." << std::endl;
6715 }
6716 // runningPhase = NormalRunningPhase;
6717 // Keep running as RampUpPhase, but in the run() switching into RampUpPhase in normal running mode
6718 // delete paraRacingSolverPool;
6719 run();
6720 return;
6721 }
6722 }
6723
6726 && paraNodePool->getNumOfNodes() > 0
6727 )
6728 {
6729 newRacing();
6730 }
6731 break;
6732 }
6733 default:
6734 {
6735 THROW_LOGICAL_ERROR2( "Undefined running phase: ", static_cast<int>(runningPhase) );
6736 }
6737 }
6738 }
6739 return;
6740}
6741
6742void
6744 )
6745{
6746 for( int i = 1; i < paraComm->getSize(); i++ )
6747 {
6749 paraComm->send( NULL, 0, ParaBYTE, i, TagRetryRampUp )
6750 );
6751 }
6752}
6753
6754void
6756 )
6757{
6758 int exitSolverRequest = 0; // do nothing
6764 (signed)nCollectedSolvers < paraParams->getIntParamValue(UG::FinalCheckpointNSolvers) )
6765 ) )
6766 {
6768 {
6770 "Start collecting the final check-point data after " <<
6771 paraTimer->getElapsedTime() << " seconds. " << std::endl;
6772 }
6773
6775 {
6776 int bestSolverRank = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getGoodSolverSolvingEssentialNode();
6777 if( bestSolverRank > 0 ) // bestSolverRank exits
6778 {
6779 BbParaNode *solvingNode = dynamic_cast<BbParaNode *>(paraSolverPool->getCurrentTask(bestSolverRank));
6780 assert( !solvingNode->getAncestor() );
6781 solvingNode->collectsNodes();
6782 exitSolverRequest = 1; // collect all nodes
6784 paraComm->send( &exitSolverRequest, 1, ParaINT, bestSolverRank, TagInterruptRequest )
6785 );
6787 {
6789 << " S." << bestSolverRank << " TagInterruptRequest with collecting is sent"
6790 << std::endl;
6791 }
6792 }
6793 else
6794 {
6796 {
6798 << " S." << bestSolverRank << " TagInterruptRequest with collecting could not be sent (No best solvers)"
6799 << std::endl;
6800 }
6801 }
6802 }
6803 else
6804 {
6806 {
6808 << " S." << 0 << " TagInterruptRequest with collecting could not be sent (No active solvers)"
6809 << std::endl;
6810 }
6811 }
6812 }
6813 else
6814 {
6817 {
6818 for( int i = 1; i < paraComm->getSize(); i++ )
6819 {
6821 {
6823 paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
6824 );
6826 }
6827 else
6828 {
6830 paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
6831 );
6834 {
6835 int token[2];
6836 token[0] = i;
6837 token[1] = -2;
6839 paraComm->send( token, 2, ParaINT, token[0], TagToken )
6840 );
6841 }
6842 // nTerminated++;
6843 }
6844 }
6845// std::cout << "TagTerminateRequest 4" << std::endl;
6846 }
6847 else
6848 {
6849 // normal TimeLimit
6850 if( interruptIsRequested ) return;
6852 {
6853 for( int i = 1; i < paraComm->getSize(); i++ )
6854 {
6856 {
6858 paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
6859 );
6861 }
6862 else
6863 {
6865 paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
6866 );
6869 {
6870 int token[2];
6871 token[0] = i;
6872 token[1] = -2;
6874 paraComm->send( token, 2, ParaINT, token[0], TagToken )
6875 );
6876 }
6877 }
6878 }
6879// hardTimeLimitIsReached = true;
6880// std::cout << "TagTerminateRequest 5" << std::endl;
6881 }
6883 {
6884 for( int i = 1; i < static_cast<int>(paraRacingSolverPool->getNSolvers()) + 1; i++ )
6885 {
6887 {
6889 paraComm->send( &exitSolverRequest, 1, ParaINT, i, TagInterruptRequest )
6890 );
6892 }
6893 else
6894 {
6896 paraComm->send( NULL, 0, ParaBYTE, i, TagTerminateRequest )
6897 );
6900 {
6901 int token[2];
6902 token[0] = i;
6903 token[1] = -2;
6905 paraComm->send( token, 2, ParaINT, token[0], TagToken )
6906 );
6907 }
6908 }
6909 }
6910// hardTimeLimitIsReached = true;
6911// std::cout << "TagTerminateRequest 6" << std::endl;
6912// std::cout << "racingTermination = " << racingTermination << std::endl;
6913 }
6914 }
6915 }
6916
6917 interruptIsRequested = true;
6918}
6919
6920bool
6922 BbParaSolution *sol
6923 )
6924{
6925
6926 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6927
6928 if( !bbParaInitiator->getGlobalBestIncumbentSolution() )
6929 return bbParaInitiator->tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(sol->clone(paraComm)),false);
6930 if( sol->getObjectiveFunctionValue()
6932 return bbParaInitiator->tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(sol->clone(paraComm)),false);
6933 else
6934 return false;
6935}
6936
6937void
6939 int receivedRank
6940 )
6941{
6942
6943 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6944
6945 double globalBestIncumbentValue = bbParaInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue();
6947 {
6948 for( int i = 1; i < paraComm->getSize(); i++ )
6949 {
6950 if( i != receivedRank )
6951 {
6953 paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
6954 );
6955 }
6956
6957 }
6958 }
6959 lcts.nDeletedInLc += paraNodePool->removeBoundedNodes(globalBestIncumbentValue);
6960 /*
6961 if( paraParams->getIntParamValue(RampUpPhaseProcess) == 3 )
6962 {
6963 lcts.nDeletedInLc += dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->removeBoundedNodes(globalBestIncumbentValue);
6964 }
6965 */
6966}
6967
6968void
6970 int receivedRank
6971 )
6972{
6973
6974 BbParaInitiator *bbParaInitiator = dynamic_cast<BbParaInitiator *>(paraInitiator);
6975
6976 double globalBestCutOffValue = bbParaInitiator->getGlobalBestIncumbentSolution()->getCutOffValue();
6978 {
6979 for( int i = 1; i < paraComm->getSize(); i++ )
6980 {
6981 if( i != receivedRank )
6982 {
6984 paraComm->send( &globalBestCutOffValue, 1, ParaDOUBLE, i, TagCutOffValue )
6985 );
6986 }
6987
6988 }
6989 }
6990 lcts.nDeletedInLc += paraNodePool->removeBoundedNodes(globalBestCutOffValue);
6991}
6992
6993void
6995 int rank
6996 )
6997{
6998 nSolvedInInterruptedRacingSolvers = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesSolvedInBestSolver();
6999 nTasksLeftInInterruptedRacingSolvers = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->getNnodesLeftInBestSolver();
7000 if( paraRacingSolverPool->isSolverActive(rank) ) // if rank is the winner, it should be inactive
7001 {
7002 dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->inactivateSolver(rank);
7003 }
7004 if( paraSolverPool->isSolverActive(rank) )
7005 {
7006 /*
7007 * special timining problem
7008 *
7009 * 1113.58 S.4 I.SOL 0
7010 * 1113.58 S.3 is the racing winner! Selected strategy 2.
7011 * 1113.58 S.4 >(TERMINATED_IN_RACING_STAGE)
7012 *
7013 */
7015 {
7016 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(rank, -1, paraNodePool);
7017 // reschedule collecting mode
7019 {
7020 double tempTime = dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->getSwichOutTime();
7021 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchOutCollectingMode();
7022 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->setSwichOutTime(tempTime);
7023 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->switchInCollectingMode(paraNodePool);
7024 }
7025 }
7026 else
7027 {
7028 dynamic_cast<BbParaSolverPoolForMinimization *>(paraSolverPool)->inactivateSolver(rank, -1, paraNodePool);
7029 }
7030 }
7031
7032 if ( (!interruptIsRequested) &&
7033 (!restartingRacing )&&
7035 {
7036 /** if the computation is interrupted,
7037 * paraRacingSolverPool is needed to output statistics */
7039 {
7040 delete paraRacingSolverPool;
7042 }
7043 }
7044
7045}
7046
7047void
7049 int source,
7050 ParaCalculationState *calcState
7051 )
7052{
7053 if( logSubtreeInfoFlag )
7054 {
7055 ParaTask *node = paraSolverPool->getCurrentTask(source);
7057 << ", "
7058 << source
7059 << ", "
7060 << node->toSimpleString()
7061 << ", "
7062 << calcState->toSimpleString()
7063 << std::endl;
7064 }
7065}
7066
7067int
7069 )
7070{
7071 // RESTART RACING MAY NOT WORK WITH DETERMINSTIC MODE: NOT DEBUGGED
7072
7074 {
7075 restartingRacing = false;
7076 return 1;
7077 }
7078
7079 ParaInstance *paraInstance = paraInitiator->getParaInstance();
7081
7082 BbParaNode *rootNode = dynamic_cast<BbParaNode *>(dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->extractNode());
7083 rootNode->setDualBoundValue(-DBL_MAX);
7084 rootNode->setInitialDualBoundValue(-DBL_MAX);
7085 rootNode->setEstimatedValue(-DBL_MAX);
7086
7087 /** recreate racing solver pool */
7088 delete paraRacingSolverPool;
7090 1, // paraSolver origin rank
7092
7093 /** activate racing solver with root node */
7095 rootNode->bcast(paraComm, 0)
7096 );
7097 dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool)->activate(rootNode);
7098 lcts.nSent++;
7099
7101
7103 {
7104 *osStatisticsRacingRampUp << "##################################" << std::endl;
7105 *osStatisticsRacingRampUp << "### Racing restarted " << nRestartedRacing << " times" << std::endl;
7106 *osStatisticsRacingRampUp << "##################################" << std::endl;
7107 }
7108
7110 {
7112 {
7114 << " Racing Ramp-up restarted." << std::endl;
7115 }
7116 }
7117
7119 {
7120 *osTabularSolvingStatus << "Racing Ramp-up restarted." << std::endl;
7121 }
7122
7123 primalUpdated = false;
7124 restartingRacing = false;
7125
7126 lcts.globalBestDualBoundValue = -DBL_MAX;
7128 interruptIsRequested = false;
7129
7130 return 0;
7131}
7132
7133void
7135 )
7136{
7137 racingTermination = false;
7138 // assert( nTerminated == paraRacingSolverPool->getNumInactiveSolvers() );
7139 BbParaNode *paraNode = paraNodePool->extractNode();
7140 if( paraNodePool->isEmpty() )
7141 {
7142 for( int i = 1; i < paraComm->getSize(); i++ )
7143 {
7144 int noKeep = 0;
7146 paraComm->send( &noKeep, 1, ParaINT,i, TagKeepRacing)
7147 );
7149 paraNode->send(paraComm, i)
7150 );
7151 }
7152 }
7153 else
7154 {
7155 for( int i = 1; i < paraComm->getSize(); i++ )
7156 {
7157 int keep = 1;
7159 paraComm->send( &keep, 1, ParaINT, i, TagKeepRacing)
7160 );
7161// PARA_COMM_CALL(
7162// paraComm->send( NULL, 0, ParaBYTE,i, TagTerminateSolvingToRestart)
7163// );
7165 paraNode->send(paraComm, i)
7166 );
7167 }
7168 }
7169
7170 /** activate racing solver with root node */
7171 BbParaRacingSolverPool *bbParaRacingSolverPool = dynamic_cast<BbParaRacingSolverPool *>(paraRacingSolverPool);
7172 bbParaRacingSolverPool->reset();
7173 bbParaRacingSolverPool->activate(paraNode);
7174 lcts.nSent++;
7176 {
7177 int token[2];
7178 token[0] = 1;
7179 token[1] = -1;
7181 paraComm->send( token, 2, ParaINT, token[0], TagToken )
7182 );
7183 }
7185 {
7186 for(int i = 1; i < paraComm->getSize(); i++ )
7187 {
7189 }
7190 }
7191
7192 /** output start racing to log file, if it is necessary */
7194 {
7196 << " All Solvers starts racing "
7197 << dynamic_cast<BbParaInitiator *>(paraInitiator)->convertToExternalValue(
7198 dynamic_cast<BbParaNode *>(paraNode)->getDualBoundValue() )
7199 << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
7200 << std::endl;
7201 }
7202#ifdef _DEBUG_LB
7203 std::cout << paraTimer->getElapsedTime()
7204 << " All Solvers starts racing "
7205 << paraInitiator->convertToExternalValue(
7206 paraNode->getDualBoundValue() )
7207 << ", size of ParaNodePool = " << paraNodePool->getNumOfNodes()
7208 << std::endl;
7209#endif
7210 // nTerminated = 0;
7211 interruptIsRequested = false;
7212}
7213
7214void
7216 )
7217{
7218 /* Not implemented yet
7219 int bestBoundSearch = 1;
7220 for( int i = 1; i < paraComm->getSize(); i++ )
7221 {
7222 PARA_COMM_CALL(
7223 paraComm->send( &bestBoundSearch, 1, ParaINT, i, TagChangeSearchStrategy )
7224 );
7225 }
7226 */
7227}
7228
7229void
7231 )
7232{
7233 /* Not implemented yet
7234 int originalSearch = 0;
7235 for( int i = 1; i < paraComm->getSize(); i++ )
7236 {
7237 PARA_COMM_CALL(
7238 paraComm->send( &originalSearch, 1, ParaINT, i, TagChangeSearchStrategy )
7239 );
7240 }
7241 */
7242}
7243
7244
7245#ifdef UG_WITH_UGS
7246int
7247BbParaLoadCoordinator::checkAndReadIncumbent(
7248 )
7249{
7250 int source = -1;
7251 int tag = TagAny;
7252
7253 assert(commUgs);
7254
7255 while( commUgs->iProbe(&source, &tag) )
7256 {
7257 if( source == 0 && tag == UGS::TagUpdateIncumbent )
7258 {
7259 if( paraInitiator->readUgsIncumbentSolution(commUgs, source) )
7260 {
7261 double globalBestIncumbentValue = paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue();
7263 {
7264 if( paraInitiator->canGenerateSpecialCutOffValue() )
7265 {
7266 for( int i = 1; i < paraComm->getSize(); i++ )
7267 {
7268 sendCutOffValue(i);
7270 paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
7271 );
7272 }
7273 }
7274 else
7275 {
7276 for( int i = 1; i < paraComm->getSize(); i++ )
7277 {
7279 paraComm->send( &globalBestIncumbentValue, 1, ParaDOUBLE, i, TagIncumbentValue )
7280 );
7281 }
7282 }
7283
7284 }
7285 lcts.nDeletedInLc += paraNodePool->removeBoundedNodes(globalBestIncumbentValue);
7286
7287 primalUpdated = true;
7290 {
7292 << " S." << source << " I.SOL "
7293 << paraInitiator->convertToExternalValue(
7294 paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue()
7295 ) << std::endl;
7296 }
7297#ifdef _DEBUG_LB
7298 std::cout << paraTimer->getElapsedTime()
7299 << " S." << source << " I.SOL "
7300 << paraInitiator->convertToExternalValue(
7301 paraInitiator->getGlobalBestIncumbentSolution()->getObjectiveFunctionValue()
7302 ) << std::endl;
7303#endif
7304 /** output tabular solving status */
7306 {
7308 }
7309#ifdef UG_WITH_ZLIB
7310 /* Do not have to remove ParaNodes from NodePool. It is checked and removed before sending them */
7311 /** save incumbent solution */
7312 char solutionFileNameTemp[MaxStrLen];
7313 char solutionFileName[MaxStrLen];
7315 {
7316 snprintf(solutionFileNameTemp, MaxStrLen, "%s%s_after_checkpointing_solution_t.gz",
7319 paraInitiator->writeCheckpointSolution(std::string(solutionFileNameTemp));
7320 snprintf(solutionFileName, MaxStrLen, "%s%s_after_checkpointing_solution.gz",
7323 if ( rename(solutionFileNameTemp, solutionFileName) )
7324 {
7325 std::cout << "after checkpointing solution file cannot be renamed: errno = " << strerror(errno) << std::endl;
7326 exit(1);
7327 }
7328 }
7329#endif
7330 }
7331 }
7332 else if ( source == 0 && tag == TagTerminated )
7333 {
7334 return 1;
7335 }
7336 else
7337 {
7338 THROW_LOGICAL_ERROR5("Invalid Tag = ", tag, ", from source = ", source, " received.");
7339 }
7340 }
7341 return 0;
7342
7343}
7344#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