Scippy

UG

Ubiquity Generator framework

bbParaSolverPool.cpp
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and software framework */
4/* UG --- Ubquity Generator Framework */
5/* */
6/* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7/* Copyright (C) 2021-2024 by Zuse Institute Berlin, */
8/* licensed under LGPL version 3 or later. */
9/* Commercial licenses are available through <licenses@zib.de> */
10/* */
11/* This code is free software; you can redistribute it and/or */
12/* modify it under the terms of the GNU Lesser General Public License */
13/* as published by the Free Software Foundation; either version 3 */
14/* of the License, or (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU Lesser General Public License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file bbParaSolverPool.cpp
27 * @brief Solver pool.
28 * @author Yuji Shinano
29 *
30 *
31 *
32 */
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36
37#include <cassert>
38#include <string>
39#include <cstring>
40#include <sstream>
41#include <list>
42#include <map>
43#include <cmath>
44#include "ug/paraDef.h"
45#include "bbParaComm.h"
46#include "bbParaParamSet.h"
47#include "bbParaSolverPool.h"
48
49using namespace std;
50using namespace UG;
51
52/** constructor of selection heap */
53SelectionHeap::SelectionHeap(
54 std::size_t size /**< maximum size of this heap */
55 )
56{
57 maxHeapSize = size;
58 heapSize = 0;
59 heap = new BbParaSolverPoolElementPtr[size+1]; /* index 0 is a sentinel */
60}
61
62/** destructor of selection heap */
64 )
65{
66 delete[] heap;
67}
68/** resize selection heap */
69void
71 std::size_t size /**< new heap size */
72 )
73{
75 new BbParaSolverPoolElementPtr[size+1]; /* index 0 is a sentinel */
76 std::memcpy(tempHeap, heap, (unsigned long int)(sizeof(BbParaSolverPoolElementPtr) * (maxHeapSize+1)));
77 delete[] heap;
78 heap = tempHeap;
79 maxHeapSize = size;
80}
81
82/** insert BbParaSolverPoolElementPtr to selection heap */
85 BbParaSolverPoolElementPtr inSolver /**< BbParaSolverPoolElementPtr to be inserted */
86 )
87{
88 if( heapSize >= maxHeapSize ) return FAILED_BY_FULL;
89 heap[++heapSize] = inSolver;
91 return SUCCEEDED;
92}
93
94/** remove the top priority element form selection heap */
97 )
98{
100
101 heap[1] = heap[heapSize];
102 heapSize--;
103 downHeap(1);
104 if( heapSize == 0 )
105 {
106 heap[1] = 0;
107 }
108 solver->setSelectionHeapElement(0);
109 return solver;
110}
111
112
113/** stringfy selection heap */
114const std::string
116 )
117{
118 std::ostringstream os;
119 os << "--- selection heap ---" << std::endl;
120 os << "maxHeapSize: " << maxHeapSize << std::endl;
121 os << "heapSize: " << heapSize << std::endl;
122 for( std::size_t i = 1; i <= heapSize; i++ )
123 {
124 os << "heap[" << i << "]->rank: "
125 << heap[i]->getRank() << std::endl
126 << "heap[" << i << "]->status: "
127 << static_cast<int>(heap[i]->getStatus()) << std::endl
128 << "heap[" << i << "]->bestBound: "
129 << heap[i]->getBestDualBoundValue() << std::endl
130 << "heap[" << i << "]->numOfNodesLeft: "
131 << heap[i]->getNumOfNodesLeft() << std::endl
132 << "heap[" << i << "]->numOfDiff: "
133 << heap[i]->getNumOfDiffNodesLeft() << std::endl
134 << "heap[" << i << "]->collectingMode: "
135 << heap[i]->isInCollectingMode() << std::endl;
136 }
137 return os.str();
138}
139
140/** constructor of DescendingSelectionHeap */
142 std::size_t size /**< maximum size of this heap */
143 )
144 : SelectionHeap(size)
145{
146}
147
148/** update dual bound value of the solver in heap */
149void
151 BbParaSolverPoolElementPtr solver, /**< pointer to solver pool element whose dual bound is updated */
152 double newDualBoundValue /**< new dual bound value */
153 )
154{
155 int pos = solver->getSelectionHeapElement() - heap;
156 if( solver->getBestDualBoundValue() < newDualBoundValue )
157 {
158 solver->setBestDualBoundValue(newDualBoundValue);
159 upHeap(pos);
160 }
161 else
162 {
163 solver->setBestDualBoundValue(newDualBoundValue);
164 downHeap(pos);
165 }
166}
167
168/** delete BbParaSolverPoolElement */
169void
171 BbParaSolverPoolElementPtr solver /**< BbParaSolverPoolElement to be deleted */
172 )
173{
174 std::size_t pos = (solver->getSelectionHeapElement()) - heap;
175
176 if( pos == heapSize )
177 {
178 /* no need to rearrange heap element */
179 heap[heapSize--] = 0;
180 }
181 else
182 {
183 if( heap[pos]->getBestDualBoundValue() < heap[heapSize]->getBestDualBoundValue() )
184 {
185 heap[pos] = heap[heapSize];
186 heap[heapSize--] = 0;
187 upHeap(pos);
188 }
189 else
190 {
191 heap[pos] = heap[heapSize];
192 heap[heapSize--] = 0;
193 downHeap(pos);
194 }
195 }
196 solver->setSelectionHeapElement(0);
197}
198
199
200/** up heap */
201void
203 std::size_t pos /**< up heap this position element */
204 )
205{
207
208 she = heap[pos];
209 heap[0] = NULL;
210 while ( heap[pos/2] != NULL &&
211 ( heap[pos/2]->getBestDualBoundValue()
212 < she->getBestDualBoundValue() ) )
213 {
214 heap[pos] = heap[pos/2];
215 heap[pos]->setSelectionHeapElement(&heap[pos]);
216 pos = pos/2;
217 }
218 heap[pos] = she;
219 heap[pos]->setSelectionHeapElement(&heap[pos]);
220}
221
222/** down heap */
223void
225 std::size_t pos /**< down heap this position element */
226 )
227{
228 std::size_t j;
230
231 she = heap[pos];
232 while ( pos <= (heapSize/2) )
233 {
234 j = pos + pos;
235 if( j < heapSize &&
236 ( heap[j]->getBestDualBoundValue()
237 < heap[j+1]->getBestDualBoundValue() ) ) j++;
238 if( she->getBestDualBoundValue()
240 break;
241 heap[pos] = heap[j];
242 heap[pos]->setSelectionHeapElement(&heap[pos]);
243 pos = j;
244 }
245 heap[pos] = she;
246 heap[pos]->setSelectionHeapElement(&heap[pos]);
247}
248
249/** constructor of AscendingSelectionHeap */
251 std::size_t size /**< maximum size of this heap */
252 )
253 : SelectionHeap(size)
254{
255}
256
257/** update dual bound value of the solver in heap */
258void
260 BbParaSolverPoolElementPtr solver, /**< pointer to solver pool element whose dual bound is updated */
261 double newDualBoundValue /**< new dual bound value */
262 )
263{
264 int pos = solver->getSelectionHeapElement() - heap;
265 if( solver->getBestDualBoundValue() > newDualBoundValue )
266 {
267 solver->setBestDualBoundValue(newDualBoundValue);
268 upHeap(pos);
269 }
270 else
271 {
272 solver->setBestDualBoundValue(newDualBoundValue);
273 downHeap(pos);
274 }
275}
276
277/** delete BbParaSolverPoolElement */
278void
280 BbParaSolverPoolElementPtr solver /**< BbParaSolverPoolElement to be deleted */
281 )
282{
283 std::size_t pos = (solver->getSelectionHeapElement()) - heap;
284
285 if( pos == heapSize )
286 {
287 /* no need to rearrange heap element */
288 heap[heapSize--] = 0;
289 }
290 else
291 {
292 if( heap[pos]->getBestDualBoundValue() > heap[heapSize]->getBestDualBoundValue() )
293 {
294 heap[pos] = heap[heapSize];
295 heap[heapSize--] = 0;
296 upHeap(pos);
297 }
298 else
299 {
300 heap[pos] = heap[heapSize];
301 heap[heapSize--] = 0;
302 downHeap(pos);
303 }
304 }
305 solver->setSelectionHeapElement(0);
306}
307
308/** up heap */
309void
311 std::size_t pos /**< up heap this position element */
312){
314
315 she = heap[pos];
316 heap[0] = NULL;
317
318 while ( heap[pos/2] != NULL &&
319 ( heap[pos/2]->getBestDualBoundValue()
320 > she->getBestDualBoundValue() ) )
321 {
322 heap[pos] = heap[pos/2];
323 heap[pos]->setSelectionHeapElement(&heap[pos]);
324 pos = pos/2;
325 }
326 heap[pos] = she;
327 heap[pos]->setSelectionHeapElement(&heap[pos]);
328}
329
330/** down heap */
331void
333 std::size_t pos /**< down heap this position element */
334){
335 std::size_t j;
337
338 she = heap[pos];
339 while ( pos <= (heapSize/2) )
340 {
341 j = pos + pos;
342 if( j < heapSize &&
343 ( heap[j]->getBestDualBoundValue()
344 > heap[j+1]->getBestDualBoundValue() ) ) j++;
345 if( she->getBestDualBoundValue()
347 break;
348 heap[pos] = heap[j];
349 heap[pos]->setSelectionHeapElement(&heap[pos]);
350 pos = j;
351 }
352 heap[pos] = she;
353 heap[pos]->setSelectionHeapElement(&heap[pos]);
354}
355
356/** constructor of selection heap */
358 std::size_t size /**< maximum size of this heap */
359 )
360{
361 maxHeapSize = size;
362 heapSize = 0;
363 heap = new BbParaSolverPoolElementPtr[size+1]; /* index 0 is a sentinel */
364}
365
366/** destructor of selection heap */
368 )
369{
370 delete[] heap;
371}
372/** resize selection heap */
373void
375 std::size_t size /**< new heap size */
376 )
377{
379 new BbParaSolverPoolElementPtr[size+1]; /* index 0 is a sentinel */
380 std::memcpy(tempHeap, heap, (unsigned long int)(sizeof(BbParaSolverPoolElementPtr) * (maxHeapSize+1)));
381 delete[] heap;
382 heap = tempHeap;
383 maxHeapSize = size;
384}
385
386/** insert BbParaSolverPoolElementPtr to selection heap */
389 BbParaSolverPoolElementPtr inSolver /**< BbParaSolverPoolElementPtr to be inserted */
390 )
391{
392 if( heapSize >= maxHeapSize ) return FAILED_BY_FULL;
393 heap[++heapSize] = inSolver;
395 return SUCCEEDED;
396}
397
398/** remove the top priority element form selection heap */
401 )
402{
404
405 heap[1] = heap[heapSize];
406 heapSize--;
407 downHeap(1);
408 if( heapSize == 0 )
409 {
410 heap[1] = 0;
411 }
413 return solver;
414}
415
416
417/** stringfy selection heap */
418const std::string
420 )
421{
422 std::ostringstream os;
423 os << "--- selection heap ---" << std::endl;
424 os << "maxHeapSize: " << maxHeapSize << std::endl;
425 os << "heapSize: " << heapSize << std::endl;
426 for( std::size_t i = 1; i <= heapSize; i++ )
427 {
428 os << "heap[" << i << "]->rank: "
429 << heap[i]->getRank() << std::endl
430 << "heap[" << i << "]->status: "
431 << static_cast<int>(heap[i]->getStatus()) << std::endl
432 << "heap[" << i << "]->bestBound: "
433 << heap[i]->getBestDualBoundValue() << std::endl
434 << "heap[" << i << "]->numOfNodesLeft: "
435 << heap[i]->getNumOfNodesLeft() << std::endl
436 << "heap[" << i << "]->numOfDiff: "
437 << heap[i]->getNumOfDiffNodesLeft() << std::endl
438 << "heap[" << i << "]->collectingMode: "
439 << heap[i]->isInCollectingMode() << std::endl;
440 }
441 return os.str();
442}
443
444/** constructor of DescendingCollectingModeSolverHeap */
446 std::size_t size /**< maximum size of this heap */
447 )
449{
450}
451
452/** update dual bound value of the solver in heap */
453void
455 BbParaSolverPoolElementPtr solver, /**< pointer to solver pool element whose dual bound is updated */
456 double newDualBoundValue /**< new dual bound value */
457 )
458{
459 int pos = solver->getCollectingModeSolverHeapElement() - heap;
460 if( solver->getBestDualBoundValue() < newDualBoundValue )
461 {
462 solver->setBestDualBoundValue(newDualBoundValue);
463 upHeap(pos);
464 }
465 else
466 {
467 solver->setBestDualBoundValue(newDualBoundValue);
468 downHeap(pos);
469 }
470}
471
472/** delete BbParaSolverPoolElement */
473void
475 BbParaSolverPoolElementPtr solver /**< BbParaSolverPoolElement to be deleted */
476 )
477{
478 std::size_t pos = (solver->getCollectingModeSolverHeapElement()) - heap;
479
480 if( pos == heapSize )
481 {
482 /* no need to rearrange heap element */
483 heap[heapSize--] = 0;
484 }
485 else
486 {
487 if( heap[pos]->getBestDualBoundValue() < heap[heapSize]->getBestDualBoundValue() )
488 {
489 heap[pos] = heap[heapSize];
490 heap[heapSize--] = 0;
491 upHeap(pos);
492 }
493 else
494 {
495 heap[pos] = heap[heapSize];
496 heap[heapSize--] = 0;
497 downHeap(pos);
498 }
499 }
501}
502
503
504/** up heap */
505void
507 std::size_t pos /**< up heap this position element */
508 )
509{
511
512 she = heap[pos];
513 heap[0] = NULL;
514 while ( heap[pos/2] != NULL &&
515 ( heap[pos/2]->getBestDualBoundValue()
516 < she->getBestDualBoundValue() ) )
517 {
518 heap[pos] = heap[pos/2];
520 pos = pos/2;
521 }
522 heap[pos] = she;
524}
525
526/** down heap */
527void
529 std::size_t pos /**< down heap this position element */
530 )
531{
532 std::size_t j;
534
535 she = heap[pos];
536 while ( pos <= (heapSize/2) )
537 {
538 j = pos + pos;
539 if( j < heapSize &&
540 ( heap[j]->getBestDualBoundValue()
541 < heap[j+1]->getBestDualBoundValue() ) ) j++;
542 if( she->getBestDualBoundValue()
544 break;
545 heap[pos] = heap[j];
547 pos = j;
548 }
549 heap[pos] = she;
551}
552
553/** constructor of AscendingCollectingModeSolverHeap */
555 std::size_t size /**< maximum size of this heap */
556 )
558{
559}
560
561/** update dual bound value of the solver in heap */
562void
564 BbParaSolverPoolElementPtr solver, /**< pointer to solver pool element whose dual bound is updated */
565 double newDualBoundValue /**< new dual bound value */
566 )
567{
568 int pos = solver->getCollectingModeSolverHeapElement() - heap;
569 if( solver->getBestDualBoundValue() > newDualBoundValue )
570 {
571 solver->setBestDualBoundValue(newDualBoundValue);
572 upHeap(pos);
573 }
574 else
575 {
576 solver->setBestDualBoundValue(newDualBoundValue);
577 downHeap(pos);
578 }
579}
580
581/** delete BbParaSolverPoolElement */
582void
584 BbParaSolverPoolElementPtr solver /**< BbParaSolverPoolElement to be deleted */
585 )
586{
587 std::size_t pos = (solver->getCollectingModeSolverHeapElement()) - heap;
588
589 if( pos == heapSize )
590 {
591 /* no need to rearrange heap element */
592 heap[heapSize--] = 0;
593 }
594 else
595 {
596 if( heap[pos]->getBestDualBoundValue() > heap[heapSize]->getBestDualBoundValue() )
597 {
598 heap[pos] = heap[heapSize];
599 heap[heapSize--] = 0;
600 upHeap(pos);
601 }
602 else
603 {
604 heap[pos] = heap[heapSize];
605 heap[heapSize--] = 0;
606 downHeap(pos);
607 }
608 }
610}
611
612/** up heap */
613void
615 std::size_t pos /**< up heap this position element */
616){
618
619 she = heap[pos];
620 heap[0] = NULL;
621
622 while ( heap[pos/2] != NULL &&
623 ( heap[pos/2]->getBestDualBoundValue()
624 > she->getBestDualBoundValue() ) )
625 {
626 heap[pos] = heap[pos/2];
628 pos = pos/2;
629 }
630 heap[pos] = she;
632}
633
634/** down heap */
635void
637 std::size_t pos /**< down heap this position element */
638){
639 std::size_t j;
641
642 she = heap[pos];
643 while ( pos <= (heapSize/2) )
644 {
645 j = pos + pos;
646 if( j < heapSize &&
647 ( heap[j]->getBestDualBoundValue()
648 > heap[j+1]->getBestDualBoundValue() ) ) j++;
649 if( she->getBestDualBoundValue()
651 break;
652 heap[pos] = heap[j];
654 pos = j;
655 }
656 heap[pos] = she;
658}
659
660/** activate Solver specified by its rank */
661void
663 int rank, ///< rank of the solver to be activated
664 BbParaNode *paraNode, ///< paraNode to be solved in the solver
665 int nGoodNodesInNodePool,
666 double averageDualBoundGain
667 )
668{
669
670 active = true; // activate this solver pool
671
672 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
673 {
674 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
675 }
676 map<int, BbParaSolverPoolElementPtr>::iterator p;
677 if( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Inactive )
678 {
679 p = inactiveSolvers.find(rank);
680 if( p != inactiveSolvers.end() )
681 {
682 if( p->second->getRank() != rank ||
683 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
684 {
685 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
686 }
687 inactiveSolvers.erase(p);
688 }
689 else
690 {
691 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
692 }
693 }
694 else
695 {
696 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
697 }
698 activeSolvers.insert(make_pair(rank,pool[SOLVER_POOL_INDEX( rank )]));
699 pool[SOLVER_POOL_INDEX( rank )]->activate(paraNode);
701 {
703 }
705 selectionHeap->insert(pool[SOLVER_POOL_INDEX( rank )]); // this should be called after activate: dual bound value need to be set
707 {
708 if( ( (nDualBoundGainTesting*2) + nGoodNodesInNodePool ) < getNumInactiveSolvers() +
710 {
711 //if( beforeInitialCollect )
712 // {
713 // averageDualBoundGain*=2;
714 //}
716 paraComm->send(&averageDualBoundGain, 1, ParaDOUBLE, rank, TagTestDualBoundGain )
717 );
720 // std::cout << "S." << rank << " Test dual bound gain" << std::endl;
721 }
722 else
723 {
726 );
727 // std::cout << "S." << rank << " No test dual bound gain" << std::endl;
728 }
729 }
730 paraNode->send(paraComm, rank);
731}
732
733/** activate Solver specified by its rank and number of nodes left. This is for the racing winner. */
734void
736 int rank, ///< rank of the solver to be activated */
737 BbParaNode *paraNode, ///< paraNode to be solved in the solver */
738 int nNodesLeft ///< number of nodes left in the Solver */
739 )
740{
741
742 active = true; // activate this solver pool
743
744 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
745 {
746 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
747 }
748 map<int, BbParaSolverPoolElementPtr>::iterator p;
749 if( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Inactive )
750 {
751 p = inactiveSolvers.find(rank);
752 if( p != inactiveSolvers.end() )
753 {
754 if( p->second->getRank() != rank ||
755 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
756 {
757 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
758 }
759 inactiveSolvers.erase(p);
760 }
761 else
762 {
763 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
764 }
765 }
766 else
767 {
768 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
769 }
770 activeSolvers.insert(make_pair(rank,pool[SOLVER_POOL_INDEX( rank )]));
771 pool[SOLVER_POOL_INDEX( rank )]->activate(paraNode);
772 pool[SOLVER_POOL_INDEX( rank )]->setNumOfNodesLeft(nNodesLeft);
773 /** DO NOT PROHIBIT COLLECTING MODE. THIS IS ACTIVATION ROUTIN FOR RACING WIINGER */
774 nNodesInSolvers += nNodesLeft;
775 selectionHeap->insert(pool[SOLVER_POOL_INDEX( rank )]); // this should be called after activate: dual bound value need to be set
776}
777
778
779/** activate any Solver which is idle */
780int
782 BbParaNode *paraNode, ///< paraNode to be solved in an activated solver
783 BbParaRacingSolverPool *paraRacingSolverPool,///< paraRacingSolverPool to check if the solver is not solving root node
784 bool rampUpPhase,
785 int nGoodNodesInNodePool,
786 double averageDualBoundGain
787 )
788{
789 map<int, BbParaSolverPoolElementPtr>::iterator p;
790 int rank;
791
792 active = true; // activate this solver pool
793
794 if( !paraRacingSolverPool )
795 {
796 p = inactiveSolvers.begin();
797 if( p == inactiveSolvers.end() )
798 {
799 THROW_LOGICAL_ERROR1("No inactive Solver");
800 }
801 rank = p->second->getRank();
802 }
803 else
804 {
805 for( p = inactiveSolvers.begin(); p != inactiveSolvers.end(); ++p )
806 {
807 if( !paraRacingSolverPool->isSolverActive(p->second->getRank()) )
808 {
809 // at least one notification message is received
810 rank = p->second->getRank();
811 break;
812 }
813 }
814 if( p == inactiveSolvers.end() )
815 {
816 return -1;
817 }
818 }
819 activeSolvers.insert(make_pair(rank,pool[SOLVER_POOL_INDEX( rank )]));
820 pool[SOLVER_POOL_INDEX( rank )]->activate(paraNode);
822 {
824 }
826 selectionHeap->insert(pool[SOLVER_POOL_INDEX( rank )]); // this should be called after activate: dual bound value need to be set
827 inactiveSolvers.erase(p);
829 (!rampUpPhase) && (!paraRacingSolverPool ) && // already ramp-up ( and no racing solvers )
830 inactiveSolvers.size() >
832 // specified idle solver exists
833 )
834 {
837 );
838 }
840 {
841 if( ( (nDualBoundGainTesting*2) + nGoodNodesInNodePool ) < getNumInactiveSolvers() +
843 {
844 //if( beforeInitialCollect )
845 // {
846 // averageDualBoundGain*=2;
847 //}
849 paraComm->send(&averageDualBoundGain, 1, ParaDOUBLE, rank, TagTestDualBoundGain )
850 );
853 // std::cout << "S." << rank << " Test dual bound gain" << std::endl;
854 }
855 else
856 {
859 );
860 // std::cout << "S." << rank << " No test dual bound gain" << std::endl;
861 }
862 }
863 paraNode->send(paraComm, rank);
864 assert( ( paraNode->getMergingStatus() != 0 && ( !paraNode->getMergeNodeInfo() ) ) ||
865 ( paraNode->getMergingStatus() == 0 && paraNode->getMergeNodeInfo() ) );
866 return rank;
867}
868
869void
871 int rank, ///< rank of the solver, in which the subtree root node is added
872 BbParaNode *paraNode ///< paraNode to be added as the subtree root
873 )
874{
875 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
876 {
877 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
878 }
879 map<int, BbParaSolverPoolElementPtr>::iterator p;
880 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
881 {
882 p = activeSolvers.find(rank);
883 if( p != activeSolvers.end() )
884 {
885 if( p->second->getRank() != rank ||
886 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
887 {
888 THROW_LOGICAL_ERROR2("Rank = ", rank);
889 }
890 if( collectingMode || p->second->isCandidateOfCollecting() )
891 {
892 THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
893 }
894 p->second->addSubtreeRoot(paraNode);
895 // std::cout << "ADD: " << paraNode->toString() << std::endl;
896 }
897 else
898 {
899 THROW_LOGICAL_ERROR2("Rank = ", rank);
900 }
901 }
902 else
903 {
904 if( pool[SOLVER_POOL_INDEX( rank )]->getStatus() != InterruptRequested &&
905 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != TerminateRequested &&
906 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != Terminated )
907 {
908 std::cout << "Status = " << static_cast<int>(pool[SOLVER_POOL_INDEX( rank )]->getStatus()) << std::endl;
909 THROW_LOGICAL_ERROR2("Rank = ", rank);
910 }
911 }
912}
913
914void
916 int rank, ///< rank of the solver, in which the subtree root node is removed
917 BbParaNode *paraNode ///< paraNode to be removed
918 )
919{
920 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
921 {
922 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
923 }
924 map<int, BbParaSolverPoolElementPtr>::iterator p;
925 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
926 {
927 p = activeSolvers.find(rank);
928 if( p != activeSolvers.end() )
929 {
930 if( p->second->getRank() != rank ||
931 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
932 {
933 THROW_LOGICAL_ERROR2("Rank = ", rank);
934 }
935
936 // if( collectingMode || p->second->isCandidateOfCollecting() )
937 // {
938 // THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
939 // }
940 // std::cout << "REMOVE: " << paraNode->toString() << std::endl;
941 p->second->makeSubtreeRootCurrent(paraNode);
942 }
943 else
944 {
945 THROW_LOGICAL_ERROR2("Rank = ", rank);
946 }
947 }
948 else
949 {
950 if( pool[SOLVER_POOL_INDEX( rank )]->getStatus() != InterruptRequested &&
951 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != TerminateRequested &&
952 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != Terminated )
953 {
954 std::cout << "Status = " << static_cast<int>(pool[SOLVER_POOL_INDEX( rank )]->getStatus()) << std::endl;
955 THROW_LOGICAL_ERROR2("Rank = ", rank);
956 }
957 }
958}
959
960void
962 int rank, ///< rank of the solver, in which the subtree root node is removed
963 BbParaNode *paraNode ///< paraNode to be removed
964 )
965{
966 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
967 {
968 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
969 }
970 map<int, BbParaSolverPoolElementPtr>::iterator p;
971 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
972 {
973 p = activeSolvers.find(rank);
974 if( p != activeSolvers.end() )
975 {
976 if( p->second->getRank() != rank ||
977 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
978 {
979 THROW_LOGICAL_ERROR2("Rank = ", rank);
980 }
981
982 // if( collectingMode || p->second->isCandidateOfCollecting() )
983 // {
984 // THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
985 // }
986 // std::cout << "REMOVE: " << paraNode->toString() << std::endl;
987 p->second->removeSubtreeRoot(paraNode);
988 }
989 else
990 {
991 THROW_LOGICAL_ERROR2("Rank = ", rank);
992 }
993 }
994 else
995 {
996 if( pool[SOLVER_POOL_INDEX( rank )]->getStatus() != InterruptRequested &&
997 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != TerminateRequested &&
998 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != Terminated )
999 {
1000 std::cout << "Status = " << static_cast<int>(pool[SOLVER_POOL_INDEX( rank )]->getStatus()) << std::endl;
1001 THROW_LOGICAL_ERROR2("Rank = ", rank);
1002 }
1003 }
1004}
1005
1006//BbParaNode *
1007//BbParaSolverPool::removeAllSubtreeRootNode(
1008// int rank, ///< rank of the solver, in which the subtree root node is removed
1009// BbParaNode *paraNode ///< paraNode to be removed
1010// )
1011//{
1012// if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1013// {
1014// THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1015// }
1016// map<int, BbParaSolverPoolElementPtr>::iterator p;
1017// if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
1018// {
1019// p = activeSolvers.find(rank);
1020// if( p != activeSolvers.end() )
1021// {
1022// if( p->second->getRank() != rank ||
1023// pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
1024// {
1025// THROW_LOGICAL_ERROR2("Rank = ", rank);
1026// }
1027//
1028// // if( collectingMode || p->second->isCandidateOfCollecting() )
1029// // {
1030// // THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
1031// // }
1032// // std::cout << "REMOVE: " << paraNode->toString() << std::endl;
1033// p->second->removeSubtreeRoot(paraNode);
1034// }
1035// else
1036// {
1037// THROW_LOGICAL_ERROR2("Rank = ", rank);
1038// }
1039// }
1040// else
1041// {
1042// THROW_LOGICAL_ERROR2("Rank = ", rank);
1043// }
1044// BbParaNode *node = pool[SOLVER_POOL_INDEX(rank)]->extractCurrentNodeGeneratedBySelfSplit();
1045// return node;
1046//}
1047
1048BbParaNode *
1050 int rank, ///< rank of the solver, in which the subtree root node is removed
1051 BbParaNode *paraNode ///< paraNode to be removed
1052 )
1053{
1054 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1055 {
1056 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1057 }
1058 map<int, BbParaSolverPoolElementPtr>::iterator p;
1059 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
1060 {
1061 p = activeSolvers.find(rank);
1062 if( p != activeSolvers.end() )
1063 {
1064 if( p->second->getRank() != rank ||
1065 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
1066 {
1067 THROW_LOGICAL_ERROR2("Rank = ", rank);
1068 }
1069
1070 // if( collectingMode || p->second->isCandidateOfCollecting() )
1071 // {
1072 // THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
1073 // }
1074
1075 BbParaNode *node = p->second->extractSubtreeRoot(paraNode);
1076 node->next = 0;
1077 // std::cout << "EXTRACT: " << node->toString() << std::endl;
1078 return node;
1079 }
1080 else
1081 {
1082 THROW_LOGICAL_ERROR2("Rank = ", rank);
1083 }
1084 }
1085 else
1086 {
1087 THROW_LOGICAL_ERROR2("Rank = ", rank);
1088 }
1089}
1090
1091BbParaNode *
1093 int rank ///< rank of the solver, in which the subtree root node is removed
1094 )
1095{
1096 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1097 {
1098 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1099 }
1100 map<int, BbParaSolverPoolElementPtr>::iterator p;
1101 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
1102 {
1103 p = activeSolvers.find(rank);
1104 if( p != activeSolvers.end() )
1105 {
1106 if( p->second->getRank() != rank ||
1107 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
1108 {
1109 THROW_LOGICAL_ERROR2("Rank = ", rank);
1110 }
1111
1112 // if( collectingMode || p->second->isCandidateOfCollecting() )
1113 // {
1114 // THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
1115 // }
1116 return p->second->getSelfSplitNodes();
1117 }
1118 else
1119 {
1120 THROW_LOGICAL_ERROR2("Rank = ", rank);
1121 }
1122 }
1123 else
1124 {
1125 THROW_LOGICAL_ERROR2("Rank = ", rank);
1126 }
1127}
1128
1129BbParaNode *
1131 int rank ///< rank of the solver, in which the subtree root node is removed
1132 )
1133{
1134 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1135 {
1136 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1137 }
1138 return pool[SOLVER_POOL_INDEX( rank )]->extractSelfSplitNodes();
1139}
1140
1141void
1143 int rank ///< rank of the solver, in which the subtree root node is removed
1144 )
1145{
1146 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1147 {
1148 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1149 }
1150 map<int, BbParaSolverPoolElementPtr>::iterator p;
1151 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
1152 {
1153 p = activeSolvers.find(rank);
1154 if( p != activeSolvers.end() )
1155 {
1156 if( p->second->getRank() != rank ||
1157 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
1158 {
1159 THROW_LOGICAL_ERROR2("Rank = ", rank);
1160 }
1161
1162 // if( collectingMode || p->second->isCandidateOfCollecting() )
1163 // {
1164 // THROW_LOGICAL_ERROR3("Rank = ", rank, " should not be in colleting mode and shuould not be a candidate of collecting.");
1165 // }
1166 return p->second->deleteCurrentNode();
1167 }
1168 else
1169 {
1170 THROW_LOGICAL_ERROR2("Rank = ", rank);
1171 }
1172 }
1173 else
1174 {
1175 if( pool[SOLVER_POOL_INDEX( rank )]->getStatus() != InterruptRequested &&
1176 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != TerminateRequested &&
1177 pool[SOLVER_POOL_INDEX( rank )]->getStatus() != Terminated )
1178 {
1179 std::cout << "Status = " << static_cast<int>(pool[SOLVER_POOL_INDEX( rank )]->getStatus()) << std::endl;
1180 THROW_LOGICAL_ERROR2("Rank = ", rank);
1181 }
1182 }
1183}
1184
1185/** inactivate the Solver specified by rank */
1186void
1188 int rank, ///< rank of the solver to be inactivated
1189 long long numOfNodesSolved, ///< number of nodes solved
1190 BbParaNodePool *paraNodePool ///< pointer to ParaNodePool to change into collecting mode
1191 )
1192{
1193 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1194 {
1195 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1196 }
1197 // if( breakingFirstSubtree && rank == 1 && pool[SOLVER_POOL_INDEX(rank)]->isInCollectingMode() )
1198 if( breakingFirstSubtree && rank == 1 )
1199 {
1200 breakingFirstSubtree = false;
1201 }
1203 map<int, BbParaSolverPoolElementPtr>::iterator p;
1204 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active ||
1205 pool[SOLVER_POOL_INDEX( rank )]->getStatus() == InterruptRequested ||
1206 pool[SOLVER_POOL_INDEX( rank )]->getStatus() == TerminateRequested )
1207 {
1208 p = activeSolvers.find(rank);
1209 if( p != activeSolvers.end() )
1210 {
1211 if( p->second->getRank() != rank ||
1212 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
1213 {
1214 THROW_LOGICAL_ERROR2("Rank = ", rank);
1215 }
1216 if( numOfNodesSolved >= 0 )
1217 {
1218 nNodesSolvedInSolvers += numOfNodesSolved - p->second->getNumOfNodesSolved();
1219 // if(nNodesSolvedInSolvers > 999) abort();
1220 }
1221 nNodesInSolvers -= p->second->getNumOfNodesLeft();
1222 if( collectingMode && !pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1223 {
1224 // Don't have to send this message. Solver should be initialized with out of collecting mode
1225 //
1226 // PARA_COMM_CALL(
1227 // paraComm->send(NULL, 0, ParaBYTE, p->second->getRank(), TagOutCollectingMode)
1228 // );
1229 //
1230 // Should be initialized
1231 // pool[SOLVER_POOL_INDEX(rank)]->setCollectingMode(false);
1233 if( paraNodePool &&
1238 {
1239 //
1240 // the solver with the best dual bound should always in collecting mode first!
1241 //
1243 }
1244 }
1245 if( p->second->isCandidateOfCollecting() )
1246 {
1247 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
1248 for( pCandidate = candidatesOfCollectingModeSolvers.begin();
1249 pCandidate != candidatesOfCollectingModeSolvers.end(); ++pCandidate )
1250 {
1251 if( pCandidate->second->getRank() == rank )
1252 break;
1253 }
1254 assert( pCandidate != candidatesOfCollectingModeSolvers.end() );
1255 pCandidate->second->setCandidateOfCollecting(false);
1256 candidatesOfCollectingModeSolvers.erase(pCandidate);
1257 }
1258 activeSolvers.erase(p);
1259 }
1260 else
1261 {
1262 THROW_LOGICAL_ERROR2("Rank = ", rank);
1263 }
1264 }
1265 else
1266 {
1267 THROW_LOGICAL_ERROR2("Rank = ", rank);
1268 }
1269 selectionHeap->deleteElement(pool[SOLVER_POOL_INDEX( rank )]); /** need to have dual bound, so should be before inactivate() */
1271 {
1273 }
1274 pool[SOLVER_POOL_INDEX( rank )]->inactivate();
1276 {
1278 }
1279 inactiveSolvers.insert(make_pair(rank,pool[SOLVER_POOL_INDEX( rank )]));
1280}
1281
1282/** reset counters in the Solver specified by rank */
1283void
1285 int rank, ///< rank of the solver to be inactivated
1286 long long numOfNodesSolved, ///< number of nodes solved
1287 int numOfSelfSplitNodesLeft, ///< number of self-split nodes left
1288 BbParaNodePool *paraNodePool ///< pointer to ParaNodePool to change into collecting mode
1289 )
1290{
1291 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1292 {
1293 THROW_LOGICAL_ERROR2("Invalid rank. Rank = ", rank);
1294 }
1295 // if( breakingFirstSubtree && rank == 1 && pool[SOLVER_POOL_INDEX(rank)]->isInCollectingMode() )
1296 if( breakingFirstSubtree && rank == 1 )
1297 {
1298 breakingFirstSubtree = false;
1299 }
1301 map<int, BbParaSolverPoolElementPtr>::iterator p;
1302 if ( pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Active )
1303 {
1304 p = activeSolvers.find(rank);
1305 if( p != activeSolvers.end() )
1306 {
1307 if( p->second->getRank() != rank ||
1308 pool[SOLVER_POOL_INDEX( rank )]->getRank() != rank )
1309 {
1310 THROW_LOGICAL_ERROR2("Rank = ", rank);
1311 }
1312 nNodesSolvedInSolvers += numOfNodesSolved - p->second->getNumOfNodesSolved();
1313 // if(nNodesSolvedInSolvers > 999) abort();
1314 nNodesInSolvers -= p->second->getNumOfNodesLeft();
1315 if( collectingMode && !pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1316 {
1317 // Don't have to send this message. Solver should be initialized with out of collecting mode
1318 //
1319 // PARA_COMM_CALL(
1320 // paraComm->send(NULL, 0, ParaBYTE, p->second->getRank(), TagOutCollectingMode)
1321 // );
1322 //
1323 // Should be initialized
1324 // pool[SOLVER_POOL_INDEX(rank)]->setCollectingMode(false);
1326 if( selectionHeap->top()->getNumOfNodesLeft() > 1 &&
1330 {
1331 //
1332 // the solver with the best dual bound should always in collecting mode first!
1333 //
1335 }
1336 }
1337 if( p->second->isCandidateOfCollecting() )
1338 {
1339 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
1340 for( pCandidate = candidatesOfCollectingModeSolvers.begin();
1341 pCandidate != candidatesOfCollectingModeSolvers.end(); ++pCandidate )
1342 {
1343 if( pCandidate->second->getRank() == rank )
1344 break;
1345 }
1346 assert( pCandidate != candidatesOfCollectingModeSolvers.end() );
1347 pCandidate->second->setCandidateOfCollecting(false);
1348 candidatesOfCollectingModeSolvers.erase(pCandidate);
1349 }
1350 activeSolvers.erase(p);
1351 }
1352 else
1353 {
1354 THROW_LOGICAL_ERROR2("Rank = ", rank);
1355 }
1356 }
1357 else
1358 {
1359 THROW_LOGICAL_ERROR2("Rank = ", rank);
1360 }
1361 // selectionHeap->deleteElement(pool[SOLVER_POOL_INDEX( rank )]); /** need to have dual bound, so should be before inactivate() */
1363 {
1365 }
1367 // assert( node );
1368 selectionHeap->deleteElement(pool[SOLVER_POOL_INDEX( rank )]); /** need to have dual bound, so should be before inactivate() */
1370 {
1372 }
1373 pool[SOLVER_POOL_INDEX( rank )]->inactivate();
1374 // pool[SOLVER_POOL_INDEX( rank )]->activate(node);
1376 {
1378 }
1379 inactiveSolvers.insert(make_pair(rank,pool[SOLVER_POOL_INDEX( rank )]));
1380 if( node )
1381 {
1382 activateSolver(rank, node, numOfSelfSplitNodesLeft);
1383 }
1384}
1385
1386/** solver specified by rank died */
1387BbParaNode *
1389 int rank /**< rank of the dead solver */
1390 )
1391{
1392 if( rank < originRank || rank >= (signed)(originRank + nSolvers) )
1393 {
1394 THROW_LOGICAL_ERROR2("Rank = ", rank);
1395 }
1396 map<int, BbParaSolverPoolElementPtr>::iterator p;
1397 if ( pool[SOLVER_POOL_INDEX(rank)]->getStatus() == Active )
1398 {
1399 p = activeSolvers.find(rank);
1400 if( p != activeSolvers.end() )
1401 {
1402 if( p->second->getRank() != rank ||
1403 pool[SOLVER_POOL_INDEX(rank)]->getRank() != rank )
1404 {
1405 THROW_LOGICAL_ERROR2("Rank = ", rank);
1406 }
1407 nNodesSolvedInSolvers -= p->second->getNumOfNodesSolved();
1408 nNodesInSolvers -= p->second->getNumOfNodesLeft();
1409 activeSolvers.erase(p);
1410 }
1411 else
1412 {
1413 THROW_LOGICAL_ERROR2("Rank = ", rank);
1414 }
1415 }
1416 else
1417 {
1418 THROW_LOGICAL_ERROR2("Rank = ", rank);
1419 }
1420 selectionHeap->deleteElement(pool[SOLVER_POOL_INDEX(rank)]); /** need to have dual bound, so should be before died() */
1422 {
1424 }
1425 deadSolvers.insert(make_pair(rank,pool[SOLVER_POOL_INDEX(rank)]));
1426 return pool[SOLVER_POOL_INDEX(rank)]->died();
1427}
1428
1429/** switch out collecting mode */
1430void
1432 )
1433{
1434 if( !collectingMode )
1435 {
1436 return;
1437 }
1438 if( activeSolvers.size() > 0 )
1439 {
1440 map<int, BbParaSolverPoolElementPtr>::iterator p;
1441 for( p = activeSolvers.begin(); p != activeSolvers.end(); ++p)
1442 {
1443 int rank = p->second->getRank();
1445 if ( pool[SOLVER_POOL_INDEX(rank)]->isCandidateOfCollecting() )
1446 {
1448 /** clear candidatesOfCollectingModeSolvers in below */
1449 }
1451 pool[SOLVER_POOL_INDEX(rank)]->isDualBoundGainTesting() )
1452 {
1454 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoTestDualBoundGain )
1455 );
1458 }
1459 }
1460 }
1461 assert(nCollectingModeSolvers == 0);
1464 collectingMode = false;
1466}
1467
1468/** switch out collecting mode to the specified rank if it is necessary */
1469void
1471 int rank /**< rank of the solver */
1472 )
1473{
1474 /** sending TagOutCollectingMode is harmless */
1476 paraComm->send( NULL, 0, ParaBYTE, rank, TagOutCollectingMode )
1477 );
1478 /** pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() should be true */
1479 if ( !pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1480 {
1483 {
1485 }
1487 }
1488}
1489
1490/** switch out collecting mode to the specified rank */
1491void
1493 int rank
1494 )
1495{
1496 if ( !pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1497 {
1499 paraComm->send( NULL, 0, ParaBYTE, rank, TagOutCollectingMode )
1500 );
1503 {
1505 }
1507 }
1508}
1509
1510/** send switch in-collecting mode to a specific solver */
1511void
1513 int rank,
1514 BbParaNodePool *paraNodePool
1515 )
1516{
1517 // assert(nLimitCollectingModeSolvers > nCollectingModeSolvers); ** this is not hold anymore **
1518 int nCollect = std::min(pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft()/4,
1519 static_cast<int>(
1523 - (signed)paraNodePool->getNumOfGoodNodes(getGlobalBestDualBoundValue())));
1524 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
1526 {
1527 nCollect = 0 - (nCollect + 1); // indicate aggressive collecting
1528 }
1529 assert( pool[SOLVER_POOL_INDEX(rank)]->isGenerator() );
1530 assert( !pool[SOLVER_POOL_INDEX(rank)]->isCollectingProhibited() );
1531 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1532 {
1534 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1535 );
1536 }
1538 paraComm->send(&nCollect, 1, ParaINT, rank, TagInCollectingMode)
1539 );
1540 if( pool[SOLVER_POOL_INDEX(rank)]->isCandidateOfCollecting() )
1541 {
1542 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
1543 for( pCandidate = candidatesOfCollectingModeSolvers.begin();
1544 pCandidate != candidatesOfCollectingModeSolvers.end(); ++pCandidate )
1545 {
1546 if( pCandidate->second->getRank() == rank )
1547 break;
1548 }
1549 assert( pCandidate != candidatesOfCollectingModeSolvers.end() );
1550 pCandidate->second->setCandidateOfCollecting(false);
1551 candidatesOfCollectingModeSolvers.erase(pCandidate);
1552 }
1555 {
1557 }
1559}
1560
1561/** send switch in-collecting mode */
1562void
1564 BbParaNodePool *paraNodePool
1565 )
1566{
1569 (signed)paraNodePool->getNumOfGoodNodes(getGlobalBestDualBoundValue()) >
1571 )
1572 {
1573 return;
1574 }
1576 switchOutTime > 0 &&
1579 mCollectingNodes < 100 )
1580 {
1581 if( candidatesOfCollectingModeSolvers.size() > 0 &&
1582 candidatesOfCollectingModeSolvers.begin()->second->getNumOfDiffNodesLeft() < 0 )
1583 {
1585 if( mCollectingNodes <= 0 ) mCollectingNodes = 1;
1586 }
1587 else
1588 {
1591 {
1593 }
1594 }
1595 switchOutTime = -1.0;
1596 // std::cout << paraTimer->getElapsedTime() << " mCollectingNodes = " << mCollectingNodes << std::endl;
1597 }
1598 int nCollect = static_cast<int>(
1602 - (signed)paraNodePool->getNumOfGoodNodes(getGlobalBestDualBoundValue()));
1603 map<int, BbParaSolverPoolElementPtr>::iterator p;
1604 if( activeSolvers.size() > 0 )
1605 {
1607 {
1608 for( p = activeSolvers.begin();
1609 p != activeSolvers.end();
1610 ++p)
1611 {
1612 if( p->second->getRank() == 1 )
1613 {
1614 int rank = p->second->getRank();
1615 assert(pool[SOLVER_POOL_INDEX(rank)]->isGenerator());
1616 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1617 {
1619 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1620 );
1621 }
1623 paraComm->send(&nCollect, 1, ParaINT, rank, TagInCollectingMode )
1624 );
1625 nCollect = 0;
1628 {
1630 }
1632 break;
1633 }
1634 }
1635 }
1636 if( nCollect > 0 )
1637 {
1638 double globalBestDualBoundValue = selectionHeap->top()->getBestDualBoundValue();
1640 {
1641 case -1: // no ordering
1642 {
1643 for( p = activeSolvers.begin();
1645 ++p)
1646 {
1647 if( p->second->getNumOfNodesLeft() > 1 && /* Solver should have at least two nodes left */
1648 ( (p->second->getBestDualBoundValue() - globalBestDualBoundValue) /
1649 max( fabs(globalBestDualBoundValue), 1.0 ) ) < bgap )
1650 {
1651 int rank = p->second->getRank();
1652 if ( pool[SOLVER_POOL_INDEX(rank)]->isGenerator() &&
1653 pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1654 {
1655 int nCollectPerSolver = std::min(
1656 pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft()/4, nCollect );
1657 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
1659 {
1660 nCollectPerSolver = 0 - (nCollectPerSolver + 1); // indicate aggressive collecting
1661 }
1662 assert(pool[SOLVER_POOL_INDEX(rank)]->isGenerator());
1663 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1664 {
1666 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1667 );
1668 }
1670 paraComm->send(&nCollectPerSolver, 1, ParaINT, rank, TagInCollectingMode )
1671 );
1672 nCollect -= nCollectPerSolver;
1675 }
1676 }
1677 else
1678 {
1679 // The following code works, when the number of collecting mode solvers is increased
1680 if( !paraNodePool->isEmpty() &&
1681 ( ( (p->second->getBestDualBoundValue() - globalBestDualBoundValue) /
1682 max( fabs(globalBestDualBoundValue), 1.0 ) ) > ( bgap * mBgap ) ) )
1683 {
1684 int rank = p->second->getRank();
1686 }
1687 }
1688 }
1689 break;
1690 }
1691 case 0: // ordering by dual bound value
1692 {
1693
1694 std::multimap< double, int > boundOrderMap;
1695 for( p = activeSolvers.begin(); p != activeSolvers.end(); ++p )
1696 {
1697 boundOrderMap.insert(std::make_pair(p->second->getBestDualBoundValue(),p->second->getRank()));
1698 }
1699 std::multimap< double, int >::iterator pbo;
1700 for( pbo = boundOrderMap.begin();
1701 pbo != boundOrderMap.end() && nLimitCollectingModeSolvers > nCollectingModeSolvers;
1702 ++pbo )
1703 {
1704 int rank = pbo->second;
1705 if( pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft() > 1 ) // Solver should have at least two nodes left
1706 {
1707 if ( pool[SOLVER_POOL_INDEX(rank)]->isGenerator() &&
1708 pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1709 {
1710 int nCollectPerSolver = std::min(
1711 pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft()/4, nCollect );
1712 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
1714 {
1715 nCollectPerSolver = 0 - (nCollectPerSolver + 1); // indicate aggressive collecting
1716 }
1717 assert(pool[SOLVER_POOL_INDEX(rank)]->isGenerator());
1718 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1719 {
1721 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1722 );
1723 }
1725 paraComm->send(&nCollectPerSolver, 1, ParaINT, rank, TagInCollectingMode )
1726 );
1727 nCollect -= nCollectPerSolver;
1728 if( pool[SOLVER_POOL_INDEX(rank)]->isCandidateOfCollecting() )
1729 {
1730 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
1731 for( pCandidate = candidatesOfCollectingModeSolvers.begin();
1732 pCandidate != candidatesOfCollectingModeSolvers.end(); ++pCandidate )
1733 {
1734 if( pCandidate->second->getRank() == rank )
1735 break;
1736 }
1737 assert( pCandidate != candidatesOfCollectingModeSolvers.end() );
1738 pCandidate->second->setCandidateOfCollecting(false);
1739 candidatesOfCollectingModeSolvers.erase(pCandidate);
1740 }
1742 assert( collectingModeSolverHeap );
1745 }
1746 else // pool[SOLVER_POOL_INDEX(rank)] is in collecting mode
1747 {
1748 if( pool[SOLVER_POOL_INDEX(rank)]->isGenerator() )
1749 {
1750 assert( pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() ); // No collecting mode soler exists. Never comes here.
1751 THROW_LOGICAL_ERROR2("Logical Error. All solvers are not in collecting mode. rank = ", rank);
1752 // The following code works, when the number of collecting mode solvers is increased
1753 if( !paraNodePool->isEmpty() &&
1754 ( ( (pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() - globalBestDualBoundValue) /
1755 max( fabs(globalBestDualBoundValue), 1.0 ) ) > ( bgap * mBgap ) ) )
1756 {
1758 }
1759 else // re-boost the collecting mode solver
1760 {
1762 int nCollectPerSolver = std::min(
1763 pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft()/4, nCollect );
1764 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
1766 {
1767 nCollectPerSolver = 0 - (nCollectPerSolver + 1); // indicate aggressive collecting
1768 }
1769 assert(pool[SOLVER_POOL_INDEX(rank)]->isGenerator());
1770 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1771 {
1773 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1774 );
1775 }
1777 paraComm->send(&nCollectPerSolver, 1, ParaINT, rank, TagInCollectingMode )
1778 );
1779 nCollect -= nCollectPerSolver;
1781 assert( collectingModeSolverHeap );
1783 // the solvers was already in collecting mode, so do not have to nCollectingModeSolvers++;
1784 }
1785 }
1786 }
1787 }
1788 }
1789 for(; pbo != boundOrderMap.end() &&
1790 static_cast<int>( candidatesOfCollectingModeSolvers.size() )
1791 < std::min((int)nLimitCollectingModeSolvers,
1793 ++pbo )
1794 {
1795 int rank = pbo->second;
1796 if( pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft() > 1 &&
1797 pool[SOLVER_POOL_INDEX(rank)]->isGenerator() &&
1798 ( !pool[SOLVER_POOL_INDEX(rank)]->isCandidateOfCollecting() ) )
1799 {
1801 make_pair(pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue(),pool[SOLVER_POOL_INDEX(rank)])
1802 );
1804 }
1805 }
1806 break;
1807 }
1808 case 1: // ordering by number of nodes left
1809 {
1810 std::multimap< int, int > nNodesOrderMap;
1811 for( p = activeSolvers.begin(); p != activeSolvers.end(); ++p )
1812 {
1813 nNodesOrderMap.insert(std::make_pair(p->second->getNumOfNodesLeft(),p->second->getRank()));
1814 }
1815 std::multimap< int, int >::iterator pno;
1816 for( pno = nNodesOrderMap.begin();
1817 pno != nNodesOrderMap.end() && nLimitCollectingModeSolvers > nCollectingModeSolvers;
1818 ++pno )
1819 {
1820 int rank = pno->second;
1821 if( pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft() > 1 && /* Solver should have at least two nodes left */
1822 pool[SOLVER_POOL_INDEX(rank)]->isGenerator() &&
1823 ( (pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() - globalBestDualBoundValue) /
1824 max( fabs(globalBestDualBoundValue), 1.0 ) ) < bgap )
1825 {
1826 if ( pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1827 {
1828 int nCollectPerSolver = std::min(
1829 pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft()/4, nCollect );
1830 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
1832 {
1833 nCollectPerSolver = 0 - (nCollectPerSolver + 1); // indicate aggressive collecting
1834 }
1835 assert(pool[SOLVER_POOL_INDEX(rank)]->isGenerator());
1836 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1837 {
1839 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1840 );
1841 }
1843 paraComm->send(&nCollectPerSolver, 1, ParaINT, rank, TagInCollectingMode )
1844 );
1845 nCollect -= nCollectPerSolver;
1848 }
1849 }
1850 else
1851 {
1852 // The following code works, when the number of collecting mode solvers is increased
1853 if( !paraNodePool->isEmpty() &&
1854 ( ( (pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() - globalBestDualBoundValue) /
1855 max( fabs(globalBestDualBoundValue), 1.0 ) ) > ( bgap * mBgap ) ) )
1856 {
1858 }
1859 }
1860 }
1861 break;
1862 }
1863 case 2: // choose alternatively the best bound and the number of nodes orders
1864 {
1865 std::multimap< double, int > boundOrderMap;
1866 for( p = activeSolvers.begin(); p != activeSolvers.end(); ++p )
1867 {
1868 boundOrderMap.insert(std::make_pair(p->second->getBestDualBoundValue(),p->second->getRank()));
1869 }
1870 std::multimap< int, int > nNodesOrderMap;
1871 for( p = activeSolvers.begin(); p != activeSolvers.end(); ++p )
1872 {
1873 nNodesOrderMap.insert(std::make_pair(p->second->getNumOfNodesLeft(),p->second->getRank()));
1874 }
1875 std::multimap< double, int >::iterator pbo;
1876 std::multimap< int, int >::iterator pno;
1877 pbo = boundOrderMap.begin();
1878 pno = nNodesOrderMap.begin();
1879 bool boundOrderSection = true;
1880 while( pbo != boundOrderMap.end()
1881 && pno != nNodesOrderMap.end()
1883 {
1884 int rank;
1885 if( boundOrderSection )
1886 {
1887 if( pbo != boundOrderMap.end() )
1888 {
1889 rank = pbo->second;
1890 pbo++;
1891 boundOrderSection = false;
1892 }
1893 else
1894 {
1895 boundOrderSection = false;
1896 continue;
1897 }
1898 }
1899 else
1900 {
1901 if( pno != nNodesOrderMap.end() )
1902 {
1903 rank = pno->second;
1904 pno++;
1905 boundOrderSection = true;
1906 } else {
1907 boundOrderSection = true;
1908 continue;
1909 }
1910 }
1911 if( pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft() > 1 && /* Solver should have at least two nodes left */
1912 pool[SOLVER_POOL_INDEX(rank)]->isGenerator() &&
1913 ( (pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() - globalBestDualBoundValue) /
1914 max( fabs(globalBestDualBoundValue), 1.0 ) ) < bgap )
1915 {
1916 if ( pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
1917 {
1918 int nCollectPerSolver = std::min(
1919 pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft()/4, nCollect );
1920 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
1922 {
1923 nCollectPerSolver = 0 - (nCollectPerSolver + 1); // indicate aggressive collecting
1924 }
1925 assert(pool[SOLVER_POOL_INDEX(rank)]->isGenerator());
1926 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
1927 {
1929 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
1930 );
1931 }
1933 paraComm->send(&nCollectPerSolver, 1, ParaINT, rank, TagInCollectingMode )
1934 );
1935 nCollect -= nCollectPerSolver;
1938 }
1939 }
1940 else
1941 {
1942 // The following code works, when the number of collecting mode solvers is increased
1943 if( !paraNodePool->isEmpty() &&
1944 ( ( (pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() - globalBestDualBoundValue) /
1945 max( fabs(globalBestDualBoundValue), 1.0 ) ) > ( bgap * mBgap ) ) )
1946 {
1948 }
1949 }
1950 }
1951 break;
1952 }
1953 default:
1954 THROW_LOGICAL_ERROR2("paraParams->getIntParamValue(SolverOrderInCollectingMode) = ", paraParams->getIntParamValue(SolverOrderInCollectingMode));
1955 }
1956 }
1957 }
1958 collectingMode = true;
1960 beforeInitialCollect = false;
1961}
1962
1963void
1965 int rank,
1966 long long numOfNodesSolved,
1967 int numOfNodesLeft,
1968 double solverLocalBestDualBound,
1969 BbParaNodePool *paraNodePool
1970 )
1971{
1972 map<int, BbParaSolverPoolElementPtr>::iterator p;
1973 p = activeSolvers.find(rank);
1974 if( p != activeSolvers.end() )
1975 {
1976 if( (numOfNodesSolved - p->second->getNumOfNodesSolved() ) < 0 )
1977 {
1978 std::cout << "numOfNodesSolved = " << numOfNodesSolved << ", p->second->getNumOfNodesSolved() = " << p->second->getNumOfNodesSolved() << std::endl;
1979 THROW_LOGICAL_ERROR2("Rank = ", rank);
1980 }
1981 // assert( (numOfNodesSolved - p->second->getNumOfNodesSolved() ) >= 0 ); // if solver restart, this is not always true
1982 nNodesSolvedInSolvers += numOfNodesSolved - p->second->getNumOfNodesSolved();
1983 // if(nNodesSolvedInSolvers > 999) abort();
1984 nNodesInSolvers += numOfNodesLeft - p->second->getNumOfNodesLeft();
1985 p->second->setNumOfDiffNodesSolved( numOfNodesSolved - p->second->getNumOfNodesSolved() );
1986 p->second->setNumOfNodesSolved(numOfNodesSolved);
1987 p->second->setNumOfDiffNodesLeft( numOfNodesLeft - p->second->getNumOfNodesLeft() );
1988 p->second->setNumOfNodesLeft(numOfNodesLeft);
1989 if( p->second->getBestDualBoundValue() < solverLocalBestDualBound ) // even in LP solving, solver may notify its status
1990 {
1991 p->second->setDualBoundValue(solverLocalBestDualBound);
1992 selectionHeap->updateDualBoundValue(*(p->second->getSelectionHeapElement()), solverLocalBestDualBound);
1993 if( p->second->isInCollectingMode() )
1994 {
1996 {
1997 collectingModeSolverHeap->updateDualBoundValue(*(p->second->getCollectingModeSolverHeapElement()), solverLocalBestDualBound);
1998 }
1999 }
2000 }
2001 }
2002 else
2003 {
2004 THROW_LOGICAL_ERROR2("Rank = ", rank);
2005 }
2006 double globalBestDualBoundValue = selectionHeap->top()->getBestDualBoundValue();
2007 if( globalBestDualBoundValue > p->second->getBestDualBoundValue() )
2008 {
2009 std::cout << "Top rank = " << selectionHeap->top()->getRank() << std::endl;
2010 std::cout << "Top bound = " << selectionHeap->top()->getBestDualBoundValue() << std::endl;
2011 std::cout << "This bound = " << p->second->getBestDualBoundValue() << std::endl;
2012 std::cout << "myRank = " << rank << std::endl;
2013 std::cout << "solverLocalBestDualBound = " << p->second->getBestDualBoundValue() << std::endl;
2014 std::cout << selectionHeap->toString();
2016 {
2017 std::cout << collectingModeSolverHeap->toString();
2018 }
2019 abort();
2020 }
2021
2022 if( pool[SOLVER_POOL_INDEX(rank)]->isDualBoundGainTesting()
2023 && numOfNodesSolved > 1 )
2024 {
2027 }
2028
2029 if( collectingMode )
2030 {
2031 int nCollect = 0; // assume zero
2033 {
2038 {
2040 {
2042 }
2043 else // nLimitCollectingModeSolvers == nCollectingModeSolvers
2044 {
2045 if( pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() - absoluteGap
2047 {
2048 if( !( breakingFirstSubtree && rank == 1 ) )
2049 {
2050 if( !paraNodePool->isEmpty() )
2051 {
2053 }
2055 }
2056 }
2057 }
2058 }
2059 else
2060 {
2063 ( p->second->getBestDualBoundValue() - collectingModeSolverHeap->top()->getBestDualBoundValue() ) > absoluteGap && // the notified solver is no so good
2064 ( (!candidatesOfCollectingModeSolvers.empty()) &&
2065 ( candidatesOfCollectingModeSolvers.begin()->second->getBestDualBoundValue() + absoluteGap ) // to avoid flip
2066 < p->second->getBestDualBoundValue() ) //promising candidates exists
2067 )
2068 {
2069 assert( p->second->getRank() == rank );
2070 assert( rank != selectionHeap->top()->getRank() );
2071 if( !paraNodePool->isEmpty() )
2072 {
2074 }
2075
2076 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
2077 pCandidate = candidatesOfCollectingModeSolvers.begin();
2078 assert( pCandidate->second->isOutCollectingMode() );
2079 // nCollect = std::min(selectionHeap->top()->getNumOfNodesLeft()/4,
2080 nCollect = std::min(pCandidate->second->getNumOfNodesLeft()/4,
2081 static_cast<int>(
2085 - (signed)paraNodePool->getNumOfGoodNodes(getGlobalBestDualBoundValue())));
2086 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
2088 {
2089 nCollect = 0 - (nCollect + 1); // indicate aggressive collecting
2090 }
2091 assert(pool[SOLVER_POOL_INDEX(pCandidate->second->getRank())]->isGenerator());
2092 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
2093 {
2095 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
2096 );
2097 }
2099 paraComm->send(&nCollect, 1, ParaINT, pCandidate->second->getRank(), TagInCollectingMode)
2100 );
2101 pCandidate->second->setCollectingMode(true);
2102 collectingModeSolverHeap->insert( pCandidate->second );
2104 pCandidate->second->setCandidateOfCollecting(false);
2105 candidatesOfCollectingModeSolvers.erase(pCandidate);
2106 }
2107 else
2108 {
2109 if( !paraNodePool->isEmpty() &&
2110 ( ( ( ( p->second->getBestDualBoundValue() - globalBestDualBoundValue ) /
2111 max( fabs(globalBestDualBoundValue), 1.0 ) ) > ( bgap * mBgap ) ) ) )
2112 {
2113 sendSwitchOutCollectingModeIfNecessary( p->second->getRank() );
2114 }
2115 }
2116 }
2117 }
2118 else // current notification solver is out collecting mode
2119 {
2121 {
2122 if( pool[SOLVER_POOL_INDEX(rank)]->getRank() == selectionHeap->top()->getRank() &&
2123 pool[SOLVER_POOL_INDEX(rank)]->isGenerator() &&
2124 (!pool[SOLVER_POOL_INDEX(rank)]->isCollectingProhibited()) &&
2126 {
2127 switchInCollectingToSolver(rank, paraNodePool);
2128 }
2129 }
2130 else // nLimitCollectingModeSolvers == nCollectingModeSolvers
2131 {
2132 if( !paraNodePool->isEmpty() &&
2133 pool[SOLVER_POOL_INDEX(rank)]->getNumOfDiffNodesLeft() > 1 &&
2136 ( pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue() + absoluteGap )
2138 {
2140 }
2141 }
2142 }
2143
2144 bool manyIdleSolversExist = false;
2145 if( getNumInactiveSolvers() > nSolvers/4 ) manyIdleSolversExist = true;
2147 {
2148 if( manyIdleSolversExist )
2149 {
2150 double temp = switchOutTime;
2152 switchOutTime = temp;
2153 switchInCollectingMode(paraNodePool);
2154 }
2155 else
2156 {
2157 if( selectionHeap->top()->getNumOfNodesLeft() > 1 &&
2161 {
2163 }
2164 else
2165 {
2167 {
2168 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
2169 pCandidate = candidatesOfCollectingModeSolvers.begin();
2170 assert( pCandidate->second->isOutCollectingMode() );
2171 nCollect = std::min(pCandidate->second->getNumOfNodesLeft()/4,
2172 static_cast<int>(
2176 - (signed)paraNodePool->getNumOfGoodNodes(getGlobalBestDualBoundValue())));
2177 if( (signed)paraNodePool->getNumOfGoodNodes( getGlobalBestDualBoundValue()) <
2179 {
2180 nCollect = 0 - (nCollect + 1); // indicate aggressive collecting
2181 }
2182 assert(pool[SOLVER_POOL_INDEX(pCandidate->second->getRank())]->isGenerator());
2183 if( paraNodePool->isEmpty() && nLimitCollectingModeSolvers > 10 )
2184 {
2186 paraComm->send(NULL, 0, ParaBYTE, rank, TagNoWaitModeSend )
2187 );
2188 }
2190 paraComm->send(&nCollect, 1, ParaINT, pCandidate->second->getRank(), TagInCollectingMode)
2191 );
2192 pCandidate->second->setCollectingMode(true);
2194 {
2195 collectingModeSolverHeap->insert( pCandidate->second );
2196 }
2198 pCandidate->second->setCandidateOfCollecting(false);
2199 candidatesOfCollectingModeSolvers.erase(pCandidate);
2200 }
2201 else
2202 {
2203 assert( rank == p->second->getRank() );
2204 if( p->second->getNumOfNodesLeft() > 1 && // Solver should have at least two nodes left //
2205 p->second->isGenerator() &&
2206 ( !p->second->isCollectingProhibited() ) &&
2207 p->second->isOutCollectingMode() &&
2208 ( paraNodePool->isEmpty() ||
2209 ( ( ( p->second->getBestDualBoundValue() - globalBestDualBoundValue ) /
2210 max( fabs(globalBestDualBoundValue), 1.0 ) ) < bgap ) ) ) // &&
2211 {
2212 switchInCollectingToSolver(rank, paraNodePool);
2213 }
2214 }
2215 }
2216 }
2217 }
2218 else // nLimitCollectingModeSolvers == nCollectingModeSolvers
2219 {
2220 if ( pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
2221 {
2223 {
2224 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
2225 if( p->second->isCandidateOfCollecting() )
2226 {
2227 for( pCandidate = candidatesOfCollectingModeSolvers.begin();
2228 pCandidate != candidatesOfCollectingModeSolvers.end(); ++pCandidate )
2229 {
2230 if( pCandidate->second->getRank() == rank )
2231 break;
2232 }
2233 if( pCandidate == candidatesOfCollectingModeSolvers.end() )
2234 {
2235 THROW_LOGICAL_ERROR3("rank = ", rank , " is not in candidatesOfCollectingModeSolvers.");
2236 }
2237 /* anyway remove to update dual bound value */
2238 pCandidate->second->setCandidateOfCollecting(false);
2239 candidatesOfCollectingModeSolvers.erase(pCandidate);
2240 }
2241 if( static_cast<int>( candidatesOfCollectingModeSolvers.size() )
2242 == std::min((signed)nLimitCollectingModeSolvers,
2244 {
2245 std::multimap< double, BbParaSolverPoolElementPtr >::reverse_iterator prCandidate;
2246 prCandidate = candidatesOfCollectingModeSolvers.rbegin();
2247 if( p->second->getNumOfNodesLeft() > 1 &&
2248 p->second->isGenerator() &&
2249 prCandidate->second->getBestDualBoundValue() > p->second->getBestDualBoundValue() )
2250 {
2251 BbParaSolverPoolElementPtr tCandidate = prCandidate->second;
2252 // prCandidate->second->setCandidateOfCollecting(false);
2253 ++prCandidate;
2254 assert(prCandidate.base()->second == tCandidate);
2255 if( prCandidate.base()->second != tCandidate )
2256 {
2257 THROW_LOGICAL_ERROR4("prCandidate.base()->second != tCandidate, prCandidate.base()->second = ", prCandidate.base()->second, ", tCandidate = ", tCandidate );
2258 }
2259 prCandidate.base()->second->setCandidateOfCollecting(false);
2260 candidatesOfCollectingModeSolvers.erase(prCandidate.base());
2262 make_pair(p->second->getBestDualBoundValue(),p->second)
2263 );
2264 p->second->setCandidateOfCollecting(true);
2265 }
2266 }
2267 else // candidatesOfCollectingModeSolvers.size()
2268 // < std::min(nLimitCollectingModeSolvers,
2269 // paraParams->getIntParamValue(NMaxCanditatesForCollecting)
2270 {
2273 p->second->getNumOfNodesLeft() > 1 &&
2274 p->second->isGenerator() &&
2275 ( p->second->getBestDualBoundValue() - collectingModeSolverHeap->top()->getBestDualBoundValue() ) < absoluteGap )
2276 {
2278 make_pair(p->second->getBestDualBoundValue(),p->second)
2279 );
2280 p->second->setCandidateOfCollecting(true);
2281 // p->second solver is in collecting mode, when the current collecting mode solver notifies.
2282 }
2283 }
2284 }
2285 else // candidatesOfCollectingModeSolvers is empty
2286 {
2289 p->second->getNumOfNodesLeft() > 1 &&
2290 p->second->isGenerator() &&
2291 ( p->second->getBestDualBoundValue() - collectingModeSolverHeap->top()->getBestDualBoundValue() ) < absoluteGap )
2292 {
2294 make_pair(p->second->getBestDualBoundValue(),p->second)
2295 );
2296 p->second->setCandidateOfCollecting(true);
2297 // p->second solver is in collecting mode, when the current collecting mode solver notifies.
2298 }
2299 }
2300 }
2301 }
2302#ifdef _DEBUG_LB
2303 std::cout << "ASBD = " << selectionHeap->top()->getBestDualBoundValue() << "(" << selectionHeap->top()->getRank() << ")";
2305 {
2306 std::cout << ", CMSBD = " << collectingModeSolverHeap->top()->getBestDualBoundValue() << "(" << collectingModeSolverHeap->top()->getRank() << ")";
2307 }
2309 {
2310 std::cout << ", CCSBD = ";
2311 std::multimap< double, BbParaSolverPoolElementPtr >::iterator pCandidate;
2312 for( pCandidate = candidatesOfCollectingModeSolvers.begin();
2313 pCandidate != candidatesOfCollectingModeSolvers.end(); ++pCandidate )
2314 {
2315 std::cout << ", " << pCandidate->second->getBestDualBoundValue() << "(" << pCandidate->second->getRank() << ")";
2316 }
2317 }
2318 std::cout << std::endl;
2319#endif
2320 }
2321 else
2322 {
2323 if( !pool[SOLVER_POOL_INDEX(rank)]->isOutCollectingMode() )
2324 {
2325 THROW_LOGICAL_ERROR2("Not Out collecting mode: Rank = ", rank);
2326 }
2327 }
2328}
2329
2330void
2332 int rank,
2333 long long numOfNodesSolved,
2334 int numOfNodesLeft,
2335 double solverLocalBestDualBound
2336 )
2337{
2338 if( pool[SOLVER_POOL_INDEX(rank)]->getStatus() != Racing &&
2339 pool[SOLVER_POOL_INDEX(rank)]->getStatus() != RacingEvaluation )
2340 {
2341 std::cout << "Tried to update no racing status solver's info." << std::endl;
2342 std::cout << "Update solver rank = " << rank << std::endl;
2343 abort();
2344 }
2345
2346
2347 if( paraParams->getIntParamDefaultValue(RacingRampUpTerminationCriteria) == 0 ) // Criterion is the number of nodes
2348 {
2351 {
2354 }
2356 numOfNodesLeft < paraParams->getIntParamDefaultValue(StopRacingNumberOfNodesLeft) )
2357 {
2360 }
2361
2362 } else {
2364 {
2367 }
2368 }
2370 pool[SOLVER_POOL_INDEX(rank)]->setNumOfNodesSolved(numOfNodesSolved);
2371 pool[SOLVER_POOL_INDEX(rank)]->setNumOfDiffNodesLeft( numOfNodesLeft - pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft() );
2372 pool[SOLVER_POOL_INDEX(rank)]->setNumOfNodesLeft(numOfNodesLeft);
2373// if( rank != originRank ||
2374// ( paraParams->getIntParamValue(UgCplexRunningMode) != 1 ) )
2375// if( rank != originRank )
2376// {
2377// int prviousTop = selectionHeap->top()->getRank();
2378 selectionHeap->updateDualBoundValue(*(pool[SOLVER_POOL_INDEX(rank)]->getSelectionHeapElement()), solverLocalBestDualBound);
2379// if( selectionHeap->top()->getRank() == rank || selectionHeap->top()->getRank() != prviousTop )
2380// {
2381 nNodesInBestSolver = selectionHeap->top()->getNumOfNodesLeft(); // in racing ramp-up, winner nodes should be the number of nodes left
2383// }
2384 if( selectionHeap->getHeapSize() > 0 )
2385 {
2387 {
2389 }
2390 }
2391// }
2392
2393 if( bestDualBoundInSolvers < solverLocalBestDualBound )
2394 {
2395 bestDualBoundInSolvers = solverLocalBestDualBound;
2396 }
2397
2398}
2399
2400bool
2402 bool feasibleSol
2403 )
2404{
2407 {
2408 case 0: /** stop racing at the number of nodes left in a solver reached to the value */
2409 {
2414 {
2415
2417 {
2419 return true;
2420 }
2421 }
2422 break;
2423 }
2424 case 1: /** stop racing at time limit */
2425 {
2426 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2427 {
2429 {
2431 {
2433 return true;
2434 }
2435 }
2436 else
2437 {
2439 {
2441 return true;
2442 }
2443 }
2444 }
2445 break;
2446 }
2447 case 2: /** stop racing at the Solver with the best bound value has a certain number of nodes left */
2448 {
2449 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2450 {
2452 {
2454 return true;
2455 }
2456 }
2457 break;
2458 }
2459 case 3: /** node left first adaptive */
2460 {
2463 {
2464 return false;
2465 }
2466 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2467 {
2469 {
2471 return true;
2472 }
2473
2475 {
2477 {
2479 return true;
2480 }
2481 }
2482 else
2483 {
2485 {
2487 return true;
2488 }
2489 }
2490 }
2491 break;
2492 }
2493 case 4: /** time limit first adaptive */
2494 {
2495 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2496 {
2498 {
2500 {
2502 return true;
2503 }
2504
2507 {
2508 return false;
2509 }
2510 else
2511 {
2513 {
2515 return true;
2516 }
2517 }
2518 }
2519 else
2520 {
2522 {
2524 return true;
2525 }
2528 {
2529 return false;
2530 }
2531 else
2532 {
2534 {
2536 return true;
2537 }
2538 }
2539 }
2540 }
2541 break;
2542 }
2543 case 5: /** node left first adaptive - adaptive node left (Default settings): this is for FiberSCIP */
2544 {
2545 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2546 {
2547 if( paraParams->getBoolParamValue(KeepRacingUntilToFindFirstSolution) && (!feasibleSol) ) return false; // no feasible solution keeps racing
2549 {
2550 return false;
2551 }
2552
2555 {
2557 {
2559 return true;
2560 }
2561 else
2562 {
2565 {
2567 return true;
2568 }
2570 {
2573 {
2575 return true;
2576 }
2577 }
2578 else
2579 {
2580 if( paraTimer->getElapsedTime() >
2582 {
2584 return true;
2585 }
2586 }
2587 }
2588 }
2589 else
2590 {
2592 {
2594 {
2596 {
2598 {
2600 return true;
2601 }
2602 else
2603 {
2606 {
2608 return true;
2609 }
2610 }
2611 }
2612 }
2613 }
2614 else
2615 {
2617 {
2619 {
2621 {
2623 return true;
2624 }
2625 else
2626 {
2627 if( paraTimer->getElapsedTime() >
2629 {
2631 return true;
2632 }
2633 }
2634 }
2635 }
2636 }
2637 }
2638 }
2639 break;
2640 }
2641 case 6: /** time limit first adaptive - adaptive node left */
2642 {
2643 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2644 {
2645 if( paraParams->getBoolParamValue(KeepRacingUntilToFindFirstSolution) && (!feasibleSol) ) return false; // no feasible solution keeps racing
2647 {
2648 return false;
2649 }
2650
2652 {
2654 {
2656 {
2658 return true;
2659 }
2660 else
2661 {
2664 {
2666 return true;
2667 }
2668 }
2669 }
2670 }
2671 else
2672 {
2674 {
2676 {
2678 return true;
2679 }
2680 else
2681 {
2682 if( paraTimer->getElapsedTime() >
2684 {
2686 return true;
2687 }
2688 }
2689 }
2690 }
2691 }
2692 break;
2693 }
2694 case 7: /** time limit first adaptive and node limit also checked - adaptive node left */
2695 {
2696 if( nEvaluationStage >= static_cast<int>(nSolvers*solverRatio) ) // some solver may not reply at racing
2697 {
2698 if( paraParams->getBoolParamValue(KeepRacingUntilToFindFirstSolution) && (!feasibleSol) ) return false; // no feasible solution keeps racing
2700 {
2701 return false;
2702 }
2703
2705 {
2707 {
2709 {
2711 return true;
2712 }
2713 else
2714 {
2717 {
2719 return true;
2720 }
2721 }
2722 }
2723 else
2724 {
2727 {
2729 return true;
2730 }
2731 }
2732 }
2733 else
2734 {
2736 {
2738 {
2740 return true;
2741 }
2742 else
2743 {
2744 if( paraTimer->getElapsedTime() >
2746 {
2748 return true;
2749 }
2750 }
2751 }
2752 else
2753 {
2756 {
2758 return true;
2759 }
2760 }
2761 }
2762 }
2763 break;
2764 }
2765 default:
2766 THROW_LOGICAL_ERROR1("invalid racing ramp-up termination criteria");
2767 }
2768 return false;
2769}
2770
Base class of communicator for UG Framework.
Parameter set for UG framework.
Solver pool.
virtual void updateDualBoundValue(BbParaSolverPoolElementPtr solver, double value)
update CollectingModeSolver heap by a new dual bound value of this Solver
AscendingCollectingModeSolverHeap(std::size_t size)
constructor
virtual void deleteElement(BbParaSolverPoolElementPtr solver)
delete BbParaSolverPoolElementPtr from CollectingModeSolver Heap
virtual void downHeap(std::size_t pos)
down heap
virtual void upHeap(std::size_t pos)
up heap
virtual void updateDualBoundValue(BbParaSolverPoolElementPtr solver, double value)
update selection heap by a new dual bound value of this Solver
AscendingSelectionHeap(std::size_t size)
constructor
virtual void deleteElement(BbParaSolverPoolElementPtr solver)
delete BbParaSolverPoolElementPtr from Selection Heap
virtual void downHeap(std::size_t pos)
down heap
virtual void upHeap(std::size_t pos)
up heap
class BbParaNodePool
virtual bool isEmpty()=0
check if this pool is empty or not
virtual unsigned int getNumOfGoodNodes(double globalBestBound)=0
get number of good (heavy) BbParaNodes in this pool
class BbParaNode
Definition: bbParaNode.h:62
int getMergingStatus()
get merging status
Definition: bbParaNode.h:678
BbParaMergeNodeInfo * getMergeNodeInfo()
get merge node information struct
Definition: bbParaNode.h:658
virtual int send(ParaComm *comm, int destination)=0
send this object
BbParaNode * next
this pointer is used in case of self-split ramp-up in LC this field is not transferred
Definition: bbParaNode.h:83
class BbParaRacingSolverPool (Racing Solver Pool)
double bestDualBoundInSolvers
best dual bound value in Solvers
long long nNodesSolvedInBestSolver
number of nodes solved in the best Solver
BbParaSolverPoolElementPtr * pool
Solver pool indexed by Solver's rank.
long long nNodesInBestSolver
number of nodes in the best Solver
virtual bool isSolverActive(int rank)
check if the specified Solver is active or not
int nEvaluationStage
number of Solvers that are in evaluation stage
double bestDualBound
current best dual bound value
virtual void updateSolverStatus(int rank, long long numNodesSolved, int numNodesLeft, double solverLocalBestBound)
update Solver status
virtual long long getNumOfNodesSolved(int rank)
get number of nodes solved in the Solver specified by rank
SelectionHeap * selectionHeap
pointers to active Solvers in ascending or descending order
virtual bool isWinnerDecided(bool feasibleSol)
check racing termination criteria
virtual bool isEvaluationStage(int rank)
check if the Solver specified in an argument is evaluation stage or not
class BbParaSolverPoolElement (This class includes information about a Solver status)
long long getNumOfNodesSolved()
get number of nodes solved
void setDualBoundGainTesting(bool value)
set dual bound gain is testing value
void activate(BbParaNode *inNode)
activate this Solver
void setCollectingModeSolverHeapElement(BbParaSolverPoolElementPtr *inCollectingModeSolverHeapElement)
set collecting mode Solver heap element
int getNumOfNodesLeft()
get number of nodes left
bool isOutCollectingMode()
check if this Solver is out of collecting mode or not
void setCollectingMode(bool b)
set collecting mode
void setSelectionHeapElement(BbParaSolverPoolElementPtr *inSelectionHeapElement)
set selection heap element
BbParaSolverPoolElementPtr * getSelectionHeapElement()
extract current solving BbParaNode
void setCollectingIsAllowed()
allows to be in collecting mode
void setNumOfDiffNodesSolved(int inNumOfDiff)
set number of nodes left difference between current number and that in the previous notification time
void switchIntoEvaluation()
switch into evaluation stage
void setBestDualBoundValue(double inBestDualBoundValue)
set best dual bound value
void setNumOfNodesSolved(long long inNumOfNodesSolved)
set number of nodes solved
void setNumOfNodesLeft(int inNumOfNodesLeft)
set number of nodes left
void switchOutEvaluation()
switch out of evaluation stage
BbParaNode * extractCurrentNode()
extract current solving BbParaNode
bool isGenerator()
check if this Solver is generator or not *‍/
BbParaNode * died()
kill this Solver
int getRank()
get rank of the Solver
void setCandidateOfCollecting(bool b)
set candidate of collecting mode Solver
SolverStatus getStatus()
get Solver status
bool isCollectingProhibited()
check if this Solver cannot be allowed in collecting mode
void setNumOfDiffNodesLeft(int inNumOfDiff)
set number of nodes left difference between current number and that in the previous notification time
bool isInCollectingMode()
check if this Solver is in collecting mode or not
double getBestDualBoundValue()
get best dual bound value
void prohibitCollectingMode()
prohibits to be in collecting mode
BbParaNode * extractSelfSplitNodes()
extract a list of nodes which are generated by self-split ramp-up
void inactivate()
inactivate this Solver
BbParaSolverPoolElementPtr * getCollectingModeSolverHeapElement()
get collecting mode Solver heap element
int getNumOfDiffNodesLeft()
get number of nodes left difference between current number and that in the previous notification time
virtual double getGlobalBestDualBoundValue()
get global best dual bound value
virtual void updateSolverStatus(int rank, long long numNodesSolved, int numNodesLeft, double solverLocalBestBound, BbParaNodePool *paraNodePool)
update Solver status
virtual void switchInCollectingMode(BbParaNodePool *paraNodePool)
switch in collecting mode
virtual void activateSolver(int rank, BbParaNode *node, int nGoodNodesInNodePool, double averageDualBoundGain)
activate the Solver specified by rank with specified node which has been sent
bool active
indicate if this pool is active or not
int mCollectingNodes
multiplier for the number of collecting BbParaNodes
virtual std::size_t getNumInactiveSolvers()
get number of inactive Solvers
virtual void deleteCurrentSubtreeRootNode(int rank)
delete current self-split subtree root node from the active solver with the specified rank
virtual void switchInCollectingToSolver(int rank, BbParaNodePool *paraNodePool)
switch a Solver to be in collecting mode
virtual BbParaNode * extractSelfSplitSubtreeRootNode(int rank, BbParaNode *node)
extract self-split subtree root node from the active solver with the specified rank
std::size_t nLimitCollectingModeSolvers
limit number of Solvers that can be in collecting mode
double bgap
threshold value of gap
int mMaxCollectingNodes
maximum multiplier for the number of collecting BbParaNodes
virtual void switchOutCollectingMode()
switch out collecting mode
BbParaSolverPoolElementPtr * pool
Solver pool indexed by Solver's rank.
unsigned long long nNodesSolvedInSolvers
number of nodes solved in current running Solvers
bool breakingFirstSubtree
breaking the first subtree
double switchOutTime
switch out time
virtual bool isInCollectingMode()
check if this system is in collecting mode or not
virtual void sendSwitchOutCollectingModeIfNecessary(int rank)
switch out collecting mode of the Solver specified by rank if it is necessary
std::map< int, BbParaSolverPoolElementPtr > deadSolvers
pointers to dead Solvers
bool beforeFinishingFirstCollect
before finishing first collecting mode
virtual double getGlobalBestDualBoundValue()=0
get global best dual bound value
double absoluteGap
allowable absolute dual bound gap to the best Solver
virtual void makeSubtreeRootNodeCurrent(int rank, BbParaNode *node)
make subtree root node as current task for the specified rank
virtual BbParaNode * extractSelfSplitSubtreeRootNodes(int rank)
extract self-split subtree root node from the active solver with the specified rank
virtual void resetCountersInSolver(int rank, long long numOfNodesSolved, int numOfSelfSplitNodesLeft, BbParaNodePool *paraNodePool)
reset counters in the Solver specified by rank
bool collectingMode
indicate that this system is in collecting mode or not
virtual BbParaNode * getSelfSplitSubtreeRootNodes(int rank)
get self-split subtree root node from the active solver with the specified rank
virtual void enforcedSwitchOutCollectingMode(int rank)
enforced to switch out collecting mode of the Solver specified by rank if it is necessary
virtual void inactivateSolver(int rank, long long numOfNodesSolved, BbParaNodePool *paraNodePool)
inactivate the Solver specified by rank
unsigned long long nNodesInSolvers
number of nodes in all Solvers
bool beforeInitialCollect
before initial collecting mode
double mBgap
multiplier of the bgap value
std::map< int, BbParaSolverPoolElementPtr > inactiveSolvers
pointers to inactive Solvers
virtual int getNumOfNodesLeft(int rank)
get the number of nodes left by the Solver specified
virtual BbParaNode * solverDied(int rank)
kill the Solver specified by rank
SelectionHeap * selectionHeap
pointers to active Solvers in ascending or descending order
std::map< int, BbParaSolverPoolElementPtr > activeSolvers
pointers to active Solvers
std::multimap< double, BbParaSolverPoolElementPtr > candidatesOfCollectingModeSolvers
pointers to candidates of collecting mode Solvers
virtual void addNewSubtreeRootNode(int rank, BbParaNode *node)
add new subtree root node to the active solver with the specified rank
int nDualBoundGainTesting
the number of dual bound gain testing Solvers
virtual void removeSubtreeRootNode(int rank, BbParaNode *node)
remove subtree root node from the active solver with the specified rank
CollectingModeSolverHeap * collectingModeSolverHeap
pointers to collecting mode Solvers in ascending or descending order
std::size_t nCollectingModeSolvers
number of collecting mode Solvers
class CollectingModeSolverHeap
virtual void upHeap(std::size_t pos)=0
up heap
const std::string toString()
stringfy of this object for debugging
virtual ~CollectingModeSolverHeap()
destructor
CollectingModeSolverHeap(std::size_t size)
constructor
BbParaSolverPoolElementPtr remove()
remove top priority BbParaSolverPoolElementPtr from CollectingModeSolver Heap *‍/
virtual void deleteElement(BbParaSolverPoolElementPtr solver)=0
delete BbParaSolverPoolElementPtr from CollectingModeSolver Heap
std::size_t maxHeapSize
maximum size of this heap
virtual void updateDualBoundValue(BbParaSolverPoolElementPtr solver, double value)=0
update CollectingModeSolver heap by a new dual bound value of this Solver
std::size_t heapSize
current used heap size
ResultOfInsert insert(BbParaSolverPoolElementPtr solver)
insert BbParaSolverPoolElementPtr to CollectingModeSolver Heap
void resize(std::size_t size)
resize CollectingModeSolver Heap
std::size_t getHeapSize() const
get current used heap size
virtual void downHeap(std::size_t pos)=0
down heap
BbParaSolverPoolElementPtr * heap
heap : contents are BbParaSolverPoolElementPtr
BbParaSolverPoolElementPtr top() const
obtain top priority BbParaSolverPoolElementPtr
virtual void updateDualBoundValue(BbParaSolverPoolElementPtr solver, double value)
update CollectingModeSolver heap by a new dual bound value of this Solver
virtual void deleteElement(BbParaSolverPoolElementPtr solver)
delete BbParaSolverPoolElementPtr from CollectingModeSolver Heap
virtual void downHeap(std::size_t pos)
down heap
DescendingCollectingModeSolverHeap(std::size_t size)
constructor
virtual void upHeap(std::size_t pos)
up heap
virtual void updateDualBoundValue(BbParaSolverPoolElementPtr solver, double value)
update selection heap by a new dual bound value of this Solver
DescendingSelectionHeap(std::size_t size)
constructor
virtual void deleteElement(BbParaSolverPoolElementPtr solver)
delete BbParaSolverPoolElementPtr from Selection Heap
virtual void downHeap(std::size_t pos)
down heap
virtual void upHeap(std::size_t pos)
up heap
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)=0
send function for standard ParaData types
virtual double getElapsedTime()=0
getter of the deterministic time
bool getBoolParamValue(int param)
get bool parameter value
int getIntParamDefaultValue(int param)
get default value of int parameter
double getRealParamValue(int param)
get real parameter value
int getIntParamValue(int param)
get int parameter value
ParaParamSet * paraParams
runtime parameters for parallelization
int nSolvers
number of Solvers
ParaTimer * paraTimer
timer used
int winnerRank
winner rank of racing ramp-up, -1: not decided yet
ParaDeterministicTimer * paraDetTimer
deterministic timer used
int originRank
origin rank of Solvers managed by this Solver pool
ParaParamSet * paraParams
runtime parameters for parallelization
ParaComm * paraComm
communicator
std::size_t nSolvers
number of Solvers
ParaTimer * paraTimer
timer
virtual double getElapsedTime()=0
get elapsed time
class Selection Heap
virtual void upHeap(std::size_t pos)=0
up heap
const std::string toString()
stringfy of this object for debugging
BbParaSolverPoolElementPtr remove()
remove top priority BbParaSolverPoolElementPtr from Selection Heap
ResultOfInsert
results of insert
@ FAILED_BY_FULL
FAILED_BY_FULL.
virtual void deleteElement(BbParaSolverPoolElementPtr solver)=0
delete BbParaSolverPoolElementPtr from Selection Heap
std::size_t maxHeapSize
maximum size of this heap
virtual void updateDualBoundValue(BbParaSolverPoolElementPtr solver, double value)=0
update selection heap by a new dual bound value of this Solver
std::size_t heapSize
current used heap size
void resize(std::size_t size)
resize Selection Heap
ResultOfInsert insert(BbParaSolverPoolElementPtr solver)
insert BbParaSolverPoolElementPtr to Selection Heap
std::size_t getHeapSize() const
get current used heap size
virtual void downHeap(std::size_t pos)=0
down heap
BbParaSolverPoolElementPtr * heap
heap : contents are BbParaSolverPoolElementPtr
BbParaSolverPoolElementPtr top() const
obtain top priority BbParaSolverPoolElementPtr
virtual ~SelectionHeap()
destructor
static const int KeepRacingUntilToFindFirstSolution
static const int StopRacingTimeLimitMultiplier
static const int DualBoundGainTest
static const int LightWeightRootNodeProcess
static const int CollectingModeInterval
static const int TagLightWeightRootNodeProcess
Definition: bbParaTagDef.h:54
static const int SolverOrderInCollectingMode
static const int NMaxCanditatesForCollecting
static const int RacingRampUpTerminationCriteria
static const int StopRacingTimeLimit
@ Terminated
@ Active
@ TerminateRequested
@ Inactive
@ InterruptRequested
@ Racing
@ RacingEvaluation
static const int ParaINT
Definition: paraComm.h:66
static const int TagNoWaitModeSend
Definition: bbParaTagDef.h:60
static const int RatioToApplyLightWeightRootProcess
static const int ParaBYTE
Definition: paraComm.h:79
static const int ControlCollectingModeOnSolverSide
static const int Deterministic
Definition: paraParamSet.h:76
static const int TagNoTestDualBoundGain
Definition: bbParaTagDef.h:59
static const int StopRacingNumberOfNodesLeftMultiplier
static const int NChangeIntoCollectingMode
static const int TagOutCollectingMode
Definition: bbParaTagDef.h:52
static const int NEvaluationSolversToStopRacing
static const int TagInCollectingMode
Definition: bbParaTagDef.h:50
static const int StopRacingNumberOfNodesLeft
static const int CountingSolverRatioInRacing
static const int TagTestDualBoundGain
Definition: bbParaTagDef.h:58
static const int ParaDOUBLE
Definition: paraComm.h:76
static const int MultiplierForCollectingMode
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
Defines for UG Framework.
#define THROW_LOGICAL_ERROR1(msg1)
Definition: paraDef.h:52
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
#define THROW_LOGICAL_ERROR4(msg1, msg2, msg3, msg4)
Definition: paraDef.h:103
#define THROW_LOGICAL_ERROR3(msg1, msg2, msg3)
Definition: paraDef.h:86
#define SOLVER_POOL_INDEX(rank)