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