support for lb
[charm.git] / src / ck-ldb / LBDBManager.h
1 /**
2  * \addtogroup CkLdb
3 */
4 /*@{*/
5
6 #ifndef LBDB_H
7 #define LBDB_H
8
9 #include "converse.h"
10 #include "lbdb.h"
11 #include "cklists.h"
12
13 #include "LBObj.h"
14 #include "LBOM.h"
15 #include "LBComm.h"
16 #include "LBMachineUtil.h"
17
18 class LocalBarrier {
19 friend class LBDB;
20 public:
21   LocalBarrier() { cur_refcount = 1; client_count = 0; max_client = 0;
22                    max_receiver= 0; at_count = 0; on = CmiFalse; 
23         #if CMK_BIGSIM_CHARM
24         first_free_client_slot = 0;
25         #endif
26     };
27   ~LocalBarrier() { };
28
29   LDBarrierClient AddClient(LDResumeFn fn, void* data);
30   void RemoveClient(LDBarrierClient h);
31   LDBarrierReceiver AddReceiver(LDBarrierFn fn, void* data);
32   void RemoveReceiver(LDBarrierReceiver h);
33   void TurnOnReceiver(LDBarrierReceiver h);
34   void TurnOffReceiver(LDBarrierReceiver h);
35   void AtBarrier(LDBarrierClient h);
36   void TurnOn() { on = CmiTrue; CheckBarrier(); };
37   void TurnOff() { on = CmiFalse; };
38
39 private:
40   void CallReceivers(void);
41   void CheckBarrier();
42   void ResumeClients(void);
43
44   struct client {
45     void* data;
46     LDResumeFn fn;
47     int refcount;
48   };
49   struct receiver {
50     void* data;
51     LDBarrierFn fn;
52     int on;
53   };
54
55   CkVec<client*> clients;
56   CkVec<receiver*> receivers;
57
58   int cur_refcount;
59   int max_client;
60   int client_count;
61   int max_receiver;
62   int at_count;
63   CmiBool on;
64
65   #if CMK_BIGSIM_CHARM
66   int first_free_client_slot;
67   #endif
68 };
69
70 class LBDB {
71 public:
72   LBDB();
73   ~LBDB() { }
74
75   void SetPeriod(double secs) {batsync.setPeriod(secs);}
76   double GetPeriod() {return batsync.getPeriod();}
77
78   void insert(LBOM *om);
79
80   LDOMHandle AddOM(LDOMid _userID, void* _userData, LDCallbacks _callbacks);
81   LDObjHandle AddObj(LDOMHandle _h, LDObjid _id, void *_userData,
82                      CmiBool _migratable);
83   void UnregisterObj(LDObjHandle _h);
84
85   void RegisteringObjects(LDOMHandle _h);
86   void DoneRegisteringObjects(LDOMHandle _h);
87
88   inline void LocalBarrierOn() 
89        { localBarrier.TurnOn();}
90   inline void LocalBarrierOff() 
91        { localBarrier.TurnOff();}
92
93   inline LBOM *LbOM(LDOMHandle h) 
94        { return oms[h.handle]; };
95   inline LBObj *LbObj(const LDObjHandle &h) const 
96        { return objs[h.handle]; };
97   inline LBObj *LbObjIdx(int h) const 
98        { return objs[h]; };
99   void DumpDatabase(void);
100
101   inline void TurnStatsOn(void) 
102        {statsAreOn = CmiTrue; machineUtil.StatsOn();}
103   inline void TurnStatsOff(void) 
104        {statsAreOn = CmiFalse;machineUtil.StatsOff();}
105   inline CmiBool StatsOn(void) const 
106        { return statsAreOn; };
107
108   void SetupPredictor(LDPredictModelFn on, LDPredictWindowFn onWin, LDPredictFn off, LDPredictModelFn change, void* data);
109   inline void TurnPredictorOn(void *model) {
110     if (predictCBFn!=NULL) predictCBFn->on(predictCBFn->data, model);
111     else CmiPrintf("Predictor not supported in this load balancer\n");
112   }
113   inline void TurnPredictorOn(void *model, int wind) {
114     if (predictCBFn!=NULL) predictCBFn->onWin(predictCBFn->data, model, wind);
115     else CmiPrintf("Predictor not supported in this load balancer\n");
116   }
117   inline void TurnPredictorOff(void) {
118     if (predictCBFn!=NULL) predictCBFn->off(predictCBFn->data);
119     else CmiPrintf("Predictor not supported in this load balancer\n");
120   }
121   /* the parameter model is really of class LBPredictorFunction in file LBDatabase.h */
122   inline void ChangePredictor(void *model) {
123     if (predictCBFn!=NULL) predictCBFn->change(predictCBFn->data, model);
124     else CmiPrintf("Predictor not supported in this load balancer");
125   }
126
127   void Send(const LDOMHandle &destOM, const LDObjid &destid, unsigned int bytes, int destObjProc);
128   void MulticastSend(const LDOMHandle &destOM, LDObjid *destids, int ndests, unsigned int bytes, int nMsgs);
129   int ObjDataCount();
130   void GetObjData(LDObjData *data);
131   inline int CommDataCount() { 
132     if (commTable)
133       return commTable->CommCount();
134     else return 0;
135   }
136   inline void GetCommData(LDCommData *data) 
137        { if (commTable) commTable->GetCommData(data); };
138
139   void MetaLBResumeWaitingChares(int lb_ideal_period);
140   void MetaLBCallLBOnChares();
141   int  Migrate(LDObjHandle h, int dest);
142   void Migrated(LDObjHandle h, int waitBarrier=1);
143   int  NotifyMigrated(LDMigratedFn fn, void* data);
144   void TurnOnNotifyMigrated(int handle)
145        { migrateCBList[handle]->on = 1; }
146   void TurnOffNotifyMigrated(int handle)
147        { migrateCBList[handle]->on = 0; }
148   void RemoveNotifyMigrated(int handle);
149
150   inline void TurnManualLBOn() 
151        { useBarrier = CmiFalse; }
152   inline void TurnManualLBOff() 
153        { useBarrier = CmiTrue; }
154
155   int AddStartLBFn(LDStartLBFn fn, void* data);
156   void TurnOnStartLBFn(int handle)
157        { startLBFnList[handle]->on = 1; }
158   void TurnOffStartLBFn(int handle)
159        { startLBFnList[handle]->on = 0; }
160   void RemoveStartLBFn(LDStartLBFn fn);
161   void StartLB();
162
163   int AddMigrationDoneFn(LDMigrationDoneFn fn, void* data);
164   void RemoveMigrationDoneFn(LDMigrationDoneFn fn);
165   void MigrationDone();
166
167   inline void IdleTime(LBRealType* walltime) 
168        { machineUtil.IdleTime(walltime); };
169   inline void TotalTime(LBRealType* walltime, LBRealType* cputime) 
170        { machineUtil.TotalTime(walltime,cputime); };
171   void BackgroundLoad(LBRealType* walltime, LBRealType* cputime);
172   void GetTime(LBRealType *total_walltime,LBRealType *total_cputime,
173                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime);
174   void ClearLoads(void);
175
176   /**
177     runningObj records the obj handler index so that load balancer
178     knows if an event(e.g. Send) is in an entry function or not.
179     An index is enough here because LDObjHandle can be retrieved from 
180     objs array. Copying LDObjHandle is expensive.
181   */
182   inline void SetRunningObj(const LDObjHandle &_h) 
183        { runningObj = _h.handle; obj_running = CmiTrue; };
184   inline const LDObjHandle &RunningObj() const 
185        { return objs[runningObj]->GetLDObjHandle(); };
186   inline void NoRunningObj() 
187        { obj_running = CmiFalse; };
188   inline CmiBool ObjIsRunning() const 
189        { return obj_running; };
190   
191   inline LDBarrierClient AddLocalBarrierClient(LDResumeFn fn, void* data) 
192        { return localBarrier.AddClient(fn,data); };
193   inline void RemoveLocalBarrierClient(LDBarrierClient h) 
194        { localBarrier.RemoveClient(h); };
195   inline LDBarrierReceiver AddLocalBarrierReceiver(LDBarrierFn fn, void* data) 
196        { return localBarrier.AddReceiver(fn,data); };
197   inline void RemoveLocalBarrierReceiver(LDBarrierReceiver h) 
198        { localBarrier.RemoveReceiver(h); };
199   inline void TurnOnBarrierReceiver(LDBarrierReceiver h) 
200        { localBarrier.TurnOnReceiver(h); };
201   inline void TurnOffBarrierReceiver(LDBarrierReceiver h) 
202        { localBarrier.TurnOffReceiver(h); };
203   inline void AtLocalBarrier(LDBarrierClient h) 
204        { 
205                         CkPrintf("[%d][%d] LBDBManager local barrier\n",CmiMyPartition(),CkMyPe());
206                    if (useBarrier) 
207                    localBarrier.AtBarrier(h); 
208            };
209   inline void ResumeClients() 
210        { localBarrier.ResumeClients(); };
211   inline void MeasuredObjTime(double wtime, double ctime) {
212     if (statsAreOn) {
213       obj_walltime += wtime;
214 #if CMK_LB_CPUTIMER
215       obj_cputime += ctime;
216 #endif
217     }
218   };
219
220   //This class controls the builtin-atsync frequency
221   class batsyncer {
222   private:
223     LBDB *db; //Enclosing LBDB object
224     double period;//Time (seconds) between builtin-atsyncs  
225     double nextT;
226     LDBarrierClient BH;//Handle for the builtin-atsync barrier 
227     static void gotoSync(void *bs);
228     static void resumeFromSync(void *bs);
229   public:
230     void init(LBDB *_db,double initPeriod);
231     void setPeriod(double p) {period=p;}
232     double getPeriod() {return period;}
233   };
234
235 private:
236   struct MigrateCB {
237     LDMigratedFn fn;
238     void* data;
239     int on;
240   };
241
242   struct StartLBCB {
243     LDStartLBFn fn;
244     void* data;
245     int on;
246   };
247
248   struct MigrationDoneCB {
249     LDMigrationDoneFn fn;
250     void* data;
251   };
252
253   struct PredictCB {
254     LDPredictModelFn on;
255     LDPredictWindowFn onWin;
256     LDPredictFn off;
257     LDPredictModelFn change;
258     void* data;
259   };
260
261   typedef CkVec<LBOM*> OMList;
262   typedef CkVec<LBObj*> ObjList;
263   typedef CkVec<MigrateCB*> MigrateCBList;
264   typedef CkVec<StartLBCB*> StartLBCBList;
265   typedef CkVec<MigrationDoneCB*> MigrationDoneCBList;
266
267   LBCommTable* commTable;
268   OMList oms;
269   int omCount;
270   int oms_registering;
271
272   ObjList objs;
273   int objCount;
274
275   CmiBool statsAreOn;
276   MigrateCBList migrateCBList;
277
278   MigrationDoneCBList migrationDoneCBList;
279
280   PredictCB* predictCBFn;
281
282   CmiBool obj_running;
283   int runningObj;               // index of the runningObj in ObjList
284
285   batsyncer batsync;
286
287   LocalBarrier localBarrier;    // local barrier to trigger LB automatically
288   CmiBool useBarrier;           // use barrier or not
289
290   LBMachineUtil machineUtil;
291   double obj_walltime;
292 #if CMK_LB_CPUTIMER
293   double obj_cputime;
294 #endif
295
296   StartLBCBList  startLBFnList;
297   int            startLBFn_count;
298 public:
299   int useMem();
300 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
301     int validObjHandle(LDObjHandle h ){
302             if(objCount == 0)
303                 return 0;
304             if(h.handle > objCount)
305                 return 0;
306             if(objs[h.handle] == NULL)
307                 return 0;
308
309             return 1;
310     }
311 #endif
312
313
314   int getObjCount() {return objCount;}
315   const ObjList& getObjs() {return objs;}
316
317
318
319 };
320
321 #endif
322
323 /*@}*/