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