Merge branch 'charm' of charmgit:charm into charm
[charm.git] / src / ck-ldb / lbdb.C
1 /**
2  * \addtogroup CkLdb
3 */
4 /*@{*/
5
6 #include <converse.h>
7
8 #include <math.h>
9
10 #include "lbdb.h"
11 #include "LBObj.h"
12 #include "LBOM.h"
13 #include "LBDatabase.h"
14 #include "LBDBManager.h"
15   
16 #if CMK_LBDB_ON
17
18 extern "C" LDHandle LDCreate(void)
19 {
20   LDHandle h;
21   h.handle = (void*)(new LBDB);
22   return h;
23 }
24
25 extern "C" LDOMHandle LDRegisterOM(LDHandle _db, LDOMid _userID,
26                                    void *_userptr, LDCallbacks _callbacks)
27 {
28   LBDB *const db = (LBDB*)(_db.handle);
29   return db->AddOM(_userID, _userptr, _callbacks);
30 }
31
32 extern "C" void * LDOMUserData(LDOMHandle &_h)
33 {
34   LBDB *const db = (LBDB*)(_h.ldb.handle);
35   return db->LbOM(_h)->getUserData();
36 }
37
38 extern "C" void LDRegisteringObjects(LDOMHandle _h)
39 {
40   LBDB *const db = (LBDB*)(_h.ldb.handle);
41   db->RegisteringObjects(_h);
42 }
43
44 extern "C" void LDDoneRegisteringObjects(LDOMHandle _h)
45 {
46   LBDB *const db = (LBDB*)(_h.ldb.handle);
47   db->DoneRegisteringObjects(_h);
48 }
49
50 extern "C" LDObjHandle LDRegisterObj(LDOMHandle _h, LDObjid _id, 
51                                        void *_userData, int _migratable)
52 {
53   LBDB *const db = (LBDB*)(_h.ldb.handle);
54   return db->AddObj(_h, _id, _userData, (CmiBool)(_migratable));
55 }
56
57 extern "C" void LDUnregisterObj(LDObjHandle _h)
58 {
59   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
60   db->UnregisterObj(_h);
61   return;
62 }
63
64 extern "C" const LDObjHandle &LDGetObjHandle(LDHandle h, int oh)
65 {
66   LBDB *const db = (LBDB*)(h.handle);
67   LBObj *const obj = db->LbObjIdx(oh);
68   return obj->GetLDObjHandle();
69 }
70
71 extern "C" void LDObjTime(LDObjHandle &_h,
72                             LBRealType walltime, LBRealType cputime)
73 {
74   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
75   LBObj *const obj = db->LbObj(_h);
76   obj->IncrementTime(walltime,cputime);
77 }
78   
79 extern "C" void LDGetObjLoad(LDObjHandle &_h, LBRealType *wallT, LBRealType *cpuT)
80 {
81   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
82   LBObj *const obj = db->LbObj(_h);
83   obj->getTime(wallT, cpuT);
84 }
85
86 extern "C" void LDQueryKnownObjLoad(LDObjHandle &_h, LBRealType *wallT, LBRealType *cpuT)
87 {
88   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
89   LBObj *const obj = db->LbObj(_h);
90   obj->lastKnownLoad(wallT, cpuT);
91 }
92
93 extern "C" void * LDObjUserData(LDObjHandle &_h)
94 {
95   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
96   LBObj *const obj = db->LbObj(_h);
97   return obj->getUserData();
98 }
99
100 extern "C" void LDDumpDatabase(LDHandle _db)
101 {
102   LBDB *const db = (LBDB*)(_db.handle);
103   db->DumpDatabase();
104 }
105
106 extern "C" void LDNotifyMigrated(LDHandle _db, LDMigratedFn fn, void* data)
107 {
108   LBDB *const db = (LBDB*)(_db.handle);
109   db->NotifyMigrated(fn,data);
110 }
111
112 extern "C" void LDAddStartLBFn(LDHandle _db, LDStartLBFn fn, void* data)
113 {
114   LBDB *const db = (LBDB*)(_db.handle);
115   db->AddStartLBFn(fn,data);
116 }
117
118 extern "C" void LDRemoveStartLBFn(LDHandle _db, LDStartLBFn fn)
119 {
120   LBDB *const db = (LBDB*)(_db.handle);
121   db->RemoveStartLBFn(fn);
122 }
123
124 extern "C" void LDStartLB(LDHandle _db)
125 {
126   LBDB *const db = (LBDB*)(_db.handle);
127   db->StartLB();
128 }
129
130 extern "C" void LDTurnManualLBOn(LDHandle _db)
131 {
132   LBDB *const db = (LBDB*)(_db.handle);
133   db->TurnManualLBOn();
134 }
135
136 extern "C" void LDTurnManualLBOff(LDHandle _db)
137 {
138   LBDB *const db = (LBDB*)(_db.handle);
139   db->TurnManualLBOff();
140 }
141
142 extern "C" int LDAddMigrationDoneFn(LDHandle _db, LDMigrationDoneFn fn,  void* data) 
143 {
144   LBDB *const db = (LBDB*)(_db.handle);
145   return db->AddMigrationDoneFn(fn,data);
146 }
147
148 extern "C" void  LDRemoveMigrationDoneFn(LDHandle _db, LDMigrationDoneFn fn)
149 {
150   LBDB *const db = (LBDB*)(_db.handle);
151   db->RemoveMigrationDoneFn(fn);
152 }
153
154 extern "C" void LDMigrationDone(LDHandle _db)
155 {
156   LBDB *const db = (LBDB*)(_db.handle);
157   db->MigrationDone();
158 }
159
160 extern "C" void LDTurnPredictorOn(LDHandle _db, void *model)
161 {
162   LBDB *const db = (LBDB*)(_db.handle);
163   db->TurnPredictorOn(model);
164 }
165
166 extern "C" void LDTurnPredictorOnWin(LDHandle _db, void *model, int wind)
167 {
168   LBDB *const db = (LBDB*)(_db.handle);
169   db->TurnPredictorOn(model, wind);
170 }
171
172 extern "C" void LDTurnPredictorOff(LDHandle _db)
173 {
174   LBDB *const db = (LBDB*)(_db.handle);
175   db->TurnPredictorOff();
176 }
177
178 /* the parameter model is really of class LBPredictorFunction in file LBDatabase.h */
179 extern "C" void LDChangePredictor(LDHandle _db, void *model)
180 {
181   LBDB *const db = (LBDB*)(_db.handle);
182   db->ChangePredictor(model);
183 }
184
185 extern "C" void LDCollectStatsOn(LDHandle _db)
186 {
187   LBDB *const db = (LBDB*)(_db.handle);
188
189   if (!db->StatsOn()) {
190     if (db->ObjIsRunning()) {
191        // stats on in the middle of an entry, start timer
192       const LDObjHandle &oh = db->RunningObj();
193       LBObj *obj = db->LbObj(oh);
194       obj->StartTimer();
195     }
196     db->TurnStatsOn();
197   }
198 }
199
200 extern "C" void LDCollectStatsOff(LDHandle _db)
201 {
202   LBDB *const db = (LBDB*)(_db.handle);
203   db->TurnStatsOff();
204 }
205
206 extern "C" int CLDCollectingStats(LDHandle _db)
207 {
208 //  LBDB *const db = (LBDB*)(_db.handle);
209 //
210 //  return db->StatsOn();
211   return LDCollectingStats(_db);
212 }
213
214 extern "C" int CLDRunningObject(LDHandle _h, LDObjHandle* _o)
215 {
216   return LDRunningObject(_h, _o);
217 }
218
219 extern "C" void LDObjectStart(const LDObjHandle &_h)
220 {
221   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
222
223   if (db->ObjIsRunning()) LDObjectStop(db->RunningObj());
224
225   db->SetRunningObj(_h);
226
227   if (db->StatsOn()) {
228     LBObj *const obj = db->LbObj(_h);
229     obj->StartTimer();
230   }
231 }
232
233 extern "C" void LDObjectStop(const LDObjHandle &_h)
234 {
235   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
236   LBObj *const obj = db->LbObj(_h);
237
238   if (db->StatsOn()) {
239     LBRealType walltime, cputime;
240     obj->StopTimer(&walltime,&cputime);
241     obj->IncrementTime(walltime,cputime);
242   }
243   db->NoRunningObj();
244 }
245
246 extern "C" void LDSend(const LDOMHandle &destOM, const LDObjid &destid, unsigned int bytes, int destObjProc, int force)
247 {
248   LBDB *const db = (LBDB*)(destOM.ldb.handle);
249   if (force || db->StatsOn() && _lb_args.traceComm())
250     db->Send(destOM,destid,bytes, destObjProc);
251 }
252
253 extern "C" void LDMulticastSend(const LDOMHandle &destOM, LDObjid *destids, int ndests, unsigned int bytes, int nMsgs)
254 {
255   LBDB *const db = (LBDB*)(destOM.ldb.handle);
256   if (db->StatsOn() && _lb_args.traceComm())
257     db->MulticastSend(destOM,destids,ndests,bytes,nMsgs);
258 }
259
260 extern "C" void LDBackgroundLoad(LDHandle _db,
261                                  LBRealType* walltime, LBRealType* cputime)
262 {
263   LBDB *const db = (LBDB*)(_db.handle);
264   db->BackgroundLoad(walltime,cputime);
265
266   return;
267 }
268
269 extern "C" void LDIdleTime(LDHandle _db,LBRealType* walltime)
270 {
271   LBDB *const db = (LBDB*)(_db.handle);
272   db->IdleTime(walltime);
273
274   return;
275 }
276
277 extern "C" void LDTotalTime(LDHandle _db,LBRealType* walltime, LBRealType* cputime)
278 {
279   LBDB *const db = (LBDB*)(_db.handle);
280   db->TotalTime(walltime,cputime);
281
282   return;
283 }
284
285 extern "C" void LDGetTime(LDHandle _db, LBRealType *total_walltime,
286                    LBRealType *total_cputime,
287                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime)
288 {
289   LBDB *const db = (LBDB*)(_db.handle);
290   db->GetTime(total_walltime, total_cputime, idletime, bg_walltime, bg_cputime);
291 }
292
293 extern "C" void LDNonMigratable(const LDObjHandle &h)
294 {
295   LBDB *const db = (LBDB*)(h.omhandle.ldb.handle);
296   LBObj *const obj = db->LbObj(h);
297
298   obj->SetMigratable(CmiFalse);
299 }
300
301 extern "C" void LDMigratable(const LDObjHandle &h)
302 {
303   LBDB *const db = (LBDB*)(h.omhandle.ldb.handle);
304   LBObj *const obj = db->LbObj(h);
305
306   obj->SetMigratable(CmiTrue);
307 }
308
309 extern "C" void LDAsyncMigrate(const LDObjHandle &h, CmiBool async)
310 {
311   LBDB *const db = (LBDB*)(h.omhandle.ldb.handle);
312   LBObj *const obj = db->LbObj(h);
313
314   obj->UseAsyncMigrate(async);
315 }
316
317 extern "C" void LDClearLoads(LDHandle _db)
318 {
319   LBDB *const db = (LBDB*)(_db.handle);
320
321   db->ClearLoads();
322 }
323
324 extern "C" int LDGetObjDataSz(LDHandle _db)
325 {
326   LBDB *const db = (LBDB*)(_db.handle);
327
328   return db->ObjDataCount();
329 }
330
331 extern "C" void LDGetObjData(LDHandle _db, LDObjData *data)
332 {
333   LBDB *const db = (LBDB*)(_db.handle);
334
335   db->GetObjData(data);
336 }
337
338 extern "C" int LDGetCommDataSz(LDHandle _db)
339 {
340   LBDB *const db = (LBDB*)(_db.handle);
341
342   return db->CommDataCount();
343 }
344
345 extern "C" void LDGetCommData(LDHandle _db, LDCommData *data)
346 {
347   LBDB *const db = (LBDB*)(_db.handle);
348
349   db->GetCommData(data);
350   return;
351 }
352
353 extern "C" int LDMigrate(LDObjHandle _h, int dest)
354 {
355   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
356
357   return db->Migrate(_h,dest);
358 }
359
360 extern "C" void LDMigrated(LDObjHandle _h, int waitBarrier)
361 {
362   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
363
364   db->Migrated(_h, waitBarrier);
365 }
366
367 extern "C" LDBarrierClient 
368 LDAddLocalBarrierClient(LDHandle _db, LDResumeFn fn, void* data)
369 {
370   LBDB *const db = (LBDB*)(_db.handle);
371
372   return db->AddLocalBarrierClient(fn,data);
373 }
374
375 extern "C" void LDRemoveLocalBarrierClient(LDHandle _db, LDBarrierClient h)
376 {
377   LBDB *const db = (LBDB*)(_db.handle);
378
379   db->RemoveLocalBarrierClient(h);
380 }
381
382 extern "C" LDBarrierReceiver 
383 LDAddLocalBarrierReceiver(LDHandle _db,LDBarrierFn fn, void* data)
384 {
385   LBDB *const db = (LBDB*)(_db.handle);
386
387   return db->AddLocalBarrierReceiver(fn,data);
388 }
389
390 extern "C" void 
391 LDRemoveLocalBarrierReceiver(LDHandle _db,LDBarrierReceiver h)
392 {
393   LBDB *const db = (LBDB*)(_db.handle);
394
395   db->RemoveLocalBarrierReceiver(h);
396 }
397
398 extern "C" void LDAtLocalBarrier(LDHandle _db, LDBarrierClient h)
399 {
400   LBDB *const db = (LBDB*)(_db.handle);
401         
402   db->AtLocalBarrier(h);
403 }
404
405 extern "C" void LDLocalBarrierOn(LDHandle _db)
406 {
407   LBDB *const db = (LBDB*)(_db.handle);
408
409   db->LocalBarrierOn();
410 }
411
412 extern "C" void LDLocalBarrierOff(LDHandle _db)
413 {
414   LBDB *const db = (LBDB*)(_db.handle);
415
416   db->LocalBarrierOff();
417 }
418
419
420 extern "C" void LDResumeClients(LDHandle _db)
421 {
422   LBDB *const db = (LBDB*)(_db.handle);
423
424   db->ResumeClients();
425 }
426
427 static void work(int iter_block, int* result) {
428   int i;
429   *result = 1;
430   for(i=0; i < iter_block; i++) {
431     double b=0.1 + 0.1 * *result;
432     *result=(int)(sqrt(1+cos(b * 1.57)));
433   }
434 }
435
436 extern "C" int LDProcessorSpeed()
437 {
438   // for SMP version, if one processor have done this testing,
439   // we can skip the other processors by remember the number here
440   static int thisProcessorSpeed = -1;
441
442   if (_lb_args.samePeSpeed() || CkNumPes() == 1)  // I think it is safe to assume that we can
443     return 1;            // skip this if we are only using 1 PE
444   
445   if (thisProcessorSpeed != -1) return thisProcessorSpeed;
446
447   //if (CkMyPe()==0) CkPrintf("Measuring processor speeds...");
448
449   static int result=0;  // I don't care what this is, its just for
450                         // timing, so this is thread safe.
451   int wps = 0;
452   const double elapse = 0.4;
453   // First, count how many iterations for .2 second.
454   // Since we are doing lots of function calls, this will be rough
455   const double end_time = CmiCpuTimer()+elapse;
456   wps = 0;
457   while(CmiCpuTimer() < end_time) {
458     work(1000,&result);
459     wps+=1000;
460   }
461
462   // Now we have a rough idea of how many iterations there are per
463   // second, so just perform a few cycles of correction by
464   // running for what we think is 1 second.  Then correct
465   // the number of iterations per second to make it closer
466   // to the correct value
467   
468   for(int i=0; i < 2; i++) {
469     const double start_time = CmiCpuTimer();
470     work(wps,&result);
471     const double end_time = CmiCpuTimer();
472     const double correction = elapse / (end_time-start_time);
473     wps = (int)((double)wps * correction + 0.5);
474   }
475   
476   // If necessary, do a check now
477   //    const double start_time3 = CmiWallTimer();
478   //    work(msec * 1e-3 * wps);
479   //    const double end_time3 = CmiWallTimer();
480   //    CkPrintf("[%d] Work block size is %d %d %f\n",
481   //         thisIndex,wps,msec,1.e3*(end_time3-start_time3));
482   thisProcessorSpeed = wps;
483
484   //if (CkMyPe()==0) CkPrintf(" Done.\n");
485
486   return wps;
487 }
488
489 extern "C" void LDSetLBPeriod(LDHandle _db, double s)   // s is in seconds
490 {
491   LBDB *const db = (LBDB*)(_db.handle);
492   db->SetPeriod(s);
493 }
494
495 extern "C" double LDGetLBPeriod(LDHandle _db)   // s is in seconds
496 {
497   LBDB *const db = (LBDB*)(_db.handle);
498   return db->GetPeriod();
499 }
500
501 /*
502 // to be implemented
503 extern "C" void LDEstObjLoad(LDObjHandle h, double load)
504 {
505 }
506 */
507
508 // to be implemented
509 extern "C" void LDQueryEstLoad(LDHandle bdb)
510 {
511 }
512
513 extern "C" int LDMemusage(LDHandle _db) 
514 {
515   LBDB *const db = (LBDB*)(_db.handle);
516   return db->useMem();
517 }
518
519 #else
520 extern "C" int LDProcessorSpeed() { return 1; }
521 #endif // CMK_LBDB_ON
522
523 CmiBool LDOMidEqual(const LDOMid &i1, const LDOMid &i2)
524 {
525  return i1.id == i2.id?CmiTrue:CmiFalse;
526 }
527
528 CmiBool LDObjIDEqual(const LDObjid &i1, const LDObjid &i2)
529 {
530   return (CmiBool)(i1.id[0] == i2.id[0] 
531          && i1.id[1] == i2.id[1] && i1.id[2] == i2.id[2] 
532          && i1.id[3] == i2.id[3]);
533 }
534
535 /*@}*/