Scippy

UG

Ubiquity Generator framework

bbParaSolverPool.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and software framework */
4 /* UG --- Ubquity Generator Framework */
5 /* */
6 /* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7 /* Copyright (C) 2021 by Zuse Institute Berlin, */
8 /* licensed under LGPL version 3 or later. */
9 /* Commercial licenses are available through <licenses@zib.de> */
10 /* */
11 /* This code is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 /* */
24 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25 
26 /**@file paraSolverPool.h
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 #ifndef __BB_PARA_SOLVER_POOL_H__
38 #define __BB_PARA_SOLVER_POOL_H__
39 #include <cstdlib>
40 #include <map>
41 #include "ug/paraTask.h"
42 #include "ug/paraTimer.h"
45 #include "ug/paraSolverPool.h"
47 #include "bbParaNodePool.h"
48 
49 namespace UG
50 {
51 
54 
55 // enum SolverStatus {Inactive, Racing, RacingEvaluation, Active, Dead};
56 
57 // #define SOLVER_POOL_INDEX( rank ) ( rank - originRank )
58 
59 ///
60 /// class BbParaSolverPoolElement
61 /// (This class includes information about a Solver status)
62 ///
64 {
65 
66  int rank; ///< rank of the Solver
67  SolverStatus status; ///< status of the Solver
68  bool collectingMode; ///< indicate if current Solver is in collecting mode or not
69  bool candidateOfCollecting; ///< indicate that this Solver is a candidate of collecting mode Solver
70  bool generator; ///< this Solver can generate subproblems
71  bool collectingIsProhibited; ///< collecting is temporary prohibited
72  bool dualBoundGainTesting; ///< indicate that dual bound gain is testing or not
73  BbParaNode *currentNode; ///< solving node
74  BbParaNode *selfSplitNodes; ///< list of nodes generated by self-split ramp-up
75  BbParaSolverPoolElementPtr *selectionHeapElement; ///< pointer to selection heap element
76  BbParaSolverPoolElementPtr *collectingModeSolverHeapElement; ///< pointer to collecting mode heap element
77  ///------------------------------------------------------------------
78  /// the following values are used to make decision for load balancing
79  ///------------------------------------------------------------------
80  long long numOfNodesSolved; ///< number of nodes solved.
81  ///< -1 is the special value which means never updated in racing
82  int numOfDiffNodesSolved; ///< number of nodes solved difference between current number and
83  ///< that in the previous notification time
84  int numOfNodesLeft; ///< number of nodes left
85  int numOfDiffNodesLeft; ///< number of nodes left difference between current number
86  ///< and that in the previous notification time
87  double bestDualBoundValue; ///< best dual bound value of the Solver
88  ParaSolverTerminationState *termState; ///< Solver termination statistics: for checkpoint
89 
90 public :
91 
92  ///
93  /// constructor
94  ///
96  int inRank
97  )
98  : rank(inRank),
99  status(Inactive),
100  collectingMode(false),
101  candidateOfCollecting(false),
102  generator(true),
103  collectingIsProhibited(false),
104  dualBoundGainTesting(false),
105  currentNode(0),
106  selfSplitNodes(0),
107  selectionHeapElement(0),
108  collectingModeSolverHeapElement(0),
109  numOfNodesSolved(0),
110  numOfDiffNodesSolved(0),
111  numOfNodesLeft(0),
112  numOfDiffNodesLeft(0),
113  bestDualBoundValue(0.0),
114  // racingRampUpParamSet(0),
115  termState(0)
116  {
117  }
118 
119  ///
120  /// destractor
121  ///
123  )
124  {
125  if( currentNode ) delete currentNode;
126  if( selfSplitNodes )
127  {
128  while( selfSplitNodes )
129  {
130  BbParaNode *temp = selfSplitNodes;
131  selfSplitNodes = selfSplitNodes->next;
132  delete temp;
133  }
134  }
135  if( termState ) delete termState;
136  }
137 
138  ///
139  /// get rank of the Solver
140  /// @return rank of Solver
141  ///
142  int getRank(
143  )
144  {
145  return rank;
146  }
147 
148  ///
149  /// get current solving BbParaNode
150  /// @return pointer to BbParaNode object
151  ///
153  )
154  {
155  return currentNode;
156  }
157 
158  ///
159  /// get a list of nodes which are generated by self-split ramp-up
160  /// @return pointer to BbParaNode object
161  ///
163  )
164  {
165  return selfSplitNodes;
166  }
167 
168  ///
169  /// extract a list of nodes which are generated by self-split ramp-up
170  /// @return pointer to BbParaNode object
171  ///
173  )
174  {
175  BbParaNode *nodes = selfSplitNodes;
176  selfSplitNodes = 0;
177  return nodes;
178  }
179 
180  /*
181  ///
182  /// remove bounded BbParaNodes by given incumbnet value
183  /// @return the number of bounded BbParaNodes
184  ///
185  int removeBoundedNodes(
186  double incumbentValue ///< incumbent value
187  )
188  {
189  int n;
190  BbParaNode *preNode = selfSplitNodes;
191  BbParaNode *node = selfSplitNodes;
192  while( node )
193  {
194  if( node->getDualBoundValue() > incumbentValue )
195  {
196  if( preNode == selfSplitNodes ) // head
197  {
198  selfSplitNodes = node->next;
199  preNode = selfSplitNodes;
200  delete node;
201  node = selfSplitNodes;
202  }
203  else
204  {
205  preNode->next = node->next;
206  delete node;
207  node = preNode->next;
208  }
209  n++;
210  }
211  }
212  return n;
213  }
214  */
215 
216  ///
217  /// add subtree root node
218  ///
220  BbParaNode *inNode ///< BbParaNode to be added
221  )
222  {
223  assert( !inNode->isRootTask() );
224  if( selfSplitNodes )
225  {
226  /// add the end, since it would be most like to be solved in this order
227  BbParaNode *node = selfSplitNodes;
228  while( node->next )
229  {
230  node = node->next;
231  }
232  node->next = inNode;
233  }
234  else
235  {
236  selfSplitNodes = inNode;
237  }
238  }
239 
240  ///
241  /// make subtree root node current
242  /// @return if the node is removed or not (The last node is not removed)
243  ///
245  BbParaNode *inNode ///< BbParaNode to become current
246  )
247  {
248  if( selfSplitNodes )
249  {
250  // assert( currentNode->next ); // can be next = 0
251  if( selfSplitNodes->isSameNodeIdAs( *inNode ) )
252  {
253  currentNode = selfSplitNodes;
254  selfSplitNodes = selfSplitNodes->next;
255  currentNode->next = 0;
256  }
257  else
258  {
259  if( selfSplitNodes->next )
260  {
261  BbParaNode *prev = selfSplitNodes;
262  BbParaNode *node = selfSplitNodes->next;
263  while( node && ! node->isSameNodeIdAs( *inNode ) )
264  {
265  prev = node;
266  node = node->next;
267  }
268  assert( node );
269  prev->next = node->next;
270  currentNode = node;
271  currentNode->next = 0;
272  }
273  else
274  {
275  THROW_LOGICAL_ERROR1("Should not be called. If whole subtrees are removed, TagComleation should be sent and should be inactivated.");
276  }
277  }
278  }
279  else
280  {
281  THROW_LOGICAL_ERROR1("Tried to make invalid BbParaNode to become current");
282  }
283  }
284 
285  ///
286  /// remove subtree root node in self-split nodes list
287  ///
289  BbParaNode *inNode ///< BbParaNode to be removed
290  )
291  {
292  assert( selfSplitNodes );
293 
294  if( selfSplitNodes->isSameNodeIdAs( *inNode ) )
295  {
296  BbParaNode *node = selfSplitNodes;
297  selfSplitNodes = selfSplitNodes->next;
298  delete node;
299  return;
300  }
301  else
302  {
303  if( selfSplitNodes->next )
304  {
305  BbParaNode *prev = selfSplitNodes;
306  BbParaNode *node = selfSplitNodes->next;
307  while( node && ! node->isSameNodeIdAs( *inNode ) )
308  {
309  prev = node;
310  node = node->next;
311  }
312  assert( node );
313  prev->next = node->next;
314  delete node;
315  return;
316  }
317  else
318  {
319  THROW_LOGICAL_ERROR1("Should not be called. If whole subtrees are removed, TagComleation should be sent and should be inactivated.");
320  }
321  }
322  }
323 
324  ///
325  /// extract subtree root node
326  ///
328  BbParaNode *inNode ///< BbParaNode to be removed
329  )
330  {
331  if( selfSplitNodes )
332  {
333  // assert( currentNode->next ); // can be next = 0
334  if( selfSplitNodes->isSameNodeIdAs( *inNode ) )
335  {
336  BbParaNode *node = selfSplitNodes;
337  selfSplitNodes = selfSplitNodes->next;
338  node->next = 0;
339  return node;
340  }
341  else
342  {
343  if( selfSplitNodes->next )
344  {
345  BbParaNode *prev = selfSplitNodes;
346  BbParaNode *node = selfSplitNodes->next;
347  while( node && ! node->isSameNodeIdAs( *inNode ) )
348  {
349  prev = node;
350  node = node->next;
351  }
352  assert( node );
353  prev->next = node->next;
354  node->next = 0;
355  return node;
356  }
357  else
358  {
359  THROW_LOGICAL_ERROR1("Should not be called. If whole subtrees are removed, TagComleation should be sent and should be inactivated.");
360  }
361  }
362  }
363  else
364  {
365  THROW_LOGICAL_ERROR1("Tried to remove invalid BbParaNode as a subtree root node");
366  }
367  }
368 
369  ///
370  /// extract current solving BbParaNode
371  /// @return pointer to BbParaNode object
372  ///
374  )
375  {
376  assert( !currentNode->next );
377  BbParaNode *node = currentNode;
378  currentNode = 0;
379  return node;
380  }
381 
382  ///
383  /// delete current solving BbParaNode
384  ///
386  )
387  {
388  assert( !currentNode->next );
389  delete currentNode;
390  currentNode = 0;
391  }
392 
393 
394  ///
395  /// extract current solving BbParaNode
396  /// @return pointer to BbParaNode object
397  ///
398 // BbParaNode *extractCurrentNodeGeneratedBySelfSplit(
399 // )
400 // {
401 // // assert( currentNode->next ); /// can be next == 0
402 // BbParaNode *node = currentNode;
403 // currentNode = 0;
404 // return node;
405 // }
406 
407  ///
408  /// get selection heap element
409  /// @return pointer to BbParaSolverPoolElementPtr
410  ///
411  BbParaSolverPoolElementPtr *getSelectionHeapElement(
412  )
413  {
414  return selectionHeapElement;
415  }
416 
417  ///
418  /// set selection heap element
419  ///
421  BbParaSolverPoolElementPtr *inSelectionHeapElement ///< selection heap element
422  )
423  {
424  selectionHeapElement = inSelectionHeapElement;
425  }
426 
427  ///
428  /// get collecting mode Solver heap element
429  /// @return pointer to BbParaSolverPoolElementPtr
430  ///
431  BbParaSolverPoolElementPtr *getCollectingModeSolverHeapElement(
432  )
433  {
435  }
436 
437  ///
438  /// set collecting mode Solver heap element
439  ///
441  BbParaSolverPoolElementPtr *inCollectingModeSolverHeapElement ///< collecting mode Solver heap element
442  )
443  {
444  collectingModeSolverHeapElement = inCollectingModeSolverHeapElement;
445  }
446 
447  ///
448  /// get number of nodes solved
449  /// @return number of nodes solved
450  ///
452  )
453  {
454  return numOfNodesSolved;
455  }
456 
457  ///
458  /// get number of nodes left
459  /// @return number of nodes left
460  ///
462  )
463  {
464  return numOfNodesLeft;
465  }
466 
467  ///
468  /// set number of nodes solved
469  ///
471  long long inNumOfNodesSolved ///< number of nodes solved
472  )
473  {
474  numOfNodesSolved = inNumOfNodesSolved;
475  }
476 
477  ///
478  /// get number of nodes left difference between current number and that in the previous notification time
479  /// @return number of nodes left difference between current number and that in the previous notification time
480  ///
482  )
483  {
484  return numOfDiffNodesSolved;
485  }
486 
487  ///
488  /// set number of nodes left difference between current number and that in the previous notification time
489  ///
491  int inNumOfDiff ///< number of nodes left difference between current number
492  ///< and that in the previous notification time
493  )
494  {
495  numOfDiffNodesSolved = inNumOfDiff;
496  }
497 
498  ///
499  /// set number of nodes left
500  ///
502  int inNumOfNodesLeft ///< number of nodes left
503  )
504  {
505  numOfNodesLeft = inNumOfNodesLeft;
506  }
507 
508  ///
509  /// set dual bound value on paraNode
510  ///
512  double dualBoundValue ///< dual bound value
513  )
514  {
515  dynamic_cast<BbParaNode *>(currentNode)->setDualBoundValue(dualBoundValue);
516  }
517 
518  ///
519  /// get number of nodes left difference between current number and that in the previous notification time
520  /// @return number of nodes left difference between current number and that in the previous notification time
521  ///
523  )
524  {
525  return numOfDiffNodesLeft;
526  }
527 
528  ///
529  /// set number of nodes left difference between current number and that in the previous notification time
530  ///
532  int inNumOfDiff ///< set number of nodes left difference between current number
533  ///< and that in the previous notification time
534  )
535  {
536  numOfDiffNodesLeft = inNumOfDiff;
537  }
538 
539  ///
540  /// get best dual bound value
541  /// @return best dual bound value
542  ///
544  )
545  {
546  return bestDualBoundValue;
547  }
548 
549  ///
550  /// set best dual bound value
551  ///
553  double inBestDualBoundValue ///< best dual bound value
554  )
555  {
556  bestDualBoundValue = inBestDualBoundValue;
557  }
558 
559  ///
560  /// activate this Solver
561  ///
562  void activate(
563  BbParaNode *inNode ///< pointer to BbParaNode object to activate Solver
564  )
565  {
566  status = Active;
567  currentNode = inNode;
568  if( currentNode )
569  bestDualBoundValue = inNode->getDualBoundValue();
570  else
571  bestDualBoundValue = -DBL_MAX;
572  numOfNodesSolved = 0;
573  numOfNodesLeft = 1; // at least 1 node should be left
574  }
575 
576  ///
577  /// activate this Solver as a racing Solver
578  ///
580  )
581  {
582  status = Racing;
583  currentNode = 0;
584  numOfNodesSolved = -1;
585  bestDualBoundValue = -DBL_MAX;
586  numOfNodesLeft = 1; // at least 1 node should be left
587  }
588 
589  ///
590  /// inactivate this Solver
591  ///
593  )
594  {
595  status = Inactive;
596  if( currentNode )
597  {
598  delete currentNode;
599  currentNode = 0;
600  }
601  collectingMode = false;
602  candidateOfCollecting = false;
603  collectingIsProhibited = false;
604  dualBoundGainTesting = false;
605  /** do not touch "generator" **/
606  numOfNodesSolved = 0;
607  numOfNodesLeft = 0;
608  numOfDiffNodesLeft = 0;
609  bestDualBoundValue = 0.0;
610  }
611 
612  ///
613  /// kill this Solver
614  /// @return pointer to BbParaNode object assigned to this Solver
615  ///
617  )
618  {
619  status = Dead;
620  collectingMode = false;
621  candidateOfCollecting = false;
622  collectingIsProhibited = false;
623  dualBoundGainTesting = false;
624  numOfNodesSolved = 0;
625  numOfNodesLeft = 0;
626  numOfDiffNodesLeft = 0;
627  bestDualBoundValue = 0.0;
628  BbParaNode* node = currentNode;
629  currentNode = 0;
630  return node;
631  }
632 
633  ///
634  /// get Solver status
635  /// @return Solver status
636  ///
638  )
639  {
640  return status;
641  }
642 
643  ///
644  /// set TerminateRequseted on Solver status
645  ///
647  )
648  {
649  // assert( status == Inactive );
650  status = InterruptRequested;
651  }
652 
653  ///
654  /// set TerminateRequseted on Solver status
655  ///
657  )
658  {
659  // assert( status == Inactive );
660  status = TerminateRequested;
661  }
662 
663  ///
664  /// set Terminated on Solver status
665  ///
667  )
668  {
669  assert( status == TerminateRequested || status == InterruptRequested || status == Inactive );
670  status = Terminated;
671  }
672 
673  ///
674  /// check if this Solver is active or not
675  /// @return true if this Solver is active, false otherwise
676  ///
677  bool isActive(
678  )
679  {
680  return ( status == Active );
681  }
682 
683  ///
684  /// check if this Solver is out of collecting mode or not
685  /// @return true if this Solver is out of collecting mode, false otherwise
686  ///
688  )
689  {
690  return (!collectingMode);
691  }
692 
693  ///
694  /// check if this Solver is in collecting mode or not
695  /// @return true if this Solver is in collecting mode, false otherwise
696  ///
698  )
699  {
700  return collectingMode;
701  }
702 
703  ///
704  /// set collecting mode
705  ///
707  bool b ///< true or false to be set on collecting mode
708  )
709  {
710  collectingMode = b;
711  }
712 
713  ///
714  /// check if this Solver is candidate of collecting mode Solver
715  /// @return true if this Solver is candidate, false otherwise
716  ///
718  )
719  {
720  return candidateOfCollecting;
721  }
722 
723  ///
724  /// set candidate of collecting mode Solver
725  ///
727  bool b ///< true or false to be set on candidate flag
728  )
729  {
730  candidateOfCollecting = b;
731  }
732 
733  ///
734  /// set termination state
735  ///
737  ParaSolverTerminationState *inTermState ///< termination state to be set
738  )
739  {
740  if( termState ) delete termState;
741  termState = inTermState;
742  }
743 
744  ///
745  /// get termination state
746  /// @return pointer to ParaSolverTerminationState object
747  ///
749  )
750  {
751  return termState;
752  }
753 
754  ///
755  /// switch into evaluation stage
756  ///
758  )
759  {
760  assert( status == Racing );
761  status = RacingEvaluation;
762  }
763 
764  ///
765  /// switch out of evaluation stage
766  ///
768  )
769  {
770  assert( status == RacingEvaluation );
771  status = Racing;
772  }
773 
774  ///
775  /// check if this Solver is in racing stage
776  /// @return true if this Solver is in racing stage, false otherwise
777  ///
779  )
780  {
781  return ( status == Racing );
782  }
783 
784  ///
785  /// check if this Solver is in evaluation stage
786  /// @return true if this Solver is in evaluation stage, false otherwise
787  ///
789  )
790  {
791  return ( status == RacingEvaluation );
792  }
793 
794  ///
795  /// make this Solver No generator
796  ///
798  )
799  {
800  generator = false;
801  }
802 
803  ///
804  /// check if this Solver is generator or not */
805  /// @return true if this Solver is generator, false otherwise
806  ///
808  )
809  {
810  return generator;
811  }
812 
813  ///
814  /// prohibits to be in collecting mode
815  ///
817  )
818  {
819  collectingIsProhibited = true;
820  }
821 
822  ///
823  /// allows to be in collecting mode
824  ///
826  )
827  {
828  collectingIsProhibited = false;
829  }
830 
831  ///
832  /// check if this Solver cannot be allowed in collecting mode
833  /// @return true if this Solver cannot be allowed in collecting mode, false otherwise
834  ///
836  )
837  {
838  return collectingIsProhibited;
839  }
840 
841  ///
842  /// check if dual bound gain is testing in this Solver or not
843  /// @return true if dual bound gain is testing, false otherwise
844  ///
846  )
847  {
848  return dualBoundGainTesting;
849  }
850 
851  ///
852  /// set dual bound gain is testing value
853  ///
855  bool value ///< dual bound gain
856  )
857  {
858  dualBoundGainTesting = value;
859  }
860 
861 };
862 
863 ///
864 /// class Selection Heap
865 ///
867 {
868 
869 public:
870 
871  ///
872  /// results of insert
873  ///
875  {
876  SUCCEEDED, ///< SUCCEEDED
877  FAILED_BY_FULL ///< FAILED_BY_FULL
878  };
879 
880  ///
881  /// constructor
882  ///
884  std::size_t size ///< heap size
885  );
886 
887  ///
888  /// destructor
889  ///
890  virtual ~SelectionHeap(
891  );
892 
893  ///
894  /// insert BbParaSolverPoolElementPtr to Selection Heap
895  /// @return succeeded or fail because of full
896  ///
897  ResultOfInsert insert(
898  BbParaSolverPoolElementPtr solver ///< Solver pool element to be inserted
899  );
900 
901  ///
902  /// obtain top priority BbParaSolverPoolElementPtr
903  /// @return top priority BbParaSolverPoolElementPtr
904  ///
905  BbParaSolverPoolElementPtr top(
906  ) const
907  {
908  return heap[1];
909  }
910 
911  ///
912  /// obtain i-th in heap BbParaSolverPoolElementPtr
913  /// @return ith in heap BbParaSolverPoolElementPtr
914  ///
915  BbParaSolverPoolElementPtr get(
916  int i
917  ) const
918  {
919  return heap[i];
920  }
921 
922  ///
923  /// remove top priority BbParaSolverPoolElementPtr from Selection Heap
924  /// @return removed top priority BbParaSolverPoolElementPtr
925  ///
926  BbParaSolverPoolElementPtr remove(
927  );
928 
929  ///
930  /// resize Selection Heap
931  ///
932  void resize(
933  std::size_t size ///< new size
934  );
935 
936  ///
937  /// get current used heap size
938  /// @return used heap size
939  ///
940  inline std::size_t getHeapSize(
941  ) const
942  {
943  return heapSize;
944  }
945 
946  ///
947  /// get max heap size
948  /// @return max heap size
949  ///
950  inline std::size_t getMaxHeapSize(
951  ) const
952  {
953  return maxHeapSize;
954  }
955 
956  ///
957  /// update selection heap by a new dual bound value of this Solver
958  ///
959  virtual void updateDualBoundValue(
960  BbParaSolverPoolElementPtr solver, ///< Solver pool element to be updated
961  double value ///< dual bound value
962  ) = 0;
963 
964  ///
965  /// delete BbParaSolverPoolElementPtr from Selection Heap
966  ///
967  virtual void deleteElement(
968  BbParaSolverPoolElementPtr solver ///< Solver pool element to be deleted
969  ) = 0;
970 
971  ///
972  /// up heap
973  ///
974  virtual void upHeap(
975  std::size_t pos ///< start position to up heap
976  ) = 0;
977 
978  ///
979  /// down heap
980  ///
981  virtual void downHeap(
982  std::size_t pos ///< start position to down heap
983  ) = 0;
984 
985  //------------
986  // for debug
987  //------------
988  ///
989  /// stringfy of this object for debugging
990  /// @return string to show inside of this object
991  ///
992  const std::string toString(
993  );
994 
995 protected:
996 
997  std::size_t maxHeapSize; ///< maximum size of this heap
998  std::size_t heapSize; ///< current used heap size
999  // long long currentSequenceNumber; ///< current sequence number
1000  BbParaSolverPoolElementPtr *heap; ///< heap : contents are BbParaSolverPoolElementPtr
1001 
1002 };
1003 
1004 ///
1005 /// class DescendingSelectionHeap
1006 ///
1008 
1009 public:
1010 
1011  ///
1012  /// constructor
1013  ///
1015  std::size_t size ///< heap size
1016  );
1017 
1018  ///
1019  /// destructor
1020  ///
1022  )
1023  {
1024  }
1025 
1026  ///
1027  /// update selection heap by a new dual bound value of this Solver
1028  ///
1029  virtual void updateDualBoundValue(
1030  BbParaSolverPoolElementPtr solver, ///< Solver pool element to be updated
1031  double value ///< dual bound value
1032  );
1033 
1034  ///
1035  /// delete BbParaSolverPoolElementPtr from Selection Heap
1036  ///
1037  virtual void deleteElement(
1038  BbParaSolverPoolElementPtr solver ///< Solver pool element to be deleted
1039  );
1040 
1041  ///
1042  /// up heap
1043  ///
1044  virtual void upHeap(
1045  std::size_t pos ///< start position to up heap
1046  );
1047  ///
1048  /// down heap
1049  ///
1050  virtual void downHeap(
1051  std::size_t pos ///< start position to down heap
1052  );
1053 
1054 };
1055 
1056 ///
1057 /// class AscendingSelectionHeap
1058 ///
1060 public:
1061 
1062  ///
1063  /// constructor
1064  ///
1066  std::size_t size ///< heap size
1067  );
1068 
1069  ///
1070  /// destructor
1071  ///
1073  )
1074  {
1075  }
1076 
1077  ///
1078  /// update selection heap by a new dual bound value of this Solver
1079  ///
1080  virtual void updateDualBoundValue(
1081  BbParaSolverPoolElementPtr solver, ///< Solver pool element to be updated
1082  double value ///< dual bound value
1083  );
1084 
1085  ///
1086  /// delete BbParaSolverPoolElementPtr from Selection Heap
1087  ///
1088  virtual void deleteElement(
1089  BbParaSolverPoolElementPtr solver ///< Solver pool element to be deleted
1090  );
1091 
1092  ///
1093  /// up heap
1094  ///
1095  virtual void upHeap(
1096  std::size_t pos ///< start position to up heap
1097  );
1098  ///
1099  /// down heap
1100  ///
1101  virtual void downHeap(
1102  std::size_t pos ///< start position to down heap
1103  );
1104 
1105 };
1106 
1107 ///
1108 /// class CollectingModeSolverHeap
1109 ///
1111 {
1112 
1113 public:
1114 
1115  ///
1116  /// results of insert
1117  ///
1119  {
1120  SUCCEEDED, ///< SUCCEEDED
1121  FAILED_BY_FULL ///< FAILED_BY_FULL
1122  };
1123 
1124  ///
1125  /// constructor
1126  ///
1128  std::size_t size ///< heap size
1129  );
1130 
1131  ///
1132  /// destructor
1133  ///
1134  virtual ~CollectingModeSolverHeap(
1135  );
1136 
1137  ///
1138  /// insert BbParaSolverPoolElementPtr to CollectingModeSolver Heap
1139  /// @return succeeded or fail because of full
1140  ///
1141  ResultOfInsert insert(
1142  BbParaSolverPoolElementPtr solver ///< Solver pool element to be inserted
1143  );
1144 
1145 
1146 
1147  ///
1148  /// obtain top priority BbParaSolverPoolElementPtr
1149  /// @return top priority BbParaSolverPoolElementPtr
1150  ///
1151  BbParaSolverPoolElementPtr top(
1152  ) const
1153  {
1154  return heap[1];
1155  }
1156 
1157  ///
1158  /// remove top priority BbParaSolverPoolElementPtr from CollectingModeSolver Heap */
1159  /// @return top priority BbParaSolverPoolElementPtr
1160  ///
1161  BbParaSolverPoolElementPtr remove(
1162  );
1163 
1164  ///
1165  /// resize CollectingModeSolver Heap
1166  ///
1167  void resize(
1168  std::size_t size ///< new size
1169  );
1170 
1171  ///
1172  /// get current used heap size
1173  /// @return used heap size
1174  ///
1175  inline std::size_t getHeapSize(
1176  ) const
1177  {
1178  return heapSize;
1179  }
1180 
1181  ///
1182  /// get max heap size
1183  /// @return max heap size
1184  ///
1185  inline std::size_t getMaxHeapSize(
1186  ) const
1187  {
1188  return maxHeapSize;
1189  }
1190 
1191  ///
1192  /// update CollectingModeSolver heap by a new dual bound value of this Solver
1193  ///
1194  virtual void updateDualBoundValue(
1195  BbParaSolverPoolElementPtr solver, ///< Solver pool element to be updated
1196  double value ///< dual bound value
1197  ) = 0;
1198 
1199  ///
1200  /// delete BbParaSolverPoolElementPtr from CollectingModeSolver Heap
1201  ///
1202  virtual void deleteElement(
1203  BbParaSolverPoolElementPtr solver ///< Solver pool element to be deleted
1204  ) = 0;
1205 
1206  ///
1207  /// up heap
1208  ///
1209  virtual void upHeap(
1210  std::size_t pos ///< start position to up heap
1211  ) = 0;
1212 
1213  ///
1214  /// down heap
1215  ///
1216  virtual void downHeap(
1217  std::size_t pos ///< start position to down heap
1218  ) = 0;
1219 
1220  //------------
1221  // for debug
1222  //------------
1223  ///
1224  /// stringfy of this object for debugging
1225  /// @return string to show inside of this object
1226  ///
1227  const std::string toString();
1228 
1229 protected:
1230 
1231  std::size_t maxHeapSize; ///< maximum size of this heap
1232  std::size_t heapSize; ///< current used heap size
1233  // long long currentSequenceNumber; ///< current sequence number
1234  BbParaSolverPoolElementPtr *heap; ///< heap : contents are BbParaSolverPoolElementPtr
1235 
1236 };
1237 
1238 ///
1239 /// class DescendingCollectingModeSolverHeap
1240 ///
1242 
1243 public:
1244 
1245  ///
1246  /// constructor
1247  ///
1249  std::size_t size ///< heap size
1250  );
1251 
1252  ///
1253  /// destructor
1254  ///
1256  )
1257  {
1258  }
1259 
1260  ///
1261  /// update CollectingModeSolver heap by a new dual bound value of this Solver
1262  ///
1263  virtual void updateDualBoundValue(
1264  BbParaSolverPoolElementPtr solver, ///< Solver pool element to be updated
1265  double value ///< dual bound value
1266  );
1267 
1268  ///
1269  /// delete BbParaSolverPoolElementPtr from CollectingModeSolver Heap
1270  ///
1271  virtual void deleteElement(
1272  BbParaSolverPoolElementPtr solver ///< Solver pool element to be deleted
1273  );
1274 
1275  ///
1276  /// up heap
1277  ///
1278  virtual void upHeap(
1279  std::size_t pos ///< start position to up heap
1280  );
1281 
1282  ///
1283  /// down heap
1284  ///
1285  virtual void downHeap(
1286  std::size_t pos ///< start position to down heap
1287  );
1288 
1289 };
1290 
1292 
1293 public:
1294 
1295  ///
1296  /// constructor
1297  ///
1299  std::size_t size ///< heap size
1300  );
1301 
1302  ///
1303  /// destructor
1304  ///
1306  )
1307  {
1308  }
1309 
1310  ///
1311  /// update CollectingModeSolver heap by a new dual bound value of this Solver
1312  ///
1313  virtual void updateDualBoundValue(
1314  BbParaSolverPoolElementPtr solver, ///< Solver pool element to be updated
1315  double value ///< dual bound value
1316  );
1317 
1318  ///
1319  /// delete BbParaSolverPoolElementPtr from CollectingModeSolver Heap
1320  ///
1321  virtual void deleteElement(
1322  BbParaSolverPoolElementPtr solver ///< Solver pool element to be deleted
1323  );
1324 
1325  ///
1326  /// up heap
1327  ///
1328  virtual void upHeap(
1329  std::size_t pos ///< start position to up heap
1330  );
1331 
1332  ///
1333  /// down heap
1334  ///
1335  virtual void downHeap(
1336  std::size_t pos ///< start position to down heap
1337  );
1338 
1339 };
1340 
1342 
1343 ///
1344 /// class BbParaSolverPool
1345 /// (Solver Pool base class)
1346 ///
1348 {
1349 
1350 protected:
1351 
1352  bool active; ///< indicate if this pool is active or not
1353  double bgap; ///< threshold value of gap
1354  double mp; ///< multiplier of the threshold value p
1355  double mBgap; ///< multiplier of the bgap value
1356  double absoluteGap; ///< allowable absolute dual bound gap to the best Solver
1357  std::size_t nGenerator; ///< number of generators
1358  std::size_t nCollectingModeSolvers; ///< number of collecting mode Solvers
1359  std::size_t nMaxCollectingModeSolvers; ///< maximum number of Solvers that can be in collecting mode
1360  std::size_t nLimitCollectingModeSolvers; ///< limit number of Solvers that can be in collecting mode
1361  unsigned long long nNodesSolvedInSolvers; ///< number of nodes solved in current running Solvers
1362  unsigned long long nTotalNodesSolved; ///< number of nodes solved : updated at termination of subtree computation
1363  unsigned long long nNodesInSolvers; ///< number of nodes in all Solvers
1364  bool collectingMode; ///< indicate that this system is in collecting mode or not
1365  bool breakingFirstSubtree; ///< breaking the first subtree
1366  bool beforeInitialCollect; ///< before initial collecting mode
1367  bool beforeFinishingFirstCollect; ///< before finishing first collecting mode
1368  std::map< int, BbParaSolverPoolElementPtr > inactiveSolvers; ///< pointers to inactive Solvers
1369  std::map< int, BbParaSolverPoolElementPtr > activeSolvers; ///< pointers to active Solvers
1370  std::map< int, BbParaSolverPoolElementPtr > deadSolvers; ///< pointers to dead Solvers
1371  std::multimap< double, BbParaSolverPoolElementPtr > candidatesOfCollectingModeSolvers;
1372  ///< pointers to candidates of collecting mode Solvers
1373  BbParaSolverPoolElementPtr *pool; ///< Solver pool indexed by Solver's rank
1374  SelectionHeap *selectionHeap; ///< pointers to active Solvers in ascending or descending order
1375  CollectingModeSolverHeap *collectingModeSolverHeap; ///< pointers to collecting mode Solvers in ascending or descending order
1376  double switchOutTime; ///< switch out time
1377  int mCollectingNodes; ///< multiplier for the number of collecting BbParaNodes
1378  int mMaxCollectingNodes; ///< maximum multiplier for the number of collecting BbParaNodes
1379  int nDualBoundGainTesting; ///< the number of dual bound gain testing Solvers
1380 
1381  ///
1382  /// switch a Solver to be in collecting mode
1383  ///
1384  virtual void switchInCollectingToSolver(
1385  int rank, ///< Solver rank to be in collecting mode
1386  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool object
1387  );
1388 
1389 public:
1390 
1391  ///
1392  /// constructor
1393  ///
1395  double inMp, ///< multiplier of the threshold value p
1396  double inBgap, ///< threshold value of gap
1397  double inMBgap, ///< multiplier of the bgap value
1398  int inOriginRank, ///< origin rank of Solvers managed by this Solver pool
1399  ParaComm *inParaComm, ///< communicator used
1400  ParaParamSet *inParaParams, ///< paraParamSet used
1401  ParaTimer *inParaTimer ///< timer used
1402  )
1403  : ParaSolverPool(inOriginRank, inParaComm, inParaParams, inParaTimer),
1404  active(false),
1405  bgap(inBgap),
1406  mp(inMp),
1407  mBgap(inMBgap),
1408  nCollectingModeSolvers(0),
1409  nNodesSolvedInSolvers(0),
1410  nTotalNodesSolved(0),
1411  nNodesInSolvers(0), // rampUpPhase(false),
1412  collectingMode(false),
1413  breakingFirstSubtree(false),
1414  beforeInitialCollect(true),
1415  beforeFinishingFirstCollect(true),
1416  selectionHeap(0),
1417  collectingModeSolverHeap(0),
1418  switchOutTime(-1.0),
1419  mCollectingNodes(1),
1420  mMaxCollectingNodes(1),
1421  nDualBoundGainTesting(0)
1422  {
1423  nSolvers = paraComm->getSize() - inOriginRank;
1424  nGenerator = nSolvers;
1425 
1426  pool = new BbParaSolverPoolElementPtr[nSolvers];
1427  for( unsigned int i = 0; i < nSolvers; i++ )
1428  {
1429  pool[i] = new BbParaSolverPoolElement(originRank+i);
1430  if( i >= nGenerator ) pool[i]->setNoGenerator();
1431  inactiveSolvers.insert(std::make_pair((originRank+i),pool[i]));
1432  }
1433  if( paraParams->getIntParamValue(MaxNumberOfCollectingModeSolvers) > 0 )
1434  {
1435  nMaxCollectingModeSolvers = std::min(
1436  (std::size_t)paraParams->getIntParamValue(MaxNumberOfCollectingModeSolvers), nSolvers );
1437  }
1438  else if (paraParams->getIntParamValue(MaxNumberOfCollectingModeSolvers) == 0 )
1439  {
1440  nMaxCollectingModeSolvers = std::max(nSolvers / 2, (std::size_t)1); // at least one Solver has to be in collecting mode
1441  }
1442  else
1443  {
1444  nMaxCollectingModeSolvers = nSolvers;
1445  }
1446  nLimitCollectingModeSolvers = paraParams->getIntParamValue(MinNumberOfCollectingModeSolvers);
1447  absoluteGap = paraParams->getRealParamValue(ABgapForSwitchingToBestSolver);
1448  if( paraParams->getBoolParamValue(BreakFirstSubtree) )
1449  {
1450  breakingFirstSubtree = true;
1451  }
1452  }
1453 
1454  ///
1455  /// constructor
1456  ///
1458  double inMp, ///< multiplier of the threshold value p
1459  double inBgap, ///< threshold value of gap
1460  double inMBgap, ///< multiplier of the bgap value
1461  int inNSolvers, ///< number of solvers
1462  int inOriginRank, ///< origin rank of Solvers managed by this Solver pool
1463  ParaComm *inParaComm, ///< communicator used
1464  ParaParamSet *inParaParams, ///< paraParamSet used
1465  ParaTimer *inParaTimer ///< timer used
1466  )
1467  : ParaSolverPool(inOriginRank, inParaComm, inParaParams, inParaTimer),
1468  active(false),
1469  bgap(inBgap),
1470  mp(inMp),
1471  mBgap(inMBgap),
1472  nCollectingModeSolvers(0),
1473  nNodesSolvedInSolvers(0),
1474  nTotalNodesSolved(0),
1475  nNodesInSolvers(0), // rampUpPhase(false),
1476  collectingMode(false),
1477  breakingFirstSubtree(false),
1478  beforeInitialCollect(true),
1479  beforeFinishingFirstCollect(true),
1480  selectionHeap(0),
1481  collectingModeSolverHeap(0),
1482  switchOutTime(-1.0),
1483  mCollectingNodes(1),
1484  mMaxCollectingNodes(1),
1485  nDualBoundGainTesting(0)
1486  {
1487  nSolvers = inNSolvers;
1488  nGenerator = nSolvers;
1489 
1490  pool = new BbParaSolverPoolElementPtr[nSolvers];
1491  for( unsigned int i = 0; i < nSolvers; i++ )
1492  {
1493  pool[i] = new BbParaSolverPoolElement(originRank+i);
1494  if( i >= nGenerator ) pool[i]->setNoGenerator();
1495  inactiveSolvers.insert(std::make_pair((originRank+i),pool[i]));
1496  }
1497  if( paraParams->getIntParamValue(MaxNumberOfCollectingModeSolvers) > 0 )
1498  {
1499  nMaxCollectingModeSolvers = std::min(
1500  (std::size_t)paraParams->getIntParamValue(MaxNumberOfCollectingModeSolvers), nSolvers );
1501  }
1502  else if (paraParams->getIntParamValue(MaxNumberOfCollectingModeSolvers) == 0 )
1503  {
1504  nMaxCollectingModeSolvers = std::max(nSolvers / 2, (std::size_t)1); // at least one Solver has to be in collecting mode
1505  }
1506  else
1507  {
1508  nMaxCollectingModeSolvers = nSolvers;
1509  }
1510  nLimitCollectingModeSolvers = paraParams->getIntParamValue(MinNumberOfCollectingModeSolvers);
1511  absoluteGap = paraParams->getRealParamValue(ABgapForSwitchingToBestSolver);
1512  if( paraParams->getBoolParamValue(BreakFirstSubtree) )
1513  {
1514  breakingFirstSubtree = true;
1515  }
1516  }
1517 
1518  ///
1519  /// destructor
1520  ///
1522  )
1523  {
1524  for( unsigned int i = 0; i < (unsigned int)nSolvers; i++ )
1525  {
1526  delete pool[i];
1527  }
1528  if( pool ) delete[] pool;
1529  }
1530 
1531  ///
1532  /// set the Solver specified by rank is terminate requested
1533  ///
1534  virtual void interruptRequested(
1535  int rank ///< rank of the Solver
1536  )
1537  {
1538  assert(pool[SOLVER_POOL_INDEX( rank )]->getRank() == rank);
1539  pool[SOLVER_POOL_INDEX( rank )]->interruptRequested();
1540  }
1541 
1542  ///
1543  /// set the Solver specified by rank is terminate requested
1544  ///
1545  virtual void terminateRequested(
1546  int rank ///< rank of the Solver
1547  )
1548  {
1549  assert(pool[SOLVER_POOL_INDEX( rank )]->getRank() == rank);
1550  pool[SOLVER_POOL_INDEX( rank )]->terminateRequested();
1551  }
1552 
1553  ///
1554  /// check if the Solver specified by rank is interrupt requested or not
1555  /// @return return true if the Solver is interrupt requested, false otherwise
1556  ///
1557  virtual bool isInterruptRequested(
1558  int rank ///< rank of the Solver
1559  )
1560  {
1561  return (pool[SOLVER_POOL_INDEX( rank )]->getStatus() == InterruptRequested);
1562  }
1563 
1564  ///
1565  /// check if the Solver specified by rank is terminate requested or not
1566  /// @return return true if the Solver is terminate requested, false otherwise
1567  ///
1568  virtual bool isTerminateRequested(
1569  int rank ///< rank of the Solver
1570  )
1571  {
1572  return (pool[SOLVER_POOL_INDEX( rank )]->getStatus() == TerminateRequested);
1573  }
1574 
1575  ///
1576  /// set the Solver specified by rank is terminated
1577  ///
1578  virtual void terminated(
1579  int rank ///< rank of the Solver
1580  )
1581  {
1582  assert(pool[SOLVER_POOL_INDEX( rank )]->getRank() == rank);
1583  if( this->isSolverActive(rank) ) // it looks that node != NULL and inactive could be occurred with timing issue when TimeLimit is specified
1584  {
1585  inactivateSolver(rank, -1, 0); // number of nodes solved should be added when LC receives termination message */
1586  }
1587  assert(pool[SOLVER_POOL_INDEX( rank )]->getStatus() == TerminateRequested ||
1588  pool[SOLVER_POOL_INDEX( rank )]->getStatus() == InterruptRequested ||
1589  pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Inactive );
1590  //
1591  // The following situation could happen, whne terminate or interrupt is requested
1592  //
1593  std::map<int, BbParaSolverPoolElementPtr>::iterator p;
1594  p = activeSolvers.find(rank);
1595  if( p != activeSolvers.end() )
1596  {
1597  activeSolvers.erase(p);
1598  // inactiveSolvers.insert(std::make_pair(rank,pool[SOLVER_POOL_INDEX( rank )])); // in order not to assign new Task to this rank of solver
1599  }
1600  pool[SOLVER_POOL_INDEX( rank )]->terminated();
1601  }
1602 
1603  ///
1604  /// check if the Solver specified by rank is terminated or not
1605  /// @return return true if the Solver is terminated, false otherwise
1606  ///
1607  virtual bool isTerminated(
1608  int rank ///< rank of the Solver
1609  )
1610  {
1611  return (pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Terminated);
1612  }
1613 
1614  ///
1615  /// reinitialize to restart
1616  ///
1617  virtual void reinitToRestart(
1618  )
1619  {
1620  collectingMode = false;
1621  nCollectingModeSolvers = 0;
1622  switchOutTime = -1.0;
1623  mCollectingNodes = 1;
1624  nLimitCollectingModeSolvers = paraParams->getIntParamValue(MinNumberOfCollectingModeSolvers);
1625  }
1626 
1627  ///
1628  /// activate this Solver pool
1629  ///
1630  virtual void activate(
1631  )
1632  {
1633  active = true;
1634  }
1635 
1636  ///
1637  /// check if this Solver pool is active or not
1638  /// @return true if this Solver pool is active, false otherwise
1639  ///
1640  virtual bool isActive(
1641  )
1642  {
1643  return active;
1644  }
1645 
1646  ///
1647  /// get number of Solvers in this Solver pool
1648  /// @return number of Solvers
1649  ///
1650  virtual std::size_t getNSolvers(
1651  )
1652  {
1653  return nSolvers;
1654  }
1655 
1656  ///
1657  /// get number of nodes solved in current running Solvers
1658  ///
1659  virtual unsigned long long getNnodesSolvedInSolvers(
1660  )
1661  {
1662  return nNodesSolvedInSolvers;
1663  }
1664 
1665  ///
1666  /// get number of nodes solved in all Solvers: updated at termination of subtree computation
1667  ///
1668  virtual unsigned long long getTotalNodesSolved(
1669  )
1670  {
1671  return nTotalNodesSolved;
1672  }
1673 
1674  ///
1675  /// add number of nodes solved in all Solvers
1676  ///
1677  virtual void addTotalNodesSolved(
1678  unsigned long long num ///< number of nodes solved
1679  )
1680  {
1681  nTotalNodesSolved += num;
1682  }
1683 
1684  ///
1685  /// get number of nodes in all Solvers
1686  ///
1687  virtual unsigned long long getNnodesInSolvers(
1688  )
1689  {
1690  return nNodesInSolvers;
1691  }
1692 
1693  ///
1694  /// get number of active Solvers
1695  /// @return number of active Solvers
1696  ///
1697  virtual std::size_t getNumActiveSolvers(
1698  )
1699  {
1700  return activeSolvers.size();
1701  }
1702 
1703  ///
1704  /// get number of inactive Solvers
1705  /// @return number of inactive Solvers
1706  ///
1707  virtual std::size_t getNumInactiveSolvers(
1708  )
1709  {
1710  return inactiveSolvers.size();
1711  }
1712 
1713  ///
1714  /// check if the Solver specified by rank is active or not
1715  /// @return true if the Solver is active, false otherwise
1716  ///
1717  virtual bool isSolverActive(
1718  int rank ///< rank of the Solver to be checked
1719  )
1720  {
1721  return pool[SOLVER_POOL_INDEX(rank)]->isActive();
1722  }
1723 
1724  ///
1725  /// get current solving BbParaNode in the Solver specified by rank */
1726  /// @return pointer to BbParaNode object
1727  ///
1729  int rank ///< rank of the Solver
1730  )
1731  {
1732  return pool[SOLVER_POOL_INDEX(rank)]->getCurrentNode();
1733  }
1734 
1735  ///
1736  /// check if the number of Solvers in collecting mode can be increased or not
1737  /// @return true if the number can be increased, false otherwise
1738  ///
1740  )
1741  {
1742  return (nLimitCollectingModeSolvers < nMaxCollectingModeSolvers);
1743  }
1744 
1745  ///
1746  /// get limit number of Solvers that can be in collecting mode
1747  /// @return limit number of Solvers that can be in collecting mode
1748  ///
1749  virtual std::size_t getNLimitCollectingModeSolvers(
1750  )
1751  {
1752  return nLimitCollectingModeSolvers;
1753  }
1754 
1755  // Node *getCurrentNode(int rank){ return pool[rank-1]->getCurrentNode(); }
1756 
1757  ///
1758  /// check if this system is in collecting mode or not
1759  /// @return true if this system is in collecting mode, false otherwise
1760  ///
1761  virtual bool isInCollectingMode(
1762  )
1763  {
1764  return collectingMode;
1765  }
1766 
1767  ///
1768  /// get collecting mode of the Solver specified by rank
1769  /// @return true if the Solver is in collecting mode, false otherwise
1770  ///
1772  int rank ///< rank of the Solver to be checked
1773  )
1774  {
1775  return pool[SOLVER_POOL_INDEX(rank)]->isInCollectingMode();
1776  }
1777 
1778 
1779 
1780  ///
1781  /// extract current solving BbParaNode in the Solver specified by rank
1782  /// and inactivate the Solver
1783  /// @return pointer to BbParaNode object
1784  ///
1786  int rank, ///< rank of the Solver to be inactivated
1787  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool to pass it to inactivateSolver routine
1788  )
1789  {
1790  BbParaNode *node = pool[SOLVER_POOL_INDEX(rank)]->extractCurrentNode();
1791  // for checkpointing, it should be updated always.
1792  // node->setDualBoundValue( getDualBoundValue(rank) );
1793  // if( node ) // after racing, could be inactive with timing issue
1794  if( this->isSolverActive(rank) ) // it looks that node != NULL and inactive could be occurred with timing issue when TimeLimit is specified
1795  {
1796  inactivateSolver(rank, -1, paraNodePool); // number of nodes solved should be added when LC receives termination message */
1797  }
1798  return node;
1799  }
1800 
1801  ///
1802  /// extract current solving BbParaNode in the Solver specified by rank
1803  /// and inactivate the Solver
1804  /// @return pointer to BbParaNode object
1805  ///
1806 // BbParaNode *extractCurrentNodeGeneratedBySelfSplitAndInactivate(
1807 // int rank, ///< rank of the Solver to be inactivated
1808 // BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool to pass it to inactivateSolver routine
1809 // )
1810 // {
1811 // BbParaNode *node = pool[SOLVER_POOL_INDEX(rank)]->extractCurrentNode();
1812 // // for checkpointing, it should be updated always.
1813 // // node->setDualBoundValue( getDualBoundValue(rank) );
1814 // inactivateSolver(rank, -1, paraNodePool); // number of nodes solved should be added when LC recives termination message */
1815 // return node;
1816 // }
1817 
1818  ///
1819  /// check if solving BbParaNode in the Solver specified has descendant or not
1820  /// @return true if the Solver has descendant, false otherwise
1821  ///
1823  int rank ///< solver rank to be checked
1824  )
1825  {
1826  return pool[SOLVER_POOL_INDEX(rank)]->getCurrentNode()->hasDescendant();
1827  }
1828 
1829  ///
1830  /// add number of nodes solved
1831  ///
1832  virtual void addNumNodesSolved(
1833  long long numOfNodesSolved ///< number of nodes solved
1834  )
1835  {
1836  nNodesSolvedInSolvers += numOfNodesSolved;
1837  }
1838 
1839  ///
1840  /// get the number of nodes solved by the Solver specified
1841  /// @return the number of nodes solved
1842  ///
1843  virtual long long getNumOfNodesSolved(
1844  int rank ///< rank of the Solver
1845  )
1846  {
1847  assert(isSolverActive(rank) || isTerminateRequested(rank) || isInterruptRequested(rank));
1848  return pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesSolved();
1849  }
1850 
1851  ///
1852  /// get the number of nodes left by the Solver specified
1853  /// @return the number of nodes left
1854  ///
1855  virtual int getNumOfNodesLeft(
1856  int rank ///< rank of the Solver
1857  )
1858  {
1859  assert(isSolverActive(rank));
1860  return pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft();
1861  }
1862 
1863  ///
1864  /// get the number of nodes left in the Solver which has the best dual bound value
1865  /// @return the number of nodes left
1866  ///
1868  )
1869  {
1870  if( selectionHeap->getHeapSize() > 0 )
1871  {
1872  return selectionHeap->top()->getNumOfNodesLeft();
1873  }
1874  else
1875  {
1876  return 0; // no nodes exist
1877  }
1878  }
1879 
1880  ///
1881  /// get rank of the Solver which has top priority in selection criteria
1882  /// @return rank of the Solver
1883  ///
1884  virtual int getBestSolver(
1885  )
1886  {
1887  if( selectionHeap->getHeapSize() > 0 )
1888  {
1889  return selectionHeap->top()->getRank();
1890  }
1891  else
1892  {
1893  return -1; // no nodes exist
1894  }
1895  }
1896 
1897  ///
1898  /// get rank of the Solver which has top priority in selection criteria
1899  /// @return rank of the Solver
1900  ///
1902  )
1903  {
1904  if( selectionHeap->getHeapSize() > 0 )
1905  {
1906  for(int i = 1; i <= (int)selectionHeap->getHeapSize(); i++ )
1907  {
1908  int rank = selectionHeap->get(i)->getRank();
1909  if( getCurrentTask(rank) &&
1910  !(getCurrentTask(rank)->getAncestor()) )
1911  {
1912  return rank;
1913  }
1914  }
1915  return -1; // no nodes exist
1916  }
1917  else
1918  {
1919  return -1; // no nodes exist
1920  }
1921  }
1922 
1923  ///
1924  /// get dual bound value of solving BbParaNode by the Solver specified
1925  /// @return dual bound value
1926  ///
1927  virtual double getDualBoundValue(
1928  int rank ///< rank of the Solver
1929  )
1930  {
1931  assert(isSolverActive(rank));
1932  return pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue();
1933  }
1934 
1935  ///
1936  /// set SolverTerminationState to the Solver specified
1937  ///
1938  virtual void setTermState(
1939  int rank, ///< rank of the Solver
1940  ParaSolverTerminationState *inTermState ///< pointer to ParaSolverTerminationState object
1941  )
1942  {
1943  pool[SOLVER_POOL_INDEX(rank)]->setTermState(inTermState);
1944  }
1945 
1946  ///
1947  /// get SolverTermination state of the Solver specified
1948  /// @return pointer to SolverTermination object
1949  ///
1951  int rank ///< rank of the Solver
1952  )
1953  {
1954  return pool[SOLVER_POOL_INDEX(rank)]->getTermState();
1955  }
1956 
1957  ///
1958  /// update dual bound values of saving BbParaNodes by their dual bound values for subtrees
1959  ///
1961  )
1962  {
1963  for( int i = 1; i < paraComm->getSize(); i++ )
1964  {
1965  if( getCurrentTask(i) && getCurrentTask(i)->getAncestor() == 0 )
1966  {
1967  dynamic_cast<BbParaNode *>(getCurrentTask(i))->updateInitialDualBoundToSubtreeDualBound();
1968  }
1969  }
1970  }
1971 
1972 #ifdef UG_WITH_ZLIB
1973 
1974  ///
1975  /// write BbParaNodes to checkpoint file
1976  /// @return the number of BbParaNodes saved
1977  ///
1978  virtual int writeParaNodesToCheckpointFile(
1979  gzstream::ogzstream &out ///< ogzstream to output
1980  )
1981  {
1982  int n = 0;
1983  for( int i = 1; i < paraComm->getSize(); i++ )
1984  {
1985  // if( getCurrentTask(i) && getCurrentTask(i)->getAncestor() == 0 )
1986  if( getCurrentTask(i) )
1987  {
1988  BbParaNode *node = dynamic_cast<BbParaNode *>(getCurrentTask(i));
1989  while( node )
1990  {
1991  if( node->getAncestor() == 0 )
1992  {
1993  // std::cout << "CHECKPOINT: " << node->toSimpleString() << std::endl;
1994  node->write(out);
1995  n++;
1996  }
1997  node = node->next;
1998  }
1999  }
2000  }
2001  return n;
2002  }
2003 
2004  ///
2005  /// write Solver statistics to checkpoint file
2006  /// @return the number of Solvers whose statistics were written
2007  ///
2008  virtual int writeSolverStatisticsToCheckpointFile(
2009  gzstream::ogzstream &out ///< ogzstream to output
2010  )
2011  {
2012  int n = 0;
2013  for( int i = 1; i < paraComm->getSize(); i++ )
2014  {
2015  if( pool[SOLVER_POOL_INDEX(i)]->getTermState() )
2016  {
2017  pool[SOLVER_POOL_INDEX(i)]->getTermState()->write(out);
2018  n++;
2019  }
2020  }
2021  return n;
2022  }
2023 
2024 #endif
2025 
2026  ///
2027  /// increase the limit number of Solvers getting into collecting mode
2028  ///
2030  )
2031  {
2032  nLimitCollectingModeSolvers = std::min(nLimitCollectingModeSolvers+1,
2033  std::min(nMaxCollectingModeSolvers, nSolvers));
2034  }
2035 
2036  ///
2037  /// set collecting mode is allowed to the Solver specified by rank
2038  ///
2040  int rank
2041  )
2042  {
2044  }
2045 
2046  ///
2047  /// get an inactive Solver rank
2048  /// @return rank of inactivate Solver
2049  ///
2051  )
2052  {
2053  std::map<int, BbParaSolverPoolElementPtr>::iterator p;
2054  p = inactiveSolvers.begin();
2055  if( p == inactiveSolvers.end() )
2056  {
2057  return -1; // no inactive Solver
2058  }
2059  return p->second->getRank();
2060  }
2061 
2062  ///
2063  /// activate the Solver specified by rank with specified node which has been sent
2064  ///
2065  virtual void activateSolver(
2066  int rank, ///< rank of the Solver to be activated
2067  BbParaNode *node, ///< pointer to BbParaNode object to be sent to the Solver
2068  int nGoodNodesInNodePool, ///< number of good nodes in BbParaNodePool object
2069  double averageDualBoundGain ///< current average dual bound gain
2070  );
2071 
2072 
2073  ///
2074  /// activate the Solver specified by rank with specified node which has been sent and nNodesLeft
2075  /// (This method is for the racing winner)
2076  /// TODO: Need to check how this function is used
2077  ///
2078  virtual void activateSolver(
2079  int rank, ///< rank of the Solver to be activated
2080  BbParaNode *node, ///< pointer to BbParaNode object to be sent to the Solver
2081  int nNodesLeft ///< the number of nodes left in the Solver
2082  );
2083 
2084  ///
2085  /// activate a Solver with specified BbParaNode which is sent within this Solver pool
2086  /// @return rank of Solver which is activated
2087  ///
2088  virtual int activateSolver(
2089  BbParaNode *node, ///< pointer to BbParaNode object to be sent to a Solver
2090  BbParaRacingSolverPool *paraRacingSolverPool, ///< pointer to paraRacingSolverPool object
2091  ///< to check if the Solver is not solving root node
2092  bool rampUpPhase, ///< indicate if ramp-up phase or not
2093  int nGoodNodesInNodePool, ///< number of good BbParaNodes in BbParaNodePool
2094  double averageDualBoundGain ///< current average bound gain
2095  );
2096 
2097  ///
2098  /// add new subtree root node to the active solver with the specified rank
2099  ///
2100  virtual void addNewSubtreeRootNode(
2101  int rank, ///< the active solver rank
2102  BbParaNode *node ///< new subtree root node
2103  );
2104 
2105  ///
2106  /// make subtree root node as current task for the specified rank
2107  ///
2108  virtual void makeSubtreeRootNodeCurrent(
2109  int rank, ///< the active solver rank
2110  BbParaNode *node ///< subtree root node to make it current
2111  );
2112 
2113  ///
2114  /// remove subtree root node from the active solver with the specified rank
2115  ///
2116  virtual void removeSubtreeRootNode(
2117  int rank, ///< the active solver rank
2118  BbParaNode *node ///< subtree root node to be removed
2119  );
2120 
2121 // ///
2122 // /// remove all subtree root node from the active solver with the specified rank
2123 // /// @return list of all unprocessed nodes
2124 // ///
2125 // BbParaNode *removeAllSubtreeRootNode(
2126 // int rank, ///< the active solver rank
2127 // BbParaNode *node ///< subtree root node to be removed
2128 // );
2129 
2130  ///
2131  /// extract self-split subtree root node from the active solver with the specified rank
2132  ///
2133  virtual BbParaNode *extractSelfSplitSubtreeRootNode(
2134  int rank, ///< the active solver rank
2135  BbParaNode *node ///< subtree root node to be removed
2136  );
2137 
2138  ///
2139  /// get self-split subtree root node from the active solver with the specified rank
2140  ///
2141  virtual BbParaNode *getSelfSplitSubtreeRootNodes(
2142  int rank ///< the active solver rank
2143  );
2144 
2145  ///
2146  /// extract self-split subtree root node from the active solver with the specified rank
2147  ///
2148  virtual BbParaNode *extractSelfSplitSubtreeRootNodes(
2149  int rank ///< the active solver rank
2150  );
2151 
2152  ///
2153  /// delete current self-split subtree root node from the active solver with the specified rank
2154  ///
2155  virtual void deleteCurrentSubtreeRootNode(
2156  int rank ///< the active solver rank
2157  );
2158 
2159  ///
2160  /// inactivate the Solver specified by rank
2161  ///
2162  virtual void inactivateSolver(
2163  int rank, ///< rank of the Solver to be inactivated
2164  long long numOfNodesSolved, ///< number of nodes solved
2165  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool to change into collecting mode
2166  );
2167 
2168  ///
2169  /// reset counters in the Solver specified by rank
2170  ///
2171  virtual void resetCountersInSolver(
2172  int rank, ///< rank of the Solver to reset counters
2173  long long numOfNodesSolved, ///< number of nodes solved
2174  int numOfSelfSplitNodesLeft, ///< number of self-split nodes left
2175  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool to change into collecting mode
2176  );
2177 
2178  ///
2179  /// kill the Solver specified by rank
2180  /// @return pointer to BbParaNode object assigned to the Solver
2181  ///
2182  virtual BbParaNode *solverDied(
2183  int rank ///< rank of the Solver
2184  );
2185 
2186  ///
2187  /// switch out collecting mode
2188  ///
2189  virtual void switchOutCollectingMode(
2190  );
2191 
2192  ///
2193  /// enforced to switch out collecting mode of the Solver specified by rank if it is necessary
2194  ///
2195  virtual void enforcedSwitchOutCollectingMode(
2196  int rank ///< rank of the Solver
2197  );
2198 
2199  ///
2200  /// switch out collecting mode of the Solver specified by rank if it is necessary
2201  ///
2202  virtual void sendSwitchOutCollectingModeIfNecessary(
2203  int rank ///< rank of the Solver
2204  );
2205 
2206  ///
2207  /// get global best dual bound value
2208  /// @return global best dual bound value
2209  ///
2210  virtual double getGlobalBestDualBoundValue(
2211  ) = 0;
2212 
2213  ///
2214  /// switch in collecting mode
2215  ///
2216  virtual void switchInCollectingMode(
2217  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool object
2218  ) = 0;
2219 
2220  ///
2221  /// update Solver status
2222  ///
2223  virtual void updateSolverStatus(
2224  int rank, ///< rank of the Solver
2225  long long numNodesSolved, ///< number of nodes solved
2226  int numNodesLeft, ///< number of nodes left
2227  double solverLocalBestBound, ///< best bound value in the Solver
2228  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool object
2229  ) = 0;
2230 
2231  ///
2232  /// get multiplier of collecting BbParaNodes
2233  /// @return multiplier of collecting BbParaNodes
2234  ///
2235  virtual int getMCollectingNodes(
2236  )
2237  {
2238  return mCollectingNodes;
2239  }
2240 
2241  ///
2242  /// get maximum multiplier for the number of collecting BbParaNodes
2243  /// @return maximum multiplier for the number of collecting BbParaNodes
2244  ///
2246  )
2247  {
2248  return mMaxCollectingNodes;
2249  }
2250 
2251  ///
2252  /// the following functions are to omit rebooting collecting mode process
2253  ///
2254 
2255  ///
2256  /// get time of switching out collecting mode
2257  /// @return time of switching out collecting mode
2258  ///
2259  virtual double getSwichOutTime(
2260  )
2261  {
2262  return switchOutTime;
2263  }
2264 
2265  ///
2266  /// set time of switching out collecting mode
2267  ///
2268  virtual void setSwichOutTime(
2269  double time ///< time of switching out collecting mode
2270  )
2271  {
2272  switchOutTime = time;
2273  }
2274 
2275  ///
2276  /// check if dual bound gain testing is proceeding or not in the Solver specified
2277  /// @return true if dual bound gain testing is proceeding, false otherwise
2278  ///
2280  int rank ///< rank of the Solver
2281  )
2282  {
2283  return pool[SOLVER_POOL_INDEX(rank)]->isDualBoundGainTesting();
2284  }
2285 
2286 };
2287 
2288 ///
2289 /// class BbParaSolverPoolForMinimization
2290 /// (Solver Pool for Minimization Problems)
2291 ///
2293 {
2294 
2295 public:
2296 
2297  ///
2298  /// constructor
2299  ///
2301  double inMp, ///< multiplier of the threshold value p
2302  double inBgap, ///< threshold value of gap
2303  double inMBgap, ///< multiplier of the bgap value
2304  int inOriginRank, ///< origin rank of Solvers managed by this Solver pool
2305  ParaComm *inParaComm, ///< communicator used
2306  ParaParamSet *inParaParams, ///< paraParamSet used
2307  ParaTimer *inParaTimer ///< timer used
2308  )
2309  : BbParaSolverPool(inMp, inBgap, inMBgap, inOriginRank, inParaComm, inParaParams, inParaTimer)
2310  {
2311  selectionHeap = new AscendingSelectionHeap(nSolvers);
2312  if( paraParams->getIntParamValue(SolverOrderInCollectingMode) == 0) // ordered by dual bound value
2313  {
2314  collectingModeSolverHeap = new AscendingCollectingModeSolverHeap(
2315  std::min( nMaxCollectingModeSolvers * 2, nSolvers ) ); // can be more than nMaxCollectingModeSolvers
2316  }
2317  }
2318 
2319  ///
2320  /// constructor
2321  ///
2323  double inMp, ///< multiplier of the threshold value p
2324  double inBgap, ///< threshold value of gap
2325  double inMBgap, ///< multiplier of the bgap value
2326  int inNSolvers, ///< number of solvers
2327  int inOriginRank, ///< origin rank of Solvers managed by this Solver pool
2328  ParaComm *inParaComm, ///< communicator used
2329  ParaParamSet *inParaParams, ///< paraParamSet used
2330  ParaTimer *inParaTimer ///< timer used
2331  )
2332  : BbParaSolverPool(inMp, inBgap, inMBgap, inNSolvers, inOriginRank, inParaComm, inParaParams, inParaTimer)
2333  {
2334  selectionHeap = new AscendingSelectionHeap(nSolvers);
2335  if( paraParams->getIntParamValue(SolverOrderInCollectingMode) == 0) // ordered by dual bound value
2336  {
2337  collectingModeSolverHeap = new AscendingCollectingModeSolverHeap(
2338  std::min( nMaxCollectingModeSolvers * 2, nSolvers ) ); // can be more than nMaxCollectingModeSolvers
2339  }
2340  }
2341 
2342  ///
2343  /// destructor
2344  ///
2346  )
2347  {
2348  if( selectionHeap ) delete selectionHeap;
2349  if( collectingModeSolverHeap ) delete collectingModeSolverHeap;
2350  }
2351 
2352  ///
2353  /// get global best dual bound value
2354  /// @return global best dual bound value
2355  ///
2357  )
2358  {
2359  if( selectionHeap->getHeapSize() > 0 )
2360  {
2361  return selectionHeap->top()->getBestDualBoundValue();
2362  }
2363  else
2364  {
2365  return DBL_MAX; // no nodes exist
2366  }
2367  }
2368 
2369  ///
2370  /// switch in collecting mode
2371  ///
2372  virtual void switchInCollectingMode(
2373  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool object
2374  );
2375 
2376  ///
2377  /// update Solver status
2378  ///
2379  virtual void updateSolverStatus(
2380  int rank, ///< rank of the Solver
2381  long long numNodesSolved, ///< number of nodes solved
2382  int numNodesLeft, ///< number of nodes left
2383  double solverLocalBestBound, ///< best bound value in the Solver
2384  BbParaNodePool *paraNodePool ///< pointer to BbParaNodePool object
2385  );
2386 
2387  /*
2388  ///
2389  /// remove bounded BbParaNodes by given incumbnet value
2390  /// @return the number of bounded BbParaNodes
2391  ///
2392  int removeBoundedNodes(
2393  double incumbentValue ///< incumbent value
2394  )
2395  {
2396  int n = 0;
2397  for( int rank = originRank; rank < (originRank + static_cast<int>(nSolvers)); rank++ )
2398  {
2399  if( pool[SOLVER_POOL_INDEX( rank )]->getSelfSplitNodes() )
2400  {
2401  n += pool[SOLVER_POOL_INDEX( rank )]->removeBoundedNodes(incumbentValue);
2402  }
2403  }
2404  return n;
2405  }
2406  */
2407 
2408 };
2409 
2410 ///
2411 /// class BbParaRacingSolverPool
2412 /// (Racing Solver Pool)
2413 ///
2415 {
2416 
2417 protected:
2418 
2419  int nEvaluationStage; ///< number of Solvers that are in evaluation stage
2420  long long nNodesSolvedInBestSolver; ///< number of nodes solved in the best Solver
2421  long long nNodesInBestSolver; ///< number of nodes in the best Solver
2422  size_t nActiveSolvers; ///< number of active Solvers
2423  size_t nInactiveSolvers; ///< number of inactive Solvers
2424  double bestDualBound; ///< current best dual bound value
2425  double bestDualBoundInSolvers; ///< best dual bound value in Solvers
2426  BbParaSolverPoolElementPtr *pool; ///< Solver pool indexed by Solver's rank
2427  SelectionHeap *selectionHeap; ///< pointers to active Solvers in ascending or descending order
2428  BbParaNode *rootNode; ///< root BbParaNode
2429 
2430 public:
2431 
2432  ///
2433  /// constructor
2434  ///
2436  int inOriginRank, ///< origin rank of Solvers managed by this Solver pool
2437  ParaComm *inParaComm, ///< communicator used
2438  ParaParamSet *inParaParams, ///< paraParamSet used
2439  ParaTimer *inParaTimer, ///< timer used
2440  ParaDeterministicTimer *inParaDetTimer ///< deterministic timer used
2441  )
2442  : ParaRacingSolverPool(inOriginRank,inParaComm,inParaParams, inParaTimer, inParaDetTimer),
2443  nEvaluationStage(0),
2444  nNodesSolvedInBestSolver(0),
2445  nNodesInBestSolver(0),
2446  nActiveSolvers(0),
2447  nInactiveSolvers(0),
2448  bestDualBound(-DBL_MAX),
2449  bestDualBoundInSolvers(-DBL_MAX),
2450  rootNode(0)
2451  {
2452  // nSolvers = paraComm->getSize() - inOriginRank;
2453  pool = new BbParaSolverPoolElementPtr[nSolvers];
2454  for( int i = 0; i < nSolvers; i++ )
2455  {
2456  pool[i] = new BbParaSolverPoolElement(originRank+i);
2457  }
2458  selectionHeap = new DescendingSelectionHeap(static_cast<std::size_t>(nSolvers));
2459  }
2460 
2461  ///
2462  /// constructor
2463  ///
2465  int inNSolvers, ///< the number of racing solvers
2466  int inOriginRank, ///< origin rank of Solvers managed by this Solver pool
2467  ParaComm *inParaComm, ///< communicator used
2468  ParaParamSet *inParaParams, ///< paraParamSet used
2469  ParaTimer *inParaTimer, ///< timer used
2470  ParaDeterministicTimer *inParaDetTimer ///< deterministic timer used
2471  )
2472  : ParaRacingSolverPool(inOriginRank,inParaComm,inParaParams, inParaTimer, inParaDetTimer),
2473  nEvaluationStage(0),
2474  nNodesSolvedInBestSolver(0),
2475  nNodesInBestSolver(0),
2476  nActiveSolvers(0),
2477  nInactiveSolvers(0),
2478  bestDualBound(-DBL_MAX),
2479  bestDualBoundInSolvers(-DBL_MAX),
2480  rootNode(0)
2481  {
2482  // nSolvers = paraComm->getSize() - inOriginRank;
2483  nSolvers = inNSolvers;
2484  pool = new BbParaSolverPoolElementPtr[nSolvers];
2485  for( int i = 0; i < nSolvers; i++ )
2486  {
2487  pool[i] = new BbParaSolverPoolElement(originRank+i);
2488  }
2489  selectionHeap = new DescendingSelectionHeap(static_cast<std::size_t>(nSolvers));
2490  }
2491 
2492  ///
2493  /// destructor
2494  ///
2496  )
2497  {
2498  if( selectionHeap ) delete selectionHeap;
2499  for( int i = 0; i < nSolvers; i++ )
2500  {
2501  delete pool[i];
2502  }
2503  if( pool ) delete[] pool;
2504  if( rootNode ) delete rootNode;
2505  }
2506 
2507  ///
2508  /// set the Solver specified by rank is terminate requested
2509  ///
2510  virtual void interruptRequested(
2511  int rank ///< rank of the Solver
2512  )
2513  {
2514  assert(pool[SOLVER_POOL_INDEX( rank )]->getRank() == rank);
2515  pool[SOLVER_POOL_INDEX( rank )]->interruptRequested();
2516  }
2517 
2518  ///
2519  /// set the Solver specified by rank is terminate requested
2520  ///
2521  virtual void terminateRequested(
2522  int rank ///< rank of the Solver
2523  )
2524  {
2525  assert(pool[SOLVER_POOL_INDEX( rank )]->getRank() == rank);
2526  pool[SOLVER_POOL_INDEX( rank )]->terminateRequested();
2527  }
2528 
2529  ///
2530  /// check if the Solver specified by rank is interrupt requested or not
2531  /// @return return true if the Solver is interrupt requested, false otherwise
2532  ///
2533  virtual bool isInterruptRequested(
2534  int rank ///< rank of the Solver
2535  )
2536  {
2537  return (pool[SOLVER_POOL_INDEX( rank )]->getStatus() == InterruptRequested);
2538  }
2539 
2540  ///
2541  /// check if the Solver specified by rank is terminate requested or not
2542  /// @return return true if the Solver is terminate requested, false otherwise
2543  ///
2544  virtual bool isTerminateRequested(
2545  int rank ///< rank of the Solver
2546  )
2547  {
2548  return (pool[SOLVER_POOL_INDEX( rank )]->getStatus() == TerminateRequested);
2549  }
2550 
2551  ///
2552  /// set the Solver specified by rank is terminated
2553  ///
2554  virtual void terminated(
2555  int rank ///< rank of the Solver
2556  )
2557  {
2558  assert(pool[SOLVER_POOL_INDEX( rank )]->getRank() == rank);
2559  assert( !this->isSolverActive(rank) ); // it looks that node != NULL and inactive could be occurred with timing issue when TimeLimit is specified
2560  assert(pool[SOLVER_POOL_INDEX( rank )]->getStatus() == TerminateRequested ||
2561  pool[SOLVER_POOL_INDEX( rank )]->getStatus() == InterruptRequested ||
2562  pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Inactive );
2563  pool[SOLVER_POOL_INDEX( rank )]->terminated();
2564  }
2565 
2566  ///
2567  /// check if the Solver specified by rank is terminated or not
2568  /// @return return true if the Solver is terminated, false otherwise
2569  ///
2570  virtual bool isTerminated(
2571  int rank ///< rank of the Solver
2572  )
2573  {
2574  return (pool[SOLVER_POOL_INDEX( rank )]->getStatus() == Terminated);
2575  }
2576 
2577  ///
2578  /// reset racing solver pool
2579  ///
2580  virtual void reset(
2581  )
2582  {
2583  nEvaluationStage = 0;
2584  nNodesSolvedInBestSolver = 0;
2585  nNodesInBestSolver = 0;
2586  nActiveSolvers = 0;
2587  nInactiveSolvers = 0;
2588  bestDualBound = -DBL_MAX;
2589  bestDualBoundInSolvers = -DBL_MAX;
2590  rootNode = 0;
2591  if( selectionHeap ) delete selectionHeap;
2592  for( int i = 0; i < nSolvers; i++ )
2593  {
2594  delete pool[i];
2595  }
2596  if( pool ) delete[] pool;
2597  if( rootNode ) delete rootNode;
2598  pool = new BbParaSolverPoolElementPtr[nSolvers];
2599  for( int i = 0; i < nSolvers; i++ )
2600  {
2601  pool[i] = new BbParaSolverPoolElement(originRank+i);
2602  }
2603  selectionHeap = new DescendingSelectionHeap(static_cast<std::size_t>(nSolvers));
2604  }
2605 
2606  ///
2607  /// extract racing root BbParaNode
2608  ///
2610  )
2611  {
2612  rootNode->setDualBoundValue(getGlobalBestDualBoundValue());
2613  rootNode->setInitialDualBoundValue(getGlobalBestDualBoundValue());
2614  return rootNode->clone(paraComm);
2615  }
2616 
2617  ///
2618  /// get root BbParaNode object of the Solver specified
2619  ///
2621  int rank ///< rank of the Solver
2622  )
2623  {
2624  return rootNode;
2625  }
2626 
2627  ///
2628  /// get dual bound value of solving BbParaNode in the Solver specified by rank
2629  /// @return dual bound value
2630  ///
2631  virtual double getDualBoundValue(
2632  int rank ///< rank of the Solver
2633  )
2634  {
2635  return pool[SOLVER_POOL_INDEX(rank)]->getBestDualBoundValue();
2636  }
2637 
2638  ///
2639  /// get number of nodes solved in the Solver specified by rank
2640  /// @return number of nodes solved
2641  ///
2642  virtual long long getNumOfNodesSolved(
2643  int rank ///< rank of the Solver
2644  )
2645  {
2646  return pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesSolved();
2647  }
2648 
2649  ///
2650  /// get number of nodes left in the Solver specified by rank
2651  /// @return number of nodes left
2652  ///
2653  virtual int getNumNodesLeft(
2654  int rank ///< rank of the Solver
2655  )
2656  {
2657  return pool[SOLVER_POOL_INDEX(rank)]->getNumOfNodesLeft();
2658  }
2659 
2660  ///
2661  /// get global best dual bound value
2662  /// @return global best dual bound value
2663  ///
2665  )
2666  {
2667  if( selectionHeap->getHeapSize() > 0 )
2668  {
2669  return bestDualBound;
2670  }
2671  else
2672  {
2673  return -DBL_MAX; // no nodes exist
2674  }
2675  }
2676 
2677  ///
2678  /// get winner Solver rank
2679  /// @return rank of the winner Solver
2680  ///
2681 // int getWinner(
2682 // )
2683 // {
2684 // // assert( winnerRank > 0 );
2685 // return winnerRank; // -1 means that winner is not decided
2686 // }
2687 
2688  ///
2689  /// get number of nodes solved in the best Solver
2690  /// @return number of nodes solved in the best Solver
2691  ///
2692  virtual long long getNnodesSolvedInBestSolver(
2693  )
2694  {
2695  return nNodesSolvedInBestSolver;
2696  }
2697 
2698  ///
2699  /// get number of nodes left in the best Solver
2700  /// @return number of nodes left in the best Solver
2701  ///
2702  virtual long long getNnodesLeftInBestSolver(
2703  )
2704  {
2705  return nNodesInBestSolver;
2706  }
2707 
2708  ///
2709  /// get best dual bound value in inactivated Solvers
2710  /// @return best dual bound value in inactivated Solvers
2711  ///
2713  )
2714  {
2715  return bestDualBoundInSolvers;
2716  }
2717 
2718  ///
2719  /// activate racing ramp-up Solver pool with root BbParaNode object
2720  ///
2721  virtual void activate(
2722  BbParaNode *node ///< pointer to root BbParaNode object
2723  )
2724  {
2725  rootNode = node;
2726  for( int rank = originRank; rank < (originRank + nSolvers); rank++ )
2727  {
2729 // if( rank != originRank ||
2730 // ( paraParams->getIntParamValue(UgCplexRunningMode) != 1 ) )
2731 // if( rank != originRank )
2732 // {
2733  selectionHeap->insert(pool[SOLVER_POOL_INDEX( rank )]); // this should be called after activate: dual bound value need to be set
2734 // }
2735  nActiveSolvers++;
2736  }
2737  nInactiveSolvers = 0;
2738  nNodesInBestSolver = 1;
2739  }
2740 
2741  ///
2742  /// check if the specified Solver is active or not
2743  /// @return true if the specified Solver is active, false otherwise
2744  ///
2745  virtual bool isSolverActive(
2746  int rank ///< rank of the Solver
2747  )
2748  {
2749  if(pool[SOLVER_POOL_INDEX( rank )]->isRacingStage() ||
2750  pool[SOLVER_POOL_INDEX( rank )]->isEvaluationStage() )
2751  {
2752  return true;
2753  }
2754  else
2755  {
2756  return false;
2757  }
2758  }
2759 
2760  ///
2761  /// update Solver status
2762  ///
2763  virtual void updateSolverStatus(
2764  int rank, ///< rank of the Solver
2765  long long numNodesSolved, ///< number of nodes solved
2766  int numNodesLeft, ///< number of nodes left
2767  double solverLocalBestBound ///< best bound value in the Solver
2768  );
2769 
2770  ///
2771  /// check racing termination criteria
2772  ///
2773  virtual bool isWinnerDecided(
2774  bool feasibleSol ///< indicate if a feasible solution was generagted or not
2775  );
2776 
2777  ///
2778  /// inactivate the Solver specified by rank
2779  ///
2780  virtual void inactivateSolver(
2781  int rank ///< rank of the Solver
2782  )
2783  {
2784  if(pool[SOLVER_POOL_INDEX( rank )]->isRacingStage() ||
2785  pool[SOLVER_POOL_INDEX( rank )]->isEvaluationStage() )
2786  {
2787  if( pool[SOLVER_POOL_INDEX( rank )]->getBestDualBoundValue() > bestDualBoundInSolvers )
2788  {
2789  bestDualBoundInSolvers = pool[SOLVER_POOL_INDEX( rank )]->getBestDualBoundValue();
2790  }
2791  pool[SOLVER_POOL_INDEX( rank )]->inactivate();
2792  nInactiveSolvers++;
2793  nActiveSolvers--;
2794  }
2795  else
2796  {
2797  THROW_LOGICAL_ERROR2("Rank = ", rank);
2798  }
2799  }
2800 
2801  ///
2802  /// get number of active Solvers
2803  /// @return number of active Solvers
2804  ///
2805  virtual std::size_t getNumActiveSolvers(
2806  )
2807  {
2808  return nActiveSolvers;
2809  }
2810 
2811  ///
2812  /// get number of inactive Solvers
2813  /// @return number of inactive Solvers
2814  ///
2815  virtual std::size_t getNumInactiveSolvers(
2816  )
2817  {
2818  return nInactiveSolvers;
2819  }
2820 
2821  ///
2822  /// check if the Solver specified in an argument is evaluation stage or not
2823  /// @return true if the Solver is evaluation stage, false otherwise
2824  ///
2825  virtual bool isEvaluationStage(
2826  int rank
2827  )
2828  {
2829  return ( pool[SOLVER_POOL_INDEX( rank )]->isEvaluationStage() );
2830  }
2831 
2832  ///
2833  /// get active Solver number string
2834  /// @return string to show active Solver rank
2835  ///
2836  virtual std::string getStrActiveSolerNumbers(
2837  )
2838  {
2839  std::ostringstream oss;
2840  oss << " ";
2841  for( int rank = originRank; rank < (originRank + nSolvers); rank++ )
2842  {
2843  if( pool[SOLVER_POOL_INDEX( rank )]->isRacingStage() )
2844  {
2845  oss << rank << " ";
2846 
2847  }
2848  }
2849  return oss.str();
2850  }
2851 
2852 };
2853 
2854 }
2855 
2856 #endif // __BB_PARA_SOLVER_POOL_H__
2857 
virtual std::string getStrActiveSolerNumbers()
get active Solver number string
virtual void reinitToRestart()
reinitialize to restart
bool beforeFinishingFirstCollect
before finishing first collecting mode
virtual bool isSolverActive(int rank)
check if the specified Solver is active or not
std::size_t heapSize
current used heap size
double bestDualBoundValue
best dual bound value of the Solver
virtual void terminated(int rank)
set the Solver specified by rank is terminated
#define SOLVER_POOL_INDEX(rank)
virtual bool currentSolvingNodehaeDescendant(int rank)
extract current solving BbParaNode in the Solver specified by rank and inactivate the Solver ...
virtual void terminateRequested(int rank)
set the Solver specified by rank is terminate requested
virtual int getMMaxCollectingNodes()
get maximum multiplier for the number of collecting BbParaNodes
void prohibitCollectingMode()
prohibits to be in collecting mode
virtual int getBestSolver()
get rank of the Solver which has top priority in selection criteria
bool generator
this Solver can generate subproblems
double mp
multiplier of the threshold value p
bool isOutCollectingMode()
check if this Solver is out of collecting mode or not
BbParaNode * selfSplitNodes
list of nodes generated by self-split ramp-up
void switchIntoEvaluation()
switch into evaluation stage
void terminateRequested()
set TerminateRequseted on Solver status
std::size_t nCollectingModeSolvers
number of collecting mode Solvers
virtual std::size_t getNSolvers()
get number of Solvers in this Solver pool
void setNumOfNodesLeft(int inNumOfNodesLeft)
set number of nodes left
virtual void updateDualBoundsForSavingNodes()
update dual bound values of saving BbParaNodes by their dual bound values for subtrees ...
virtual long long getNumOfNodesSolved(int rank)
get number of nodes solved in the Solver specified by rank
class ParaRacingSolverPool (Racing Solver Pool)
double bgap
threshold value of gap
unsigned long long nTotalNodesSolved
number of nodes solved : updated at termination of subtree computation
bool collectingMode
indicate that this system is in collecting mode or not
void removeSubtreeRoot(BbParaNode *inNode)
remove subtree root node in self-split nodes list
int getRank()
get rank of the Solver
virtual double getDualBoundValue(int rank)
get dual bound value of solving BbParaNode in the Solver specified by rank
std::size_t nLimitCollectingModeSolvers
limit number of Solvers that can be in collecting mode
bool isActive()
check if this Solver is active or not
unsigned long long nNodesSolvedInSolvers
number of nodes solved in current running Solvers
std::size_t getMaxHeapSize() const
get max heap size
bool breakingFirstSubtree
breaking the first subtree
virtual bool isInCollectingMode()
check if this system is in collecting mode or not
bool active
indicate if this pool is active or not
virtual ~DescendingCollectingModeSolverHeap()
destructor
void setCollectingMode(bool b)
set collecting mode
BbParaSolverPoolElementPtr * getSelectionHeapElement()
extract current solving BbParaNode
Solver pool.
long long nNodesInBestSolver
number of nodes in the best Solver
BbParaSolverPoolElementPtr * getCollectingModeSolverHeapElement()
get collecting mode Solver heap element
Base class for ParaTask.
std::size_t getHeapSize() const
get current used heap size
class BbParaSolverPoolForMinimization (Solver Pool for Minimization Problems)
void setNumOfNodesSolved(long long inNumOfNodesSolved)
set number of nodes solved
bool collectingIsProhibited
collecting is temporary prohibited
int numOfDiffNodesLeft
number of nodes left difference between current number and that in the previous notification time ...
bool isRootTask()
check if root task or not
Definition: paraTask.h:624
void setCollectingModeSolverHeapElement(BbParaSolverPoolElementPtr *inCollectingModeSolverHeapElement)
set collecting mode Solver heap element
virtual ParaTask * getCurrentTask(int rank)
get root BbParaNode object of the Solver specified
SelectionHeap * selectionHeap
pointers to active Solvers in ascending or descending order
Base class for deterministic timer.
void setSelectionHeapElement(BbParaSolverPoolElementPtr *inSelectionHeapElement)
set selection heap element
static const int SolverOrderInCollectingMode
virtual std::size_t getNumActiveSolvers()
get number of active Solvers
double bestDualBound
current best dual bound value
long long nNodesSolvedInBestSolver
number of nodes solved in the best Solver
virtual void terminateRequested(int rank)
set the Solver specified by rank is terminate requested
virtual ~DescendingSelectionHeap()
destructor
void switchOutEvaluation()
switch out of evaluation stage
void interruptRequested()
set TerminateRequseted on Solver status
int numOfDiffNodesSolved
number of nodes solved difference between current number and that in the previous notification time ...
class BbParaRacingSolverPool (Racing Solver Pool)
class CollectingModeSolverHeap
int getNumOfDiffNodesSolved()
get number of nodes left difference between current number and that in the previous notification time...
int getNumOfDiffNodesLeft()
get number of nodes left difference between current number and that in the previous notification time...
class for deterministic timer
virtual bool isActive()
check if this Solver pool is active or not
void inactivate()
inactivate this Solver
BbParaNode * extractCurrentNode()
extract current solving BbParaNode
class DescendingSelectionHeap
virtual unsigned long long getNnodesInSolvers()
get number of nodes in all Solvers
class BbParaSolverPool (Solver Pool base class)
virtual void addTotalNodesSolved(unsigned long long num)
add number of nodes solved in all Solvers
BbParaSolverPool(double inMp, double inBgap, double inMBgap, int inOriginRank, ParaComm *inParaComm, ParaParamSet *inParaParams, ParaTimer *inParaTimer)
constructor
virtual bool isSolverActive(int rank)
check if the Solver specified by rank is active or not
Base class for Timer.
double switchOutTime
switch out time
ParaTask * getCurrentNode()
get current solving BbParaNode
virtual ~AscendingCollectingModeSolverHeap()
destructor
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 Selection Heap
BbParaSolverPoolElementPtr * collectingModeSolverHeapElement
pointer to collecting mode heap element the following values are used to make decision for load balan...
void terminated()
set Terminated on Solver status
virtual double getGlobalBestDualBoundValue()
get global best dual bound value
std::size_t heapSize
current used heap size
int mCollectingNodes
multiplier for the number of collecting BbParaNodes
BbParaSolverPoolElementPtr top() const
obtain top priority BbParaSolverPoolElementPtr
SolverStatus
void setDualBoundValue(double dualBoundValue)
set dual bound value on paraNode
BbParaSolverPoolElementPtr * pool
Solver pool indexed by Solver&#39;s rank.
virtual void incNLimitCollectingModeSolvers()
increase the limit number of Solvers getting into collecting mode
virtual double getDualBoundValue(int rank)
get dual bound value of solving BbParaNode by the Solver specified
virtual ~BbParaSolverPoolForMinimization()
destructor
static const int MinNumberOfCollectingModeSolvers
virtual void reset()
reset racing solver pool
virtual void activate(BbParaNode *node)
activate racing ramp-up Solver pool with root BbParaNode object
virtual bool canIncreaseLimitNLimitCollectingModeSolvers()
check if the number of Solvers in collecting mode can be increased or not
BbParaSolverPoolForMinimization(double inMp, double inBgap, double inMBgap, int inOriginRank, ParaComm *inParaComm, ParaParamSet *inParaParams, ParaTimer *inParaTimer)
constructor
BbParaNode * died()
kill this Solver
virtual std::size_t getNumInactiveSolvers()
get number of inactive Solvers
SolverStatus status
status of the Solver
BbParaNode * extractSubtreeRoot(BbParaNode *inNode)
extract subtree root node
int nDualBoundGainTesting
the number of dual bound gain testing Solvers
class BbParaSolverPoolElement (This class includes information about a Solver status) ...
bool isCandidateOfCollecting()
check if this Solver is candidate of collecting mode Solver
BbParaNode * getSelfSplitNodes()
get a list of nodes which are generated by self-split ramp-up
virtual void interruptRequested(int rank)
set the Solver specified by rank is terminate requested
virtual long long getNumOfNodesSolved(int rank)
get the number of nodes solved by the Solver specified
int mMaxCollectingNodes
maximum multiplier for the number of collecting BbParaNodes
long long numOfNodesSolved
number of nodes solved. -1 is the special value which means never updated in racing ...
CollectingModeSolverHeap * collectingModeSolverHeap
pointers to collecting mode Solvers in ascending or descending order
virtual bool isInterruptRequested(int rank)
check if the Solver specified by rank is interrupt requested or not
virtual unsigned long long getTotalNodesSolved()
get number of nodes solved in all Solvers: updated at termination of subtree computation ...
std::multimap< double, BbParaSolverPoolElementPtr > candidatesOfCollectingModeSolvers
pointers to candidates of collecting mode Solvers
#define THROW_LOGICAL_ERROR1(msg1)
Definition: paraDef.h:52
virtual bool isTerminateRequested(int rank)
check if the Solver specified by rank is terminate requested or not
double bestDualBoundInSolvers
best dual bound value in Solvers
virtual void setSwichOutTime(double time)
set time of switching out collecting mode
void setCollectingIsAllowed()
allows to be in collecting mode
virtual bool isSolverInCollectingMode(int rank)
get collecting mode of the Solver specified by rank
void makeSubtreeRootCurrent(BbParaNode *inNode)
make subtree root node current
void addSubtreeRoot(BbParaNode *inNode)
add subtree root node
int numOfNodesLeft
number of nodes left
static const int ABgapForSwitchingToBestSolver
virtual void setTermState(int rank, ParaSolverTerminationState *inTermState)
set SolverTerminationState to the Solver specified
class ParaSolverTerminationState (Solver termination state in a ParaSolver)
Base class for racing ramp-up parameter set.
double absoluteGap
allowable absolute dual bound gap to the best Solver
BbParaSolverPoolForMinimization(double inMp, double inBgap, double inMBgap, int inNSolvers, int inOriginRank, ParaComm *inParaComm, ParaParamSet *inParaParams, ParaTimer *inParaTimer)
constructor
void setTermState(ParaSolverTerminationState *inTermState)
set termination state
void racingActivate()
activate this Solver as a racing Solver
BbParaNode * rootNode
root BbParaNode
void setDualBoundGainTesting(bool value)
set dual bound gain is testing value
SolverStatus getStatus()
get Solver status
std::size_t getMaxHeapSize() const
get max heap size
class ParaParamSet
Definition: paraParamSet.h:850
BbParaSolverPoolElement * BbParaSolverPoolElementPtr
bool isDualBoundGainTesting()
check if dual bound gain is testing in this Solver or not
void deleteCurrentNode()
delete current solving BbParaNode
int getNumOfNodesLeft()
get number of nodes left
ParaSolverTerminationState * termState
Solver termination statistics: for checkpoint.
virtual void interruptRequested(int rank)
set the Solver specified by rank is terminate requested
bool beforeInitialCollect
before initial collecting mode
virtual ~AscendingSelectionHeap()
destructor
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
BbParaSolverPoolElementPtr * selectionHeapElement
pointer to selection heap element
std::map< int, BbParaSolverPoolElementPtr > inactiveSolvers
pointers to inactive Solvers
int nEvaluationStage
number of Solvers that are in evaluation stage
virtual bool isTerminateRequested(int rank)
check if the Solver specified by rank is terminate requested or not
virtual int getNumNodesLeft(int rank)
get number of nodes left in the Solver specified by rank
virtual ParaTask * getCurrentTask(int rank)
get current solving BbParaNode in the Solver specified by rank */
virtual void activate()
activate this Solver pool
SelectionHeap * selectionHeap
pointers to active Solvers in ascending or descending order
BbParaSolverPool(double inMp, double inBgap, double inMBgap, int inNSolvers, int inOriginRank, ParaComm *inParaComm, ParaParamSet *inParaParams, ParaTimer *inParaTimer)
constructor
BbParaSolverPoolElementPtr get(int i) const
obtain i-th in heap BbParaSolverPoolElementPtr
virtual bool isTerminated(int rank)
check if the Solver specified by rank is terminated or not
virtual ParaSolverTerminationState * getTermState(int rank)
get SolverTermination state of the Solver specified
class BbParaNode
Definition: bbParaNode.h:61
void setNumOfDiffNodesSolved(int inNumOfDiff)
set number of nodes left difference between current number and that in the previous notification time...
bool collectingMode
indicate if current Solver is in collecting mode or not
void setDualBoundValue(double inDualBoundValue)
setter of dual bound value
Definition: bbParaNode.h:323
virtual std::size_t getNumInactiveSolvers()
get number of inactive Solvers
BbParaRacingSolverPool(int inOriginRank, ParaComm *inParaComm, ParaParamSet *inParaParams, ParaTimer *inParaTimer, ParaDeterministicTimer *inParaDetTimer)
constructor
bool candidateOfCollecting
indicate that this Solver is a candidate of collecting mode Solver
class ParaSolverPool (Solver Pool base class)
virtual int getNumOfNodesLeftInBestSolver()
get the number of nodes left in the Solver which has the best dual bound value
ResultOfInsert
results of insert
virtual ~BbParaSolverPool()
destructor
double getDualBoundValue()
getter of dual bound value
Definition: bbParaNode.h:303
BbParaNode * extractSelfSplitNodes()
extract a list of nodes which are generated by self-split ramp-up
ResultOfInsert insert(BbParaSolverPoolElementPtr solver)
insert BbParaSolverPoolElementPtr to Selection Heap
virtual double getGlobalBestDualBoundValue()
get global best dual bound value
virtual BbParaNode * clone(ParaComm *comm)=0
clone this BbParaNode
virtual std::size_t getNumActiveSolvers()
get number of active Solvers
std::size_t maxHeapSize
maximum size of this heap
virtual int getInactiveSolverRank()
get an inactive Solver rank
class DescendingCollectingModeSolverHeap
size_t nInactiveSolvers
number of inactive Solvers
virtual bool isDualBounGainTesting(int rank)
check if dual bound gain testing is proceeding or not in the Solver specified
std::size_t maxHeapSize
maximum size of this heap
void setNoGenerator()
make this Solver No generator
bool isCollectingProhibited()
check if this Solver cannot be allowed in collecting mode
std::size_t nMaxCollectingModeSolvers
maximum number of Solvers that can be in collecting mode
BbParaSolverPoolElementPtr * pool
Solver pool indexed by Solver&#39;s rank.
static int nSolvers
Definition: fscip.cpp:75
virtual long long getNnodesLeftInBestSolver()
get number of nodes left in the best Solver
virtual BbParaNode * extractNode()
extract racing root BbParaNode
size_t nActiveSolvers
number of active Solvers
bool dualBoundGainTesting
indicate that dual bound gain is testing or not
bool hasDescendant()
check if this task has descendant or not
Definition: paraTask.h:930
bool isEvaluationStage()
check if this Solver is in evaluation stage
class BbParaNodePool
void setBestDualBoundValue(double inBestDualBoundValue)
set best dual bound value
virtual BbParaNode * extractCurrentNodeAndInactivate(int rank, BbParaNodePool *paraNodePool)
extract current solving BbParaNode in the Solver specified by rank and inactivate the Solver ...
virtual void inactivateSolver(int rank)
inactivate the Solver specified by rank
void activate(BbParaNode *inNode)
activate this Solver
virtual double getSwichOutTime()
the following functions are to omit rebooting collecting mode process
BbParaSolverPoolElementPtr top() const
obtain top priority BbParaSolverPoolElementPtr
virtual std::size_t getNLimitCollectingModeSolvers()
get limit number of Solvers that can be in collecting mode
std::size_t nGenerator
number of generators
virtual void terminated(int rank)
set the Solver specified by rank is terminated
double getBestDualBoundValue()
get best dual bound value
bool isSameNodeIdAs(const BbParaNode &inNode)
check if this node&#39;s id is the same as that of argument ParaNode&#39;s task id
Definition: bbParaNode.h:708
virtual unsigned long long getNnodesSolvedInSolvers()
get number of nodes solved in current running Solvers
class ParaTimer
Definition: paraTimer.h:48
BbParaRacingSolverPool(int inNSolvers, int inOriginRank, ParaComm *inParaComm, ParaParamSet *inParaParams, ParaTimer *inParaTimer, ParaDeterministicTimer *inParaDetTimer)
constructor
virtual int getMCollectingNodes()
get multiplier of collecting BbParaNodes
static const int BreakFirstSubtree
int rank
rank of the Solver
std::map< int, BbParaSolverPoolElementPtr > deadSolvers
pointers to dead Solvers
virtual bool isEvaluationStage(int rank)
check if the Solver specified in an argument is evaluation stage or not
ParaSolverTerminationState * getTermState()
get termination state
bool isRacingStage()
check if this Solver is in racing stage
std::size_t getHeapSize() const
get current used heap size
virtual void setCollectingIsAllowed(int rank)
set collecting mode is allowed to the Solver specified by rank
class AscendingSelectionHeap
void setInitialDualBoundValue(double inTrueDualBoundValue)
setter of initial dual bound value
Definition: bbParaNode.h:333
virtual int getNumOfNodesLeft(int rank)
get the number of nodes left by the Solver specified
bool isGenerator()
check if this Solver is generator or not */
long long getNumOfNodesSolved()
get number of nodes solved
bool isInCollectingMode()
check if this Solver is in collecting mode or not
virtual void addNumNodesSolved(long long numOfNodesSolved)
add number of nodes solved
virtual bool isInterruptRequested(int rank)
check if the Solver specified by rank is interrupt requested or not
BbParaSolverPoolElementPtr * heap
heap : contents are BbParaSolverPoolElementPtr
void setNumOfDiffNodesLeft(int inNumOfDiff)
set number of nodes left difference between current number and that in the previous notification time...
Base class of communicator object.
Definition: paraComm.h:101
void setCandidateOfCollecting(bool b)
set candidate of collecting mode Solver
unsigned long long nNodesInSolvers
number of nodes in all Solvers
BbParaSolverPoolElementPtr * heap
heap : contents are BbParaSolverPoolElementPtr
static const int MaxNumberOfCollectingModeSolvers
BbParaNode * currentNode
solving node
virtual double getBestDualBoundInInactivatedSolvers()
get best dual bound value in inactivated Solvers
virtual bool isTerminated(int rank)
check if the Solver specified by rank is terminated or not
double mBgap
multiplier of the bgap value
BbParaSolverPoolElement(int inRank)
constructor
class ParaTask
Definition: paraTask.h:541
ParaTaskGenealogicalPtr * getAncestor()
getter of ancestor
Definition: bbParaNode.h:373
std::map< int, BbParaSolverPoolElementPtr > activeSolvers
pointers to active Solvers
virtual long long getNnodesSolvedInBestSolver()
get winner Solver rank
virtual int getGoodSolverSolvingEssentialNode()
get rank of the Solver which has top priority in selection criteria