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