Changed to LBDatabase to handle refine strategy
[charm.git] / src / ck-ldb / LBDatabase.h
1 /**
2  * \addtogroup CkLdb
3 */
4 /*@{*/
5
6 #ifndef LBDATABASE_H
7 #define LBDATABASE_H
8
9
10 //#include <charm++.h>
11 //#include "ckreduction.h" 
12 #include "lbdb.h"
13 #include "LBDBManager.h"
14 #include "lbdb++.h"
15
16 #include <vector>
17
18 #define LB_FORMAT_VERSION     2
19
20 extern int _lb_version;
21
22
23
24 // command line options
25 class CkLBArgs
26 {
27 private:
28   double _autoLbPeriod;         // in seconds
29   double _lb_alpha;             // per message send overhead
30   double _lb_beeta;             // per byte send overhead
31   int _lb_debug;                // 1 or greater
32   int _lb_printsumamry;         // print summary
33   int _lb_loop;                 // use multiple load balancers in loop
34   int _lb_ignoreBgLoad;
35   int _lb_migObjOnly;           // only consider migratable objs
36   int _lb_syncResume;
37   int _lb_samePeSpeed;          // ignore cpu speed
38   int _lb_testPeSpeed;          // test cpu speed
39   int _lb_useCpuTime;           // use cpu instead of wallclock time
40   int _lb_statson;              // stats collection
41   int _lb_traceComm;            // stats collection for comm
42   int _lb_central_pe;           // processor number for centralized startegy
43   int _lb_percentMovesAllowed; //Specifies restriction on num of chares to be moved(as a percentage of total number of chares). Used by RefineKLB
44   int _lb_teamSize;             // specifies the team size for TeamLB
45 public:
46   CkLBArgs() {
47 #if CMK_BIGSIM_CHARM
48     _autoLbPeriod = 0.02;       // bigsim needs it to be faster (lb may hang)
49 #else
50     _autoLbPeriod = 0.5;        // 0.5 second default
51 #endif
52     _lb_debug = _lb_ignoreBgLoad = _lb_syncResume = _lb_useCpuTime = 0;
53     _lb_printsumamry = _lb_migObjOnly = 0;
54     _lb_statson = _lb_traceComm = 1;
55     _lb_percentMovesAllowed=100;
56     _lb_loop = 0;
57     _lb_central_pe = 0;
58     _lb_teamSize = 1;
59   }
60   inline double & lbperiod() { return _autoLbPeriod; }
61   inline int & debug() { return _lb_debug; }
62   inline int & teamSize() {return _lb_teamSize; }
63   inline int & printSummary() { return _lb_printsumamry; }
64   inline int & lbversion() { return _lb_version; }
65   inline int & loop() { return _lb_loop; }
66   inline int & ignoreBgLoad() { return _lb_ignoreBgLoad; }
67   inline int & migObjOnly() { return _lb_migObjOnly; }
68   inline int & syncResume() { return _lb_syncResume; }
69   inline int & samePeSpeed() { return _lb_samePeSpeed; }
70   inline int & testPeSpeed() { return _lb_testPeSpeed; }
71   inline int & useCpuTime() { return _lb_useCpuTime; }
72   inline int & statsOn() { return _lb_statson; }
73   inline int & traceComm() { return _lb_traceComm; }
74   inline int & central_pe() { return _lb_central_pe; }
75   inline double & alpha() { return _lb_alpha; }
76   inline double & beeta() { return _lb_beeta; }
77   inline int & percentMovesAllowed() { return _lb_percentMovesAllowed;}
78 };
79
80 extern CkLBArgs _lb_args;
81
82 extern int _lb_predict;
83 extern int _lb_predict_delay;
84 extern int _lb_predict_window;
85 #ifndef PREDICT_DEBUG
86 #define PREDICT_DEBUG  0   // 0 = No debug, 1 = Debug info on
87 #endif
88 #define PredictorPrintf  if (PREDICT_DEBUG) CmiPrintf
89
90 // used in constructor of all load balancers
91 class CkLBOptions
92 {
93 private:
94   int seqno;            // for centralized lb, the seqno
95 public:
96   CkLBOptions(): seqno(-1) {}
97   CkLBOptions(int s): seqno(s) {}
98   int getSeqNo() const { return seqno; }
99 };
100 PUPbytes(CkLBOptions)
101                                                                                 
102 #include "LBDatabase.decl.h"
103
104 extern CkGroupID _lbdb;
105
106 class LBDB;
107
108 CkpvExtern(int, numLoadBalancers);
109 CkpvExtern(int, hasNullLB);
110 CkpvExtern(int, lbdatabaseInited);
111
112 // LB options, mostly controled by user parameter
113 extern "C" char * _lbtopo;
114
115 typedef void (*LBCreateFn)();
116 typedef BaseLB * (*LBAllocFn)();
117 void LBDefaultCreate(LBCreateFn f);
118
119 void LBRegisterBalancer(const char *, LBCreateFn, LBAllocFn, const char *, int shown=1);
120
121 void _LBDBInit();
122
123 // main chare
124 class LBDBInit : public Chare {
125   public:
126     LBDBInit(CkArgMsg*);
127     LBDBInit(CkMigrateMessage *m):Chare(m) {}
128 };
129
130 // class which implement a virtual function for the FuturePredictor
131 class LBPredictorFunction {
132 public:
133   virtual ~LBPredictorFunction() {}
134   int num_params;
135
136   virtual void initialize_params(double *x) {double normall=1.0/pow((double)2,(double)31); for (int i=0; i<num_params; ++i) x[i]=rand()*normall;}
137
138   virtual double predict(double x, double *params) =0;
139   virtual void print(double *params) {PredictorPrintf("LB: unknown model\n");};
140   virtual void function(double x, double *param, double &y, double *dyda) =0;
141 };
142
143 // a default implementation for a FuturePredictor function
144 class DefaultFunction : public LBPredictorFunction {
145  public:
146   // constructor
147   DefaultFunction() {num_params=6;};
148
149   // compute the prediction function for the variable x with parameters param
150   double predict(double x, double *param) {return (param[0] + param[1]*x + param[2]*x*x + param[3]*sin(param[4]*(x+param[5])));}
151
152   void print(double *param) {PredictorPrintf("LB: %f + %fx + %fx^2 + %fsin%f(x+%f)\n",param[0],param[1],param[2],param[3],param[4],param[5]);}
153
154   // compute the prediction function and its derivatives respect to the parameters
155   void function(double x, double *param, double &y, double *dyda) {
156     double tmp;
157
158     y = predict(x, param);
159
160     dyda[0] = 1;
161     dyda[1] = x;
162     dyda[2] = x*x;
163     tmp = param[4] * (x+param[5]);
164     dyda[3] = sin(tmp);
165     dyda[4] = param[3] * (x+param[5]) * cos(tmp);
166     dyda[5] = param[3] * param[4] *cos(tmp);
167   }
168 };
169
170
171 class LBDatabase : public CBase_LBDatabase {
172 public:
173   LBDatabase(void)  { init(); }
174   LBDatabase(CkMigrateMessage *m)  { init(); }
175   ~LBDatabase()  { if (avail_vector) delete [] avail_vector; }
176   
177 private:
178   void init();
179 public:
180   inline static LBDatabase * Object() { return CkpvAccess(lbdatabaseInited)?(LBDatabase *)CkLocalBranch(_lbdb):NULL; }
181 #if CMK_LBDB_ON
182   inline LBDB *getLBDB() {return (LBDB*)(myLDHandle.handle);}
183 #endif
184
185   static void initnodeFn(void);
186
187   void pup(PUP::er& p);
188
189   /*
190    * Calls from object managers to load database
191    */
192   inline LDOMHandle RegisterOM(LDOMid userID, void *userptr, LDCallbacks cb) {
193     return LDRegisterOM(myLDHandle,userID, userptr, cb);
194   };
195
196   inline void RegisteringObjects(LDOMHandle _om) {
197     LDRegisteringObjects(_om);
198   };
199
200   inline void DoneRegisteringObjects(LDOMHandle _om) {
201     LDDoneRegisteringObjects(_om);
202   };
203
204   inline LDObjHandle RegisterObj(LDOMHandle h, LDObjid id,
205                           void *userptr,int migratable) {
206     return LDRegisterObj(h,id,userptr,migratable);
207   };
208
209   inline void UnregisterObj(LDObjHandle h) { LDUnregisterObj(h); };
210
211   inline void ObjTime(LDObjHandle h, double walltime, double cputime) {
212     LDObjTime(h,walltime,cputime);
213   };
214
215   inline void GetObjLoad(LDObjHandle &h, LBRealType &walltime, LBRealType &cputime) {
216     LDGetObjLoad(h,&walltime,&cputime);
217   };
218
219   inline void QueryKnownObjLoad(LDObjHandle &h, LBRealType &walltime, LBRealType &cputime) {
220     LDQueryKnownObjLoad(h,&walltime,&cputime);
221   };
222
223   inline int RunningObject(LDObjHandle* _o) const { 
224 #if CMK_LBDB_ON
225       LBDB *const db = (LBDB*)(myLDHandle.handle);
226       if (db->ObjIsRunning()) {
227         *_o = db->RunningObj();
228         return 1;
229       } 
230 #endif
231       return 0;
232       //return LDRunningObject(myLDHandle,_o);
233   };
234   inline const LDObjHandle *RunningObject() const { 
235 #if CMK_LBDB_ON
236       LBDB *const db = (LBDB*)(myLDHandle.handle);
237       if (db->ObjIsRunning()) {
238         return &db->RunningObj();
239       } 
240 #endif
241       return NULL;
242   };
243   inline const LDObjHandle &GetObjHandle(int idx) { return LDGetObjHandle(myLDHandle, idx);}
244   inline void ObjectStart(const LDObjHandle &_h) { LDObjectStart(_h); };
245   inline void ObjectStop(const LDObjHandle &_h) { LDObjectStop(_h); };
246   inline void Send(const LDOMHandle &_om, const LDObjid _id, unsigned int _b, int _p, int force = 0) {
247     LDSend(_om, _id, _b, _p, force);
248   };
249   inline void MulticastSend(const LDOMHandle &_om, LDObjid *_ids, int _n, unsigned int _b, int _nMsgs=1) {
250     LDMulticastSend(_om, _ids, _n, _b, _nMsgs);
251   };
252
253   void EstObjLoad(const LDObjHandle &h, double cpuload);
254   inline void NonMigratable(LDObjHandle h) { LDNonMigratable(h); };
255   inline void Migratable(LDObjHandle h) { LDMigratable(h); };
256   inline void UseAsyncMigrate(LDObjHandle h, CmiBool flag) { LDAsyncMigrate(h, flag); };
257   inline void DumpDatabase(void) { LDDumpDatabase(myLDHandle); };
258
259   /*
260    * Calls from load balancer to load database
261    */  
262   inline void NotifyMigrated(LDMigratedFn fn, void *data) 
263   {
264     LDNotifyMigrated(myLDHandle,fn,data);
265   };
266  
267   inline void AddStartLBFn(LDStartLBFn fn, void *data) 
268   {
269     LDAddStartLBFn(myLDHandle,fn,data);
270   };
271
272   inline void RemoveStartLBFn(LDStartLBFn fn) 
273   {
274     LDRemoveStartLBFn(myLDHandle,fn);
275   };
276
277   inline void StartLB() { LDStartLB(myLDHandle); }
278
279   inline void AddMigrationDoneFn(LDMigrationDoneFn fn, void *data) 
280   {
281     LDAddMigrationDoneFn(myLDHandle,fn,data);
282   };
283
284   inline void RemoveMigrationDoneFn(LDMigrationDoneFn fn) 
285   {
286     LDRemoveMigrationDoneFn(myLDHandle,fn);
287   };
288
289   inline void MigrationDone() { LDMigrationDone(myLDHandle); }
290
291 public:
292   inline void TurnManualLBOn() { LDTurnManualLBOn(myLDHandle); }
293   inline void TurnManualLBOff() { LDTurnManualLBOff(myLDHandle); }
294  
295   inline void PredictorOn(LBPredictorFunction *model) { LDTurnPredictorOn(myLDHandle,model); }
296   inline void PredictorOn(LBPredictorFunction *model,int wind) { LDTurnPredictorOnWin(myLDHandle,model,wind); }
297   inline void PredictorOff() { LDTurnPredictorOff(myLDHandle); }
298   inline void ChangePredictor(LBPredictorFunction *model) { LDTurnPredictorOn(myLDHandle,model); }
299
300   inline void CollectStatsOn(void) { LDCollectStatsOn(myLDHandle); };
301   inline void CollectStatsOff(void) { LDCollectStatsOff(myLDHandle); };
302   inline int  CollectingStats(void) { return LDCollectingStats(myLDHandle); };
303   inline int  CollectingCommStats(void) { return LDCollectingStats(myLDHandle) && _lb_args.traceComm(); };
304   inline void QueryEstLoad(void) { LDQueryEstLoad(myLDHandle); };
305
306   inline int GetObjDataSz(void) { return LDGetObjDataSz(myLDHandle); };
307   inline void GetObjData(LDObjData *data) { LDGetObjData(myLDHandle,data); };
308   inline int GetCommDataSz(void) { return LDGetCommDataSz(myLDHandle); };
309   inline void GetCommData(LDCommData *data) { LDGetCommData(myLDHandle,data); };
310
311   inline void BackgroundLoad(LBRealType *walltime, LBRealType *cputime) {
312     LDBackgroundLoad(myLDHandle,walltime,cputime);
313   }
314
315   inline void IdleTime(LBRealType *walltime) {
316     LDIdleTime(myLDHandle,walltime);
317   };
318
319   inline void TotalTime(LBRealType *walltime, LBRealType *cputime) {
320     LDTotalTime(myLDHandle,walltime,cputime);
321   }
322
323   inline void GetTime(LBRealType *total_walltime,LBRealType *total_cputime,
324                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime) {
325     LDGetTime(myLDHandle, total_walltime, total_cputime, idletime, bg_walltime, bg_cputime);
326   }
327
328   inline void ClearLoads(void) { LDClearLoads(myLDHandle); };
329   inline int Migrate(LDObjHandle h, int dest) { return LDMigrate(h,dest); };
330
331   inline void Migrated(LDObjHandle h, int waitBarrier=1) {
332     LDMigrated(h, waitBarrier);
333   };
334
335   inline LDBarrierClient AddLocalBarrierClient(LDResumeFn fn, void* data) {
336     return LDAddLocalBarrierClient(myLDHandle,fn,data);
337   };
338
339   inline void RemoveLocalBarrierClient(LDBarrierClient h) {
340     LDRemoveLocalBarrierClient(myLDHandle, h);
341   };
342
343   inline LDBarrierReceiver AddLocalBarrierReceiver(LDBarrierFn fn, void *data) {
344     return LDAddLocalBarrierReceiver(myLDHandle,fn,data);
345   };
346
347   inline void RemoveLocalBarrierReceiver(LDBarrierReceiver h) {
348     LDRemoveLocalBarrierReceiver(myLDHandle,h);
349   };
350
351   inline void AtLocalBarrier(LDBarrierClient h) { LDAtLocalBarrier(myLDHandle,h); }
352   inline void LocalBarrierOn(void) { LDLocalBarrierOn(myLDHandle); };
353   inline void LocalBarrierOff(void) { LDLocalBarrierOn(myLDHandle); };
354   void ResumeClients();
355   inline int ProcessorSpeed() { return LDProcessorSpeed(); };
356   inline void SetLBPeriod(double s) { LDSetLBPeriod(myLDHandle, s);}
357   inline double GetLBPeriod() { return LDGetLBPeriod(myLDHandle);}
358
359   bool AddLoad(int iteration, double load);
360   void ReceiveMinStats(CkReductionMsg *);
361   void LoadBalanceDecision(int, int);
362   void LoadBalanceDecisionFinal(int, int);
363   void ReceiveIterationNo(int, int); // Receives the current iter no
364
365   bool generatePlan(int& period);
366   bool getLineEq(double new_load_percent, double& aslope, double& ac, double& mslope, double& mc);
367   bool getPeriodForLinear(double a, double b, double c, int& period);
368   bool getPeriodForStrategy(double new_load, double overhead_percent, int& period);
369   int getPredictedLBPeriod();
370
371   bool isStrategyRefine();
372
373 private:
374   //CProxy_LBDatabase thisProxy;
375   int mystep;
376   LDHandle myLDHandle;
377   static char *avail_vector;    // processor bit vector
378   int new_ld_balancer;          // for Node 0
379   CkVec<BaseLB *>   loadbalancers;
380   int nloadbalancers;
381   std::vector<double> max_load_vec;
382   std::vector<double> total_load_vec;
383   std::vector<double> total_contrib_vec;
384   int max_iteration;
385
386 public:
387   BaseLB** getLoadBalancers() {return loadbalancers.getVec();}
388   int getNLoadBalancers() {return nloadbalancers;}
389
390 public:
391   static int manualOn;
392
393 public:
394   char *availVector() { return avail_vector; }
395   void get_avail_vector(char * bitmap);
396   void set_avail_vector(char * bitmap, int new_ld=-1);
397   int & new_lbbalancer() { return new_ld_balancer; }
398
399   struct LastLBInfo {
400     LBRealType *expectedLoad;
401     LastLBInfo();
402   };
403   LastLBInfo lastLBInfo;
404   inline LBRealType myExpectedLoad() { return lastLBInfo.expectedLoad[CkMyPe()]; }
405   inline LBRealType* expectedLoad() { return lastLBInfo.expectedLoad; }
406   inline int useMem() { return LDMemusage(myLDHandle); }
407
408   int getLoadbalancerTicket();
409   void addLoadbalancer(BaseLB *lb, int seq);
410   void nextLoadbalancer(int seq);
411   const char *loadbalancer(int seq);
412
413   inline int step() { return mystep; }
414   inline void incStep() { mystep++; }
415 };
416
417 void TurnManualLBOn();
418 void TurnManualLBOff();
419
420 void LBTurnPredictorOn(LBPredictorFunction *model);
421 void LBTurnPredictorOn(LBPredictorFunction *model, int wind);
422 void LBTurnPredictorOff();
423 void LBChangePredictor(LBPredictorFunction *model);
424
425 void LBSetPeriod(double second);
426
427 extern "C" void LBTurnInstrumentOn();
428 extern "C" void LBTurnInstrumentOff();
429 void LBClearLoads();
430
431 inline LBDatabase* LBDatabaseObj() { return LBDatabase::Object(); }
432
433 inline void get_avail_vector(char * bitmap) {
434   LBDatabaseObj()->get_avail_vector(bitmap);
435 }
436
437 inline void set_avail_vector(char * bitmap) {
438   LBDatabaseObj()->set_avail_vector(bitmap);
439 }
440
441 //  a helper class to suspend/resume load instrumentation when calling into
442 //  runtime apis
443
444 class SystemLoad
445 {
446   const LDObjHandle *objHandle;
447   LBDatabase *lbdb;
448 public:
449   SystemLoad() {
450     lbdb = LBDatabaseObj();
451     objHandle = lbdb->RunningObject();
452     if (objHandle != NULL) {
453       lbdb->ObjectStop(*objHandle);
454     }
455   }
456   ~SystemLoad() {
457     if (objHandle) lbdb->ObjectStart(*objHandle);
458   }
459 };
460
461 #define CK_RUNTIME_API          SystemLoad load_entry;
462
463 #endif /* LDATABASE_H */
464
465 /*@}*/