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