Merging
[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 isComm = theLbdb->isStrategyComm();
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 tmp;
88   double refine_max_avg_ratio, lb_max_avg_ratio;
89   double greedy_max_avg_ratio;
90   int lb_type;
91   double comm_ratio, comm_refine_ratio;
92
93   GetPrevLBData(lb_type, lb_max_avg_ratio, tmp);
94   GetLBDataForLB(1, refine_max_avg_ratio, tmp);
95   GetLBDataForLB(0, greedy_max_avg_ratio, tmp);
96   GetLBDataForLB(2, tmp, comm_ratio);
97   GetLBDataForLB(3, tmp, comm_refine_ratio);
98
99   CkPrintf("AdaptiveLB> Previous LB %d\n", lb_type);
100
101   // Choose the right LB
102   //
103   // If communication overhead is 10% computation, then choose Scotch LB
104   if (isComm || (commOverhead > (totalLoad * percent_overhead / 100))) {
105     if(lb_type == -1) {
106       lb_type = 2;
107       metisLB->work(stats);
108       CkPrintf("---METIS LB\n");
109     } else if (comm_refine_ratio <= 1.01) {
110       lb_type = 3;
111       //commRefineLB->work(stats);
112       CkPrintf("---CommAwareRefineLB\n");
113     } else if (comm_ratio <= 1.01) {
114       lb_type = 2;
115       metisLB->work(stats);
116       CkPrintf("---METIS LB\n");
117     } else {
118       lb_type = 3;
119       //commRefineLB->work(stats);
120       CkPrintf("---CommAwareRefineLB\n");
121     }
122
123   } else {
124     if (lb_type == -1) {
125       lb_type = 0;
126       greedyLB->work(stats);
127       CkPrintf("---GREEDY LB\n");
128     } else if (refine_max_avg_ratio <= 1.01) {
129       lb_type = 1;
130       refineLB->work(stats);
131       CkPrintf("---REFINE LB\n");
132     } else if (greedy_max_avg_ratio <= 1.01) {
133       lb_type = 0;
134       greedyLB->work(stats);
135       CkPrintf("---GREEDY LB\n");
136     } else {
137       lb_type = 1;
138       refineLB->work(stats);
139       CkPrintf("---REFINE LB\n");
140     }
141   }
142   UpdateLBDBWithData(lb_type, stats->after_lb_max, stats->after_lb_avg,
143       stats->local_comm, stats->remote_comm);
144
145   delete parr;
146   delete ogr;
147
148 }
149
150 #include "AdaptiveLB.def.h"
151
152
153 /*@}*/