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