Changes to AdaptiveLB strategy
[charm.git] / src / ck-ldb / AdaptiveLB.C
1 /**
2  * \addtogroup CkLdb
3 */
4 /*@{*/
5
6 #include "AdaptiveLB.h"
7 #include "ckgraph.h"
8
9 #define alpha 4.0e-6
10 #define beta 2.67e-9
11 #define percent_overhead 10
12
13 extern LBAllocFn getLBAllocFn(char *lbname);
14
15 CreateLBFunc_Def(AdaptiveLB, "Allow multiple strategies to work serially")
16
17 AdaptiveLB::AdaptiveLB(const CkLBOptions &opt): CentralLB(opt)
18 {
19   lbname = "AdaptiveLB";
20   const char *lbs = theLbdb->loadbalancer(opt.getSeqNo());
21   if (CkMyPe() == 0)
22     CkPrintf("[%d] AdaptiveLB created with %s\n",CkMyPe(), lbs);
23
24   char *lbcopy = strdup(lbs);
25   char *greedyLBString = "GreedyLB";
26   char *refineLBString = "RefineLB";
27   char *metisLBString = "MetisLB";
28
29   LBAllocFn fn = getLBAllocFn(greedyLBString);
30   if (fn == NULL) {
31     CkPrintf("LB> Invalid load balancer: %s.\n", greedyLBString);
32     CmiAbort("");
33   }
34   BaseLB *glb = fn();
35   greedyLB = (CentralLB*)glb;
36
37   fn = getLBAllocFn(refineLBString);
38   if (fn == NULL) {
39     CkPrintf("LB> Invalid load balancer: %s.\n", refineLBString);
40     CmiAbort("");
41   }
42   BaseLB *rlb = fn();
43   refineLB = (CentralLB*)rlb;
44
45   fn = getLBAllocFn(metisLBString);
46   if (fn == NULL) {
47     CkPrintf("LB> Invalid load balancer: %s.\n", metisLBString);
48     CmiAbort("");
49   }
50   BaseLB *slb = fn();
51   metisLB = (CentralLB*)slb;
52 }
53
54 void AdaptiveLB::work(LDStats* stats)
55 {
56
57   ProcArray *parr = new ProcArray(stats);
58   ObjGraph *ogr = new ObjGraph(stats);
59   CkPrintf("Adaptive work\n");
60
61   bool isRefine = theLbdb->isStrategyRefine();
62
63   // Calculate the load and total messages
64   double totalLoad = 0.0;
65   long totalMsgs = 0;
66   long long totalBytes = 0;
67   int vertnbr = ogr->vertices.size();
68
69   /** the object load is normalized to an integer between 0 and 256 */
70   for(int i = 0; i < vertnbr; i++) {
71     totalLoad += ogr->vertices[i].getVertexLoad();
72   }
73
74   for(int i = 0; i < vertnbr; i++) {
75     for(int j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
76       totalMsgs += ogr->vertices[i].sendToList[j].getNumMsgs();
77       totalBytes += ogr->vertices[i].sendToList[j].getNumBytes();
78     }
79   }
80   double commOverhead = (totalMsgs * alpha) + (totalBytes * beta);
81
82   CkPrintf("AdaptiveLB> Total load %E\n", totalLoad);
83   CkPrintf("AdaptiveLB> Total Msgs %d\n", totalMsgs);
84   CkPrintf("AdaptiveLB> Total Bytes %ld\n", totalBytes);
85   CkPrintf("AdaptiveLB> Total Comm Overhead %E Total Load %E\n", commOverhead, totalLoad);
86
87   double after_lb_max;
88   double after_lb_avg;
89   int is_prev_lb_refine;
90   GetPrevLBData(is_prev_lb_refine, after_lb_max, after_lb_avg);
91
92   CkPrintf("AdaptiveLB> Previous LB %d\n", is_prev_lb_refine);
93
94   // Choose the right LB
95   //
96   // If communication overhead is 10% computation, then choose Scotch LB
97   if (commOverhead > (totalLoad * percent_overhead / 100)) {
98     metisLB->work(stats);
99     CkPrintf("---METIS LB\n");
100   } else {
101     if (is_prev_lb_refine == 1) {
102       if (after_lb_max/after_lb_avg < 1.01) {
103         refineLB->work(stats);
104         CkPrintf("---REFINE LB\n");
105       } else {
106         greedyLB->work(stats);
107         CkPrintf("---GREEDY LB\n");
108       }
109     } else if (is_prev_lb_refine == -1) {
110       greedyLB->work(stats);
111       CkPrintf("---GREEDY LB\n");
112     } else {
113       refineLB->work(stats);
114       CkPrintf("---REFINE LB\n");
115     }
116   }
117   UpdateLBDBWithData(stats->is_prev_lb_refine, stats->after_lb_max,
118       stats->after_lb_avg);
119
120   delete parr;
121   delete ogr;
122
123 }
124
125 #include "AdaptiveLB.def.h"
126
127
128 /*@}*/