fixed getObjTime to actually get obj walltime.
[charm.git] / src / ck-ldb / lbdb.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9  * \addtogroup CkLdb
10 */
11 /*@{*/
12
13 #ifndef LBDBH_H
14 #define LBDBH_H
15
16 #include "converse.h"
17 #include "charm.h"
18 #include "middle.h"
19
20 class LBDatabase;//Forward declaration
21
22 //typedef float floatType;
23 typedef double floatType;
24
25 //#define COMPRESS_LDB                       1
26
27 extern int _lb_version;
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 typedef void* cvoid; /* To eliminate warnings, because a C void* is not
34                         the same as a C++ void* */
35
36   /*  User-defined object ID is 4 ints long (as defined in converse.h) */
37   /*  as OBJ_ID_SZ */
38
39 #if CMK_LBDB_ON
40 typedef struct {
41   void *handle;            // pointer to LBDB
42 } LDHandle;
43 #else
44 typedef int LDHandle;
45 #endif
46
47 typedef struct _LDOMid {
48   CkGroupID id;
49   CmiBool operator==(const struct _LDOMid& omId) const {
50     return id == omId.id?CmiTrue:CmiFalse;
51   }
52   CmiBool operator<(const struct _LDOMid& omId) const {
53     return id < omId.id?CmiTrue:CmiFalse;
54   }
55   CmiBool operator!=(const struct _LDOMid& omId) const {
56     return id == omId.id?CmiFalse:CmiTrue;
57   }
58   inline void pup(PUP::er &p);
59 } LDOMid;
60
61 typedef struct {
62   LDHandle ldb;
63 //  void *user_ptr;
64   LDOMid id;
65   int handle;           // index to LBOM
66   inline void pup(PUP::er &p);
67 } LDOMHandle;
68
69 typedef struct _LDObjid {
70   int id[OBJ_ID_SZ];
71   CmiBool operator==(const struct _LDObjid& objid) const {
72     for (int i=0; i<OBJ_ID_SZ; i++) if (id[i] != objid.id[i]) return CmiFalse;
73     return CmiTrue;
74   }
75   CmiBool operator<(const struct _LDObjid& objid) const {
76     for (int i=0; i<OBJ_ID_SZ; i++) {
77       if (id[i] < objid.id[i]) return CmiTrue;
78       else if (id[i] > objid.id[i]) return CmiFalse;
79     }
80     return CmiFalse;
81   }
82   inline void pup(PUP::er &p);
83 } LDObjid;
84
85 /* LDObjKey uniquely identify one object */
86 typedef struct _LDObjKey {
87   LDOMid omId;
88   LDObjid objId;
89 public:
90   CmiBool operator==(const _LDObjKey& obj) const {
91     return (CmiBool)(omId == obj.omId && objId == obj.objId);
92   }
93   CmiBool operator<(const _LDObjKey& obj) const {
94     if (omId < obj.omId) return CmiTrue;
95     else if (omId == obj.omId) return objId < obj.objId;
96     else return CmiFalse;
97   }
98   inline LDOMid &omID() { return omId; }
99   inline LDObjid &objID() { return objId; }
100   inline const LDOMid &omID() const { return omId; }
101   inline const LDObjid &objID() const { return objId; }
102   inline void pup(PUP::er &p);
103 } LDObjKey;
104
105 typedef int LDObjIndex;
106 typedef int LDOMIndex;
107
108 typedef struct {
109   LDOMHandle omhandle;
110   LDObjid id;
111   LDObjIndex  handle;
112   inline const LDOMid &omID() const { return omhandle.id; }
113   inline const LDObjid &objID() const { return id; }
114   inline void pup(PUP::er &p);
115 } LDObjHandle;
116
117 typedef struct {
118   LDObjHandle handle;
119   floatType cpuTime;
120   floatType wallTime;
121 #if ! COMPRESS_LDB
122   floatType minWall, maxWall;
123 #endif
124   CmiBool migratable;
125   CmiBool asyncArrival;
126   inline const LDOMHandle &omHandle() const { return handle.omhandle; }
127   inline const LDOMid &omID() const { return handle.omhandle.id; }
128   inline const LDObjid &objID() const { return handle.id; }
129   inline const LDObjid &id() const { return handle.id; }
130   inline void pup(PUP::er &p);
131 } LDObjData;
132
133 /* used by load balancer */
134 typedef struct {
135   int index;
136   LDObjData data;
137   int from_proc;
138   int to_proc;
139   inline void pup(PUP::er &p);
140 } LDObjStats;
141
142 #define LD_PROC_MSG      1
143 #define LD_OBJ_MSG       2
144 #define LD_OBJLIST_MSG   3
145
146 typedef struct _LDCommDesc {
147   char type;
148   union {
149     int destProc;               /* 1:   processor level message */
150     struct{
151       LDObjKey  destObj;                /* 2:   object based message    */
152       int destObjProc;
153     } destObj;
154     struct {
155       LDObjKey  *objs;
156       int len;
157     } destObjs;                 /* 3:   one to many message     */
158   } dest;
159   char &get_type() { return type; }
160   char get_type() const { return type; }
161   int proc() const { return type==LD_PROC_MSG?dest.destProc:-1; }
162   void setProc(int pe) { CmiAssert(type==LD_PROC_MSG); dest.destProc = pe; }
163   int lastKnown() const { 
164     if (type==LD_OBJ_MSG) return dest.destObj.destObjProc;
165     if (type==LD_PROC_MSG) return dest.destProc;
166     return -1;
167   }
168   LDObjKey &get_destObj() 
169         { CmiAssert(type==LD_OBJ_MSG); return dest.destObj.destObj; }
170   LDObjKey const &get_destObj() const 
171         { CmiAssert(type==LD_OBJ_MSG); return dest.destObj.destObj; }
172   LDObjKey * get_destObjs(int &len) 
173         { CmiAssert(type==LD_OBJLIST_MSG); len=dest.destObjs.len; return dest.destObjs.objs; }
174   void init_objmsg(LDOMid &omid, LDObjid &objid, int destObjProc) { 
175         type=LD_OBJ_MSG; 
176         dest.destObj.destObj.omID()=omid;
177         dest.destObj.destObj.objID() =objid;
178         dest.destObj.destObjProc = destObjProc;
179   }
180   void init_mcastmsg(LDOMid &omid, LDObjid *objid, int len) { 
181         type=LD_OBJLIST_MSG; 
182         dest.destObjs.len = len;
183         dest.destObjs.objs = new LDObjKey[len];
184         for (int i=0; i<len; i++) {
185           dest.destObjs.objs[i].omID()=omid;
186           dest.destObjs.objs[i].objID() =objid[i];
187         }
188   }
189   inline CmiBool operator==(const _LDCommDesc &obj) const;
190   inline _LDCommDesc &operator=(const _LDCommDesc &c);
191   inline void pup(PUP::er &p);
192 } LDCommDesc;
193
194 typedef struct {
195   int src_proc;                 // sender can either be a proc or an obj
196   LDObjKey  sender;             // 
197   LDCommDesc   receiver;
198   int  sendHash, recvHash;
199   int messages;
200   int bytes;
201   inline int from_proc() const { return (src_proc != -1); }
202   inline int recv_type() const { return receiver.get_type(); }
203   inline void pup(PUP::er &p);
204   inline void clearHash() { sendHash = recvHash = -1; }
205 } LDCommData;
206
207 /*
208  * Requests to load balancer
209  *   FIXME: these routines don't seem to exist anywhere-- are they obsolete?
210  *   Are the official versions now in LBDatabase.h?
211  */
212 void LBBalance(void *param);
213 void LBCollectStatsOn(void);
214 void LBCollectStatsOff(void);
215
216 /*
217  * Callbacks from database to object managers
218  */
219 typedef void (*LDMigrateFn)(LDObjHandle handle, int dest);
220 typedef void (*LDStatsFn)(LDOMHandle h, int state);
221 typedef void (*LDQueryEstLoadFn)(LDOMHandle h);
222
223 typedef struct {
224   LDMigrateFn migrate;
225   LDStatsFn setStats;
226   LDQueryEstLoadFn queryEstLoad;
227 } LDCallbacks;
228
229 /*
230  * Calls from object managers to load database
231  */
232 #if CMK_LBDB_ON
233 LDHandle LDCreate(void);
234 #else
235 #define LDCreate() 0
236 #endif
237
238 LDOMHandle LDRegisterOM(LDHandle _lbdb, LDOMid userID, 
239                         void *userptr, LDCallbacks cb);
240 void * LDOMUserData(LDOMHandle &_h);
241 void LDRegisteringObjects(LDOMHandle _h);
242 void LDDoneRegisteringObjects(LDOMHandle _h);
243
244 LDObjHandle LDRegisterObj(LDOMHandle h, LDObjid id, void *userptr,
245                           int migratable);
246 void LDUnregisterObj(LDObjHandle h);
247 const LDObjHandle &LDGetObjHandle(LDHandle h, int idx);
248
249 void * LDObjUserData(LDObjHandle &_h);
250 void LDObjTime(LDObjHandle &h, double walltime, double cputime);
251 int  CLDRunningObject(LDHandle _h, LDObjHandle* _o );
252 void LDObjectStart(const LDObjHandle &_h);
253 void LDObjectStop(const LDObjHandle &_h);
254 void LDSend(const LDOMHandle &destOM, const LDObjid &destid, unsigned int bytes, int destObjProc, int force);
255 void LDMulticastSend(const LDOMHandle &destOM, LDObjid *destids, int ndests, unsigned int bytes, int nMsgs);
256
257 void LDMessage(LDObjHandle from, 
258                LDOMid toOM, LDObjid *toID, int bytes);
259
260 void LDEstObjLoad(LDObjHandle h, double load);
261 void LDNonMigratable(const LDObjHandle &h);
262 void LDMigratable(const LDObjHandle &h);
263 void LDAsyncMigrate(const LDObjHandle &h, CmiBool);
264 void LDDumpDatabase(LDHandle _lbdb);
265
266 /*
267  * Calls from load balancer to load database
268  */  
269 typedef void (*LDMigratedFn)(void* data, LDObjHandle handle, int waitBarrier);
270 void LDNotifyMigrated(LDHandle _lbdb, LDMigratedFn fn, void* data);
271
272 typedef void (*LDStartLBFn)(void *user_ptr);
273 void LDAddStartLBFn(LDHandle _lbdb, LDStartLBFn fn, void* data);
274 void LDRemoveStartLBFn(LDHandle _lbdb, LDStartLBFn fn);
275 void LDStartLB(LDHandle _db);
276 void LDTurnManualLBOn(LDHandle _lbdb);
277 void LDTurnManualLBOff(LDHandle _lbdb);
278
279 typedef void (*LDPredictFn)(void* user_ptr);
280 typedef void (*LDPredictModelFn)(void* user_ptr, void* model);
281 typedef void (*LDPredictWindowFn)(void* user_ptr, void* model, int wind);
282 void LDTurnPredictorOn(LDHandle _lbdb, void *model);
283 void LDTurnPredictorOnWin(LDHandle _lbdb, void *model, int wind);
284 void LDTurnPredictorOff(LDHandle _lbdb);
285 void LDChangePredictor(LDHandle _lbdb, void *model);
286 void LDCollectStatsOn(LDHandle _lbdb);
287 void LDCollectStatsOff(LDHandle _lbdb);
288 int  CLDCollectingStats(LDHandle _lbdb);
289 void LDQueryEstLoad(LDHandle bdb);
290 void LDQueryKnownObjLoad(LDObjHandle &h, double *wallT, double *cpuT);
291
292 int LDGetObjDataSz(LDHandle _lbdb);
293 void LDGetObjData(LDHandle _lbdb, LDObjData *data);
294
295 int LDGetCommDataSz(LDHandle _lbdb);
296 void LDGetCommData(LDHandle _lbdb, LDCommData *data);
297
298 void LDBackgroundLoad(LDHandle _lbdb, double *walltime, double *cputime);
299 void LDIdleTime(LDHandle _lbdb, double *walltime);
300 void LDTotalTime(LDHandle _lbdb, double *walltime, double *cputime);
301 void LDGetTime(LDHandle _db, double *total_walltime,double *total_cputime,
302                    double *idletime, double *bg_walltime, double *bg_cputime);
303
304 void LDClearLoads(LDHandle _lbdb);
305 int  LDMigrate(LDObjHandle h, int dest);
306 void LDMigrated(LDObjHandle h, int waitBarrier);
307
308 /*
309  * Local Barrier calls
310  */
311 typedef void (*LDBarrierFn)(void *user_ptr);
312 typedef void (*LDResumeFn)(void *user_ptr);
313
314 typedef struct {
315   int serial;
316 } LDBarrierClient;
317
318 typedef struct {
319   int serial;
320 } LDBarrierReceiver;
321
322 LDBarrierClient LDAddLocalBarrierClient(LDHandle _lbdb,LDResumeFn fn,
323                                         void* data);
324 void LDRemoveLocalBarrierClient(LDHandle _lbdb, LDBarrierClient h);
325 LDBarrierReceiver LDAddLocalBarrierReceiver(LDHandle _lbdb,LDBarrierFn fn,
326                                             void* data);
327 void LDRemoveLocalBarrierReceiver(LDHandle _lbdb,LDBarrierReceiver h);
328 void LDAtLocalBarrier(LDHandle _lbdb, LDBarrierClient h);
329 void LDLocalBarrierOn(LDHandle _db);
330 void LDLocalBarrierOff(LDHandle _db);
331 void LDResumeClients(LDHandle _lbdb);
332 int LDProcessorSpeed();
333 CmiBool LDOMidEqual(const LDOMid &i1, const LDOMid &i2);
334 CmiBool LDObjIDEqual(const LDObjid &i1, const LDObjid &i2);
335
336 /*
337  *  LBDB Configuration calls
338  */
339 void LDSetLBPeriod(LDHandle _db, double s);
340 double LDGetLBPeriod(LDHandle _db);
341
342 int LDMemusage(LDHandle _db);
343
344 #ifdef __cplusplus
345 }
346 #endif /* _cplusplus */
347
348 #if CMK_LBDB_ON
349 PUPbytes(LDHandle)
350 #endif
351
352 inline void LDOMid::pup(PUP::er &p) {
353   id.pup(p);
354 }
355 PUPmarshall(LDOMid)
356
357 inline void LDObjid::pup(PUP::er &p) {
358   for (int i=0; i<OBJ_ID_SZ; i++) p|id[i];
359 }
360 PUPmarshall(LDObjid)
361
362 inline void LDObjKey::pup(PUP::er &p) {
363   p|omId;
364   p|objId;
365 }
366 PUPmarshall(LDObjKey)
367
368 inline void LDObjStats::pup(PUP::er &p) {
369   p|index;
370   p|data;
371   p|from_proc;
372   p|to_proc;
373 }
374 PUPmarshall(LDObjStats)
375 inline void LDOMHandle::pup(PUP::er &p) {
376   // skip ldb since it is a pointer
377   int ptrSize = sizeof(void *);
378   p|ptrSize;
379   // if pointer size is not expected, must be in simulation mode
380   // ignore this field
381   if (p.isUnpacking() && ptrSize != sizeof(void *)) {  
382     char dummy;
383     for (int i=0; i<ptrSize; i++) p|dummy;
384   }
385   else
386     p|ldb;
387   p|id;
388   p|handle;
389 }
390 PUPmarshall(LDOMHandle)
391
392 inline void LDObjHandle::pup(PUP::er &p) {
393   p|omhandle;
394   p|id;
395   p|handle;
396 }
397 PUPmarshall(LDObjHandle)
398
399 inline void LDObjData::pup(PUP::er &p) {
400   p|handle;
401   p|cpuTime;
402   p|wallTime;
403 #if ! COMPRESS_LDB
404   p|minWall;
405   p|maxWall;
406 #endif
407   p|migratable;
408   if (_lb_version > -1) p|asyncArrival;
409 }
410 PUPmarshall(LDObjData)
411
412 inline CmiBool LDCommDesc::operator==(const LDCommDesc &obj) const {
413     if (type != obj.type) return CmiFalse;
414     switch (type) {
415     case LD_PROC_MSG: return (CmiBool)(dest.destProc == obj.dest.destProc);
416     case LD_OBJ_MSG:  return (CmiBool)(dest.destObj.destObj == obj.dest.destObj.destObj);
417     case LD_OBJLIST_MSG: { if (dest.destObjs.len != obj.dest.destObjs.len) 
418                                return CmiFalse;
419                            for (int i=0; i<dest.destObjs.len; i++)
420                              if (!(dest.destObjs.objs[i] == obj.dest.destObjs.objs[i])) return CmiFalse;
421                            return CmiTrue; }
422     }
423     return CmiFalse;
424 }
425 inline LDCommDesc & LDCommDesc::operator=(const LDCommDesc &c) {
426     type = c.type;
427     switch (type) {
428     case LD_PROC_MSG: dest.destProc = c.dest.destProc; break;
429     case LD_OBJ_MSG:  dest.destObj.destObj = c.dest.destObj.destObj; break;
430     case LD_OBJLIST_MSG: { dest.destObjs.len = c.dest.destObjs.len;
431                            dest.destObjs.objs = new LDObjKey[dest.destObjs.len];
432                            for (int i=0; i<dest.destObjs.len; i++)
433                              dest.destObjs.objs[i] = c.dest.destObjs.objs[i]; 
434                            break; }
435     }
436     return *this;
437 }
438 inline void LDCommDesc::pup(PUP::er &p) {
439   p|type;
440   switch (type) {
441   case LD_PROC_MSG:  p|dest.destProc; break;
442   case LD_OBJ_MSG:   p|dest.destObj.destObj; 
443                      if (_lb_version == -1 && p.isUnpacking()) 
444                        dest.destObj.destObjProc = -1;
445                      else
446                        p|dest.destObj.destObjProc; 
447                      break;
448   case LD_OBJLIST_MSG:  {  p|dest.destObjs.len; 
449                            if (p.isUnpacking()) 
450                                dest.destObjs.objs = new LDObjKey[dest.destObjs.len];
451                            for (int i=0; i<dest.destObjs.len; i++) p|dest.destObjs.objs[i];
452                            break; }
453   }   // end of switch
454 }
455 PUPmarshall(LDCommDesc)
456
457 inline void LDCommData::pup(PUP::er &p) {
458     p|src_proc;
459     p|sender;
460     p|receiver;
461     p|messages;
462     p|bytes;
463     if (p.isUnpacking()) {
464       sendHash = recvHash = -1;
465     }
466 }
467 PUPmarshall(LDCommData)
468
469 #endif /* LBDBH_H */
470
471 /*@}*/