00001
00005
00006 #include "HybridBaseLB.h"
00007 #include "LBDBManager.h"
00008 #include "GreedyLB.h"
00009 #include "GreedyCommLB.h"
00010 #include "RefineCommLB.h"
00011 #include "RefineLB.h"
00012
00013 #define DEBUGF(x) // CmiPrintf x;
00014
00015 CreateLBFunc_Def(HybridBaseLB, "HybridBase load balancer")
00016
00017 class DummyMsg: public CMessage_DummyMsg
00018 {
00019 };
00020
00021 void HybridBaseLB::staticMigrated(void* data, LDObjHandle h, int waitBarrier)
00022 {
00023 HybridBaseLB *me = (HybridBaseLB*)(data);
00024
00025 me->Migrated(h, waitBarrier);
00026 }
00027
00028 void HybridBaseLB::staticAtSync(void* data)
00029 {
00030 HybridBaseLB *me = (HybridBaseLB*)(data);
00031
00032 me->AtSync();
00033 }
00034
00035 HybridBaseLB::HybridBaseLB(const CkLBOptions &opt): BaseLB(opt)
00036 {
00037 #if CMK_LBDB_ON
00038 lbname = (char *)"HybridBaseLB";
00039 thisProxy = CProxy_HybridBaseLB(thisgroup);
00040 receiver = theLbdb->
00041 AddLocalBarrierReceiver((LDBarrierFn)(staticAtSync),
00042 (void*)(this));
00043 notifier = theLbdb->getLBDB()->
00044 NotifyMigrated((LDMigratedFn)(staticMigrated), (void*)(this));
00045
00046 statsStrategy = FULL;
00047
00048
00049 if (CkNumPes() <= 4) {
00050 tree = new TwoLevelTree;
00051 }
00052 else {
00053 tree = new ThreeLevelTree;
00054 if (CkNumPes() >= 4096) statsStrategy = SHRINK;
00055
00056
00057 }
00058
00059 if (CkMyPe() == 0)
00060 CkPrintf("%s: %s is created.\n", lbname, tree->name());
00061
00062
00063
00064
00065
00066 currentLevel = 0;
00067 foundNeighbors = 0;
00068 future_migrates_expected = -1;
00069
00070 vector_n_moves = 0;
00071
00072 maxLoad = 0.0;
00073 maxCpuLoad = 0.0;
00074 totalLoad = 0.0;
00075 maxCommCount = 0;
00076 maxCommBytes = 0.0;
00077 maxMem = 0.0;
00078
00079 if (_lb_args.statsOn()) theLbdb->CollectStatsOn();
00080
00081 group1_created = 0;
00082 #endif
00083 }
00084
00085 void HybridBaseLB::initTree()
00086 {
00087 #if CMK_LBDB_ON
00088 #if ! CMK_BIGSIM_CHARM
00089
00090 if (tree->isroot(CkMyPe(), 1)) {
00091 int npes = tree->numChildren(CkMyPe(), 1);
00092 if (npes >= 128) {
00093 int *pes = new int[npes];
00094 tree->getChildren(CkMyPe(), 1, pes, npes);
00095 group1 = CmiEstablishGroup(npes, pes);
00096 group1_created = 1;
00097 delete [] pes;
00098 }
00099 }
00100 #endif
00101 #endif
00102 }
00103
00104 HybridBaseLB::~HybridBaseLB()
00105 {
00106 #if CMK_LBDB_ON
00107 theLbdb = CProxy_LBDatabase(_lbdb).ckLocalBranch();
00108 if (theLbdb) {
00109 theLbdb->getLBDB()->
00110 RemoveNotifyMigrated(notifier);
00111
00112
00113 }
00114 delete tree;
00115 #endif
00116 }
00117
00118
00119 void HybridBaseLB::FindNeighbors()
00120 {
00121 if (foundNeighbors == 0) {
00122
00123
00124
00125 int nlevels = tree->numLevels();
00126 int mype = CkMyPe();
00127 for (int level=0; level<nlevels; level++)
00128 {
00129 LevelData *data = new LevelData;
00130 data->parent = tree->parent(mype, level);
00131 if (tree->isroot(mype, level)) {
00132 data->nChildren = tree->numChildren(mype, level);
00133 data->children = new int[data->nChildren];
00134 tree->getChildren(mype, level, data->children, data->nChildren);
00135 data->statsMsgsList = new CLBStatsMsg*[data->nChildren];
00136 for(int i=0; i < data->nChildren; i++)
00137 data->statsMsgsList[i] = NULL;
00138 data->statsData = new LDStats(data->nChildren+1, 0);
00139
00140 ProcStats &procStat = data->statsData->procs[data->nChildren];
00141 procStat.available = CmiFalse;
00142 }
00143 levelData.push_back(data);
00144 DEBUGF(("[%d] level: %d nchildren:%d - %d %d\n", CkMyPe(), level, data->nChildren, data->nChildren>0?data->children[0]:-1, data->nChildren>1?data->children[1]:-1));
00145 }
00146
00147 foundNeighbors = 1;
00148 }
00149 }
00150
00151 void HybridBaseLB::AtSync()
00152 {
00153 #if CMK_LBDB_ON
00154
00155
00156 FindNeighbors();
00157
00158
00159 if (!QueryBalanceNow(step()) || CkNumPes() == 1) {
00160 MigrationDone(0);
00161 return;
00162 }
00163
00164 thisProxy[CkMyPe()].ProcessAtSync();
00165 #endif
00166 }
00167
00168 void HybridBaseLB::ProcessAtSync()
00169 {
00170 #if CMK_LBDB_ON
00171 start_lb_time = 0;
00172
00173 if (CkMyPe() == 0) {
00174 start_lb_time = CkWallTimer();
00175 if (_lb_args.debug())
00176 CkPrintf("[%s] Load balancing step %d starting at %f\n",
00177 lbName(), step(), CkWallTimer());
00178 }
00179
00180
00181 CLBStatsMsg* msg = AssembleStats();
00182
00183 CkMarshalledCLBStatsMessage marshmsg(msg);
00184
00185 thisProxy[levelData[0]->parent].ReceiveStats(marshmsg, 0);
00186
00187 DEBUGF(("[%d] Send stats to myself\n", CkMyPe()));
00188 #endif
00189 }
00190
00191
00192 CLBStatsMsg* HybridBaseLB::AssembleStats()
00193 {
00194 #if CMK_LBDB_ON
00195
00196 const int osz = theLbdb->GetObjDataSz();
00197 const int csz = theLbdb->GetCommDataSz();
00198
00199 CLBStatsMsg* msg = new CLBStatsMsg(osz, csz);
00200 msg->from_pe = CkMyPe();
00201
00202
00203 #if CMK_LB_CPUTIMER
00204 theLbdb->GetTime(&msg->total_walltime,&msg->total_cputime,
00205 &msg->idletime, &msg->bg_walltime,&msg->bg_cputime);
00206 #else
00207 theLbdb->GetTime(&msg->total_walltime,&msg->total_walltime,
00208 &msg->idletime, &msg->bg_walltime,&msg->bg_walltime);
00209 #endif
00210
00211
00212 msg->pe_speed = 1;
00213
00214 msg->n_objs = osz;
00215 theLbdb->GetObjData(msg->objData);
00216 msg->n_comm = csz;
00217 theLbdb->GetCommData(msg->commData);
00218
00219 return msg;
00220 #else
00221 return NULL;
00222 #endif
00223 }
00224
00225 void HybridBaseLB::ReceiveStats(CkMarshalledCLBStatsMessage &data, int fromlevel)
00226 {
00227 #if CMK_LBDB_ON
00228 FindNeighbors();
00229
00230
00231 CLBStatsMsg *m = data.getMessage();
00232 int atlevel = fromlevel + 1;
00233 CmiAssert(tree->isroot(CkMyPe(), atlevel));
00234
00235 depositLBStatsMessage(m, atlevel);
00236
00237 int &stats_msg_count = levelData[atlevel]->stats_msg_count;
00238 stats_msg_count ++;
00239
00240 DEBUGF(("[%d] ReceiveStats at level: %d %d/%d\n", CkMyPe(), atlevel, stats_msg_count, levelData[atlevel]->nChildren));
00241 if (stats_msg_count == levelData[atlevel]->nChildren)
00242 {
00243
00244 buildStats(atlevel);
00245 stats_msg_count = 0;
00246 int parent = levelData[atlevel]->parent;
00247 if (parent != -1) {
00248
00249
00250 CLBStatsMsg* cmsg = buildCombinedLBStatsMessage(atlevel);
00251
00252
00253 CkMarshalledCLBStatsMessage marshmsg(cmsg);
00254 thisProxy[parent].ReceiveStats(marshmsg, atlevel);
00255 }
00256 else {
00257
00258 thisProxy[CkMyPe()].Loadbalancing(atlevel);
00259 }
00260 }
00261
00262 #endif
00263 }
00264
00265
00266 void HybridBaseLB::depositLBStatsMessage(CLBStatsMsg *m, int atlevel)
00267 {
00268 int pe = m->from_pe;
00269 int neighborIdx = NeighborIndex(pe, atlevel);
00270
00271 CLBStatsMsg **statsMsgsList = levelData[atlevel]->statsMsgsList;
00272 LDStats *statsData = levelData[atlevel]->statsData;
00273 CmiAssert(statsMsgsList && statsData);
00274
00275 if (statsMsgsList[neighborIdx] != 0) {
00276 CkPrintf("*** Unexpected CLBStatsMsg in ReceiveStats from PE %d-%d ***\n", pe,neighborIdx);
00277 CkAbort("HybridBaseLB> Abort!");
00278 }
00279
00280
00281 for (int i=0; i<m->n_comm; i++) {
00282 LDCommData &commData = m->commData[i];
00283
00284 if (commData.from_proc()) m->commData[i].src_proc = neighborIdx;
00285 if (commData.receiver.get_type() == LD_PROC_MSG) m->commData[i].receiver.setProc(neighborIdx);
00286 }
00287
00288 statsMsgsList[neighborIdx] = m;
00289
00290 struct ProcStats &procStat = statsData->procs[neighborIdx];
00291 procStat.pe = pe;
00292 procStat.total_walltime = m->total_walltime;
00293 procStat.idletime = m->idletime;
00294 procStat.bg_walltime = m->bg_walltime;
00295 #if CMK_LB_CPUTIMER
00296 procStat.total_cputime = m->total_cputime;
00297 procStat.bg_cputime = m->bg_cputime;
00298 #endif
00299 procStat.pe_speed = m->pe_speed;
00300 procStat.available = CmiTrue;
00301 procStat.n_objs = m->n_objs;
00302
00303 statsData->n_objs += m->n_objs;
00304 statsData->n_comm += m->n_comm;
00305 }
00306
00307
00308 void HybridBaseLB::buildStats(int atlevel)
00309 {
00310 #if CMK_LBDB_ON
00311
00312 LevelData *lData = levelData[atlevel];
00313 LDStats *statsData = lData->statsData;
00314 CLBStatsMsg **statsMsgsList = lData->statsMsgsList;
00315 int stats_msg_count = lData->stats_msg_count;
00316
00317
00318 DEBUGF(("[%d] buildStats for %d nobj:%d\n", CkMyPe(), stats_msg_count, statsData->n_objs));
00319 statsData->nprocs() = stats_msg_count;
00320 statsData->objData.resize(statsData->n_objs);
00321 statsData->commData.resize(statsData->n_comm);
00322 statsData->from_proc.resize(statsData->n_objs);
00323 statsData->to_proc.resize(statsData->n_objs);
00324 int nobj = 0;
00325 int nmigobj = 0;
00326 int ncom = 0;
00327 for (int n=0; n<stats_msg_count; n++) {
00328 int i;
00329 CLBStatsMsg *msg = statsMsgsList[n];
00330 int pe = msg->from_pe;
00331 for (i=0; i<msg->n_objs; i++) {
00332
00333 statsData->from_proc[nobj] = statsData->to_proc[nobj] = NeighborIndex(pe, atlevel);
00334 statsData->objData[nobj] = msg->objData[i];
00335 if (msg->objData[i].migratable) nmigobj++;
00336 nobj++;
00337 }
00338 for (i=0; i<msg->n_comm; i++) {
00339 statsData->commData[ncom] = msg->commData[i];
00340 ncom++;
00341 }
00342
00343 delete msg;
00344 statsMsgsList[n]=0;
00345 }
00346 if (_lb_args.debug()>1) {
00347 CmiPrintf("[%d] n_obj:%d migratable:%d ncom:%d at level %d at %f.\n", CkMyPe(), nobj, nmigobj, ncom, atlevel, CkWallTimer());
00348 }
00349 CmiAssert(statsData->n_objs == nobj);
00350 CmiAssert(statsData->n_comm == ncom);
00351 statsData->n_migrateobjs = nmigobj;
00352 #endif
00353 }
00354
00355
00356
00357 CLBStatsMsg * HybridBaseLB::buildCombinedLBStatsMessage(int atlevel)
00358 {
00359 #if CMK_LBDB_ON
00360 int i;
00361 double obj_walltime, obj_nmwalltime;
00362 #if CMK_LB_CPUTIMER
00363 double obj_cputime, obj_nmcputime;
00364 #endif
00365
00366 LDStats *statsData = levelData[atlevel]->statsData;
00367 CmiAssert(statsData);
00368
00369 CLBStatsMsg* cmsg;
00370
00371 int osz = statsData->n_objs;
00372 int csz = statsData->n_comm;
00373
00374 int shrink = 0;
00375 if ((statsStrategy == SHRINK || statsStrategy == SHRINK_NULL) && atlevel == tree->numLevels()-2)
00376 {
00377 shrink = 1;
00378 obj_walltime = obj_nmwalltime = 0.0;
00379 #if CMK_LB_CPUTIMER
00380 obj_cputime = obj_nmcputime = 0.0;
00381 #endif
00382 for (i=0; i<osz; i++) {
00383 if (statsData->objData[i].migratable) {
00384 obj_walltime += statsData->objData[i].wallTime;
00385 #if CMK_LB_CPUTIMER
00386 obj_cputime += statsData->objData[i].cpuTime;
00387 #endif
00388 }
00389 else {
00390 obj_nmwalltime += statsData->objData[i].wallTime;
00391 #if CMK_LB_CPUTIMER
00392 obj_nmcputime += statsData->objData[i].cpuTime;
00393 #endif
00394 }
00395 }
00396
00397 osz = csz = 0;
00398 }
00399
00400 cmsg = new CLBStatsMsg(osz, csz);
00401 int mype = CkMyPe();
00402 cmsg->from_pe = mype;
00403
00404
00405 cmsg->pe_speed = 0;
00406 cmsg->total_walltime = 0.0;
00407 cmsg->idletime = 0.0;
00408 cmsg->bg_walltime = 0.0;
00409 #if CMK_LB_CPUTIMER
00410 cmsg->total_cputime = 0.0;
00411 cmsg->bg_cputime = 0.0;
00412 #endif
00413
00414 for (int pe=0; pe<statsData->nprocs(); pe++) {
00415 struct ProcStats &procStat = statsData->procs[pe];
00416 cmsg->pe_speed += procStat.pe_speed;
00417 cmsg->total_walltime += procStat.total_walltime;
00418 cmsg->idletime += procStat.idletime;
00419 cmsg->bg_walltime += procStat.bg_walltime;
00420 #if CMK_LB_CPUTIMER
00421 cmsg->total_cputime += procStat.total_cputime;
00422 cmsg->bg_cputime += procStat.bg_cputime;
00423 #endif
00424 }
00425
00426
00427
00428
00429
00430
00431
00432 cmsg->n_objs = osz;
00433 for (i=0; i<osz; i++) {
00434 cmsg->objData[i] = statsData->objData[i];
00435 }
00436
00437 cmsg->n_comm = csz;
00438 for (i=0; i<csz; i++) {
00439 LDCommData &commData = statsData->commData[i];
00440 cmsg->commData[i] = commData;
00441
00442 if (commData.from_proc()) cmsg->commData[i].src_proc = mype;
00443 if (commData.receiver.get_type() == LD_PROC_MSG) cmsg->commData[i].receiver.setProc(mype);
00444 }
00445
00446 if (shrink) {
00447 cmsg->total_walltime = obj_walltime;
00448 cmsg->bg_walltime += obj_nmwalltime;
00449 #if CMK_LB_CPUTIMER
00450 cmsg->total_cputime = obj_cputime;
00451 cmsg->bg_cputime += obj_nmcputime;
00452 #endif
00453 }
00454
00455 return cmsg;
00456 #else
00457 return NULL;
00458 #endif
00459 }
00460
00461
00462
00463 void HybridBaseLB::Loadbalancing(int atlevel)
00464 {
00465 int i;
00466
00467 CmiAssert(atlevel >= 1);
00468 CmiAssert(tree->isroot(CkMyPe(), atlevel));
00469
00470 LevelData *lData = levelData[atlevel];
00471 LDStats *statsData = lData->statsData;
00472 CmiAssert(statsData);
00473
00474
00475
00476
00477
00478 if (_lb_args.ignoreBgLoad()) statsData->clearBgLoad();
00479
00480 currentLevel = atlevel;
00481 int nclients = lData->nChildren;
00482
00483 DEBUGF(("[%d] Calling Strategy ... \n", CkMyPe()));
00484 double start_lb_time, strat_end_time;
00485 start_lb_time = CkWallTimer();
00486
00487 if ((statsStrategy == SHRINK || statsStrategy == SHRINK_NULL) && atlevel == tree->numLevels()-1) {
00488
00489 LBVectorMigrateMsg* migrateMsg = VectorStrategy(statsData);
00490 strat_end_time = CkWallTimer();
00491
00492
00493 thisProxy.ReceiveVectorMigration(migrateMsg, nclients, lData->children);
00494 }
00495 else {
00496 LBMigrateMsg* migrateMsg = Strategy(statsData);
00497 strat_end_time = CkWallTimer();
00498
00499
00500
00501 if (!group1_created)
00502 thisProxy.ReceiveMigration(migrateMsg, nclients, lData->children);
00503 else {
00504
00505 thisProxy.ReceiveMigration(migrateMsg, group1);
00506
00507 }
00508
00509 }
00510
00511 if (_lb_args.debug()>0){
00512 CkPrintf("[%d] Loadbalancing Level %d (%d children) started at %f, elapsed time %f\n", CkMyPe(), atlevel, lData->nChildren, start_lb_time, strat_end_time-start_lb_time);
00513 if (atlevel == tree->numLevels()-1) {
00514 CkPrintf("[%d] %s memUsage: %.2fKB\n", CkMyPe(), lbName(), (1.0*useMem())/1024);
00515 }
00516 }
00517
00518
00519 if (atlevel < tree->numLevels()-1) {
00520 for (i=0; i<statsData->n_objs; i++) {
00521 CmiAssert(statsData->from_proc[i] != -1);
00522 if (statsData->from_proc[i] == nclients) {
00523 CmiAssert(statsData->to_proc[i] < nclients);
00524 int tope = lData->children[statsData->to_proc[i]];
00525
00526 CkVec<LDCommData> comms;
00527
00528 thisProxy[tope].ObjMigrated(statsData->objData[i], comms.getVec(), comms.size(), atlevel-1);
00529 }
00530 }
00531 }
00532 }
00533
00534 LBMigrateMsg* HybridBaseLB::Strategy(LDStats* stats)
00535 {
00536 #if CMK_LBDB_ON
00537 work(stats);
00538
00539 if (_lb_args.debug()>2) {
00540 CkPrintf("Obj Map:\n");
00541 for (int i=0; i<stats->n_objs; i++) CkPrintf("%d ", stats->to_proc[i]);
00542 CkPrintf("\n");
00543 }
00544
00545 return createMigrateMsg(stats);
00546 #else
00547 return NULL;
00548 #endif
00549 }
00550
00551
00552
00553 void HybridBaseLB::ReceiveMigration(LBMigrateMsg *msg)
00554 {
00555 #if CMK_LBDB_ON
00556 FindNeighbors();
00557
00558 int atlevel = msg->level - 1;
00559
00560 DEBUGF(("[%d] ReceiveMigration\n", CkMyPe()));
00561
00562 LevelData *lData = levelData[atlevel];
00563
00564
00565 LDStats *statsData = lData->statsData;
00566
00567
00568 const int me = CkMyPe();
00569 lData->migrates_expected = 0;
00570 for(int i=0; i < msg->n_moves; i++) {
00571 MigrateInfo& move = msg->moves[i];
00572
00573 if (move.from_pe != me && move.to_pe == me) {
00574
00575 DEBUGF(("[%d] expecting LDStats object from %d\n",me,move.from_pe));
00576
00577 lData->migrates_expected ++;
00578 }
00579 else if (move.from_pe == me) {
00580 if (statsData) {
00581
00582 int obj;
00583 int found = 0;
00584 for (obj = 0; obj<statsData->n_objs; obj++) {
00585 if (move.obj.omID() == statsData->objData[obj].handle.omID() &&
00586 move.obj.objID() == statsData->objData[obj].handle.objID())
00587 {
00588 DEBUGF(("[%d] level: %d sending objData %d to %d. \n", CkMyPe(), atlevel, obj, move.to_pe));
00589 found = 1;
00590
00591 CkVec<LDCommData> comms;
00592 collectCommData(obj, comms, atlevel);
00593 if (move.to_pe != -1) {
00594
00595 thisProxy[move.to_pe].ObjMigrated(statsData->objData[obj], comms.getVec(), comms.size(), atlevel);
00596 }
00597 lData->outObjs.push_back(MigrationRecord(move.obj, lData->children[statsData->from_proc[obj]], -1));
00598 statsData->removeObject(obj);
00599 break;
00600 }
00601 }
00602 CmiAssert(found == 1);
00603 }
00604 else {
00605 if (move.to_pe == -1) {
00606 lData->outObjs.push_back(MigrationRecord(move.obj, CkMyPe(), -1));
00607 }
00608 else {
00609
00610 theLbdb->Migrate(move.obj,move.to_pe);
00611 }
00612 }
00613 }
00614 }
00615
00616 if (lData->migrationDone())
00617 StatsDone(atlevel);
00618 #endif
00619 }
00620
00621 extern LBVectorMigrateMsg * VectorStrategy(BaseLB::LDStats *stats);
00622
00623 LBVectorMigrateMsg* HybridBaseLB::VectorStrategy(LDStats* stats)
00624 {
00625 #if CMK_LBDB_ON
00626 LBVectorMigrateMsg* msg;
00627 if (statsStrategy == SHRINK_NULL) {
00628 msg = new(0,0) LBVectorMigrateMsg;
00629 msg->n_moves = 0;
00630 msg->level = currentLevel;
00631 }
00632 else {
00633 msg = ::VectorStrategy(stats);
00634 msg->level = currentLevel;
00635
00636
00637 LevelData *lData = levelData[currentLevel];
00638 for(int i=0; i < msg->n_moves; i++) {
00639 VectorMigrateInfo* move = &msg->moves[i];
00640 move->from_pe = lData->children[move->from_pe];
00641 move->to_pe = lData->children[move->to_pe];
00642 }
00643 }
00644 return msg;
00645 #else
00646 return NULL;
00647 #endif
00648 }
00649
00650 void HybridBaseLB::ReceiveVectorMigration(LBVectorMigrateMsg *msg)
00651 {
00652 #if CMK_LBDB_ON
00653 FindNeighbors();
00654
00655 int atlevel = msg->level - 1;
00656
00657 DEBUGF(("[%d] ReceiveMigration\n", CkMyPe()));
00658
00659 LevelData *lData = levelData[atlevel];
00660 LDStats *statsData = lData->statsData;
00661
00662
00663 lData->vector_expected = 0;
00664 for (int i=0; i<msg->n_moves; i++) {
00665 VectorMigrateInfo &move = msg->moves[i];
00666 CkVec<LDObjData> objs;
00667 CkVec<LDCommData> comms;
00668 if (move.from_pe == CkMyPe()) {
00669 int toPe = move.to_pe;
00670 double load = move.load;
00671 int count = 0;
00672
00673 for (int obj=statsData->n_objs-1; obj>=0; obj--) {
00674 LDObjData &objData = statsData->objData[obj];
00675 if (!objData.migratable) continue;
00676 if (objData.wallTime <= load) {
00677 if (_lb_args.debug()>2)
00678 CkPrintf("[%d] send obj: %d to PE %d (load: %f).\n", CkMyPe(), obj, toPe, objData.wallTime);
00679 objs.push_back(objData);
00680
00681 collectCommData(obj, comms, atlevel);
00682 lData->outObjs.push_back(MigrationRecord(objData.handle, lData->children[statsData->from_proc[obj]], -1));
00683 load -= objData.wallTime;
00684 statsData->removeObject(obj);
00685 count ++;
00686 if (load <= 0.0) break;
00687 }
00688 }
00689 if (_lb_args.debug()>1)
00690 CkPrintf("[%d] sending %d objects to %d at %f.\n", CkMyPe(), count, toPe, CkWallTimer());
00691 if (objs.size() > 0)
00692 thisProxy[toPe].ObjsMigrated(objs.getVec(), objs.size(), comms.getVec(), comms.size(), atlevel);
00693 thisProxy[toPe].TotalObjMigrated(count, atlevel);
00694 }
00695 else if (move.to_pe == CkMyPe()) {
00696
00697 lData->vector_expected ++;
00698 }
00699 }
00700
00701 if (_lb_args.debug()>1)
00702 CkPrintf("[%d] expecting %d vectors. \n", CkMyPe(), lData->vector_expected);
00703 if (lData->vectorReceived()) {
00704 VectorDone(atlevel);
00705 if (lData->migrationDone())
00706 StatsDone(atlevel);
00707 }
00708
00709 delete msg;
00710 #endif
00711 }
00712
00713
00714 void HybridBaseLB::ObjsMigrated(LDObjData *datas, int m, LDCommData *cdata, int n, int atlevel)
00715 {
00716 int i;
00717 LevelData *lData = levelData[atlevel];
00718 LDStats *statsData = lData->statsData;
00719
00720 if (statsData != NULL) {
00721 CkVec<LDObjData> &oData = statsData->objData;
00722
00723 for (i=0; i<m; i++)
00724 {
00725
00726 LDObjData &data = datas[i];
00727 oData.push_back(data);
00728 statsData->n_objs++;
00729 if (data.migratable) statsData->n_migrateobjs++;
00730
00731
00732 statsData->from_proc.push_back(lData->nChildren);
00733 statsData->to_proc.push_back(lData->nChildren);
00734 }
00735
00736
00737 if (n) {
00738 CkVec<LDCommData> &cData = statsData->commData;
00739 for (int i=0; i<n; i++)
00740 cData.push_back(cdata[i]);
00741 statsData->n_comm += n;
00742 statsData->deleteCommHash();
00743 }
00744 }
00745 else {
00746 for (i=0; i<m; i++) {
00747 LDObjData &data = datas[i];
00748 LDObjKey key;
00749 key.omID() = data.omID();
00750 key.objID() = data.objID();
00751 newObjs.push_back(Location(key, -1));
00752 }
00753 }
00754
00755 lData->obj_completed+=m;
00756 if (lData->migrationDone()) {
00757 StatsDone(atlevel);
00758 }
00759 }
00760
00761 void HybridBaseLB::VectorDone(int atlevel)
00762 {
00763 LevelData *lData = levelData[atlevel];
00764 lData->vector_expected = -1;
00765 lData->vector_completed = 0;
00766
00767 lData->migrates_expected = vector_n_moves;
00768 vector_n_moves = 0;
00769 if (_lb_args.debug()>1)
00770 CkPrintf("[%d] VectorDone %d %d at %f.\n", CkMyPe(), lData->vector_expected, lData->migrates_expected, CkWallTimer());
00771 }
00772
00773
00774 void HybridBaseLB::TotalObjMigrated(int count, int atlevel)
00775 {
00776 LevelData *lData = levelData[atlevel];
00777 lData->vector_completed ++;
00778 vector_n_moves += count;
00779 if (_lb_args.debug()>1)
00780 CkPrintf("[%d] TotalObjMigrated receive %d objects at %f.\n", CkMyPe(), count, CkWallTimer());
00781 if (lData->vectorReceived()) {
00782 VectorDone(atlevel);
00783 if (lData->migrationDone())
00784 StatsDone(atlevel);
00785 }
00786 }
00787
00788 void HybridBaseLB::Migrated(LDObjHandle h, int waitBarrier)
00789 {
00790 LevelData *lData = levelData[0];
00791
00792 lData->migrates_completed++;
00793 DEBUGF(("[%d] An object migrated! %d %d\n", CkMyPe(),lData->migrates_completed,lData->migrates_expected));
00794 if (lData->migrationDone()) {
00795 if (!lData->resumeAfterMigration) {
00796 StatsDone(0);
00797 }
00798 else {
00799
00800 MigrationDone(1);
00801 }
00802 }
00803 }
00804
00805
00806 void HybridBaseLB::collectCommData(int objIdx, CkVec<LDCommData> &comms, int atlevel)
00807 {
00808 LevelData *lData = levelData[atlevel];
00809 LDStats *statsData = lData->statsData;
00810
00811 LDObjData &objData = statsData->objData[objIdx];
00812
00813 for (int com=0; com<statsData->n_comm; com++) {
00814 LDCommData &cdata = statsData->commData[com];
00815 if (cdata.from_proc()) continue;
00816 if (cdata.sender.objID() == objData.objID() && cdata.sender.omID() == objData.omID())
00817 comms.push_back(cdata);
00818 }
00819 }
00820
00821
00822 void HybridBaseLB::ObjMigrated(LDObjData data, LDCommData *cdata, int n, int atlevel)
00823 {
00824 LevelData *lData = levelData[atlevel];
00825 LDStats *statsData = lData->statsData;
00826
00827 if (statsData != NULL) {
00828 CkVec<LDObjData> &oData = statsData->objData;
00829
00830
00831 oData.push_back(data);
00832 statsData->n_objs++;
00833 if (data.migratable) statsData->n_migrateobjs++;
00834
00835
00836 statsData->from_proc.push_back(lData->nChildren);
00837 statsData->to_proc.push_back(lData->nChildren);
00838
00839
00840 if (n) {
00841 CkVec<LDCommData> &cData = statsData->commData;
00842 for (int i=0; i<n; i++)
00843 cData.push_back(cdata[i]);
00844 statsData->n_comm += n;
00845 statsData->deleteCommHash();
00846 }
00847 }
00848 else {
00849 LDObjKey key;
00850 key.omID() = data.omID();
00851 key.objID() = data.objID();
00852 newObjs.push_back(Location(key, -1));
00853 }
00854
00855 lData->obj_completed++;
00856 if (lData->migrationDone()) {
00857 StatsDone(atlevel);
00858 }
00859 }
00860
00861
00862 void HybridBaseLB::StatsDone(int atlevel)
00863 {
00864
00865 LevelData *lData = levelData[atlevel];
00866 lData->obj_expected = -1;
00867 lData->migrates_expected = -1;
00868 lData->obj_completed = 0;
00869 lData->migrates_completed = 0;
00870
00871 CmiAssert(lData->parent!=-1);
00872
00873 thisProxy[lData->parent].NotifyObjectMigrationDone(atlevel);
00874 }
00875
00876
00877 void HybridBaseLB::NotifyObjectMigrationDone(int fromlevel)
00878 {
00879
00880 int atlevel = fromlevel + 1;
00881 LevelData *lData = levelData[atlevel];
00882
00883 lData->mig_reported ++;
00884 if (lData->mig_reported == lData->nChildren) {
00885 lData->mig_reported = 0;
00886
00887 if (atlevel > 1) {
00888
00889 thisProxy.Loadbalancing(atlevel-1, lData->nChildren, lData->children);
00890 }
00891 else {
00892 if (_lb_args.debug() > 1)
00893 CkPrintf("[%d] NotifyObjectMigrationDone at level %d started at %f\n",
00894 CkMyPe(), atlevel, CkWallTimer());
00895 DummyMsg *m = new (8*sizeof(int)) DummyMsg;
00896 *((int *)CkPriorityPtr(m)) = -100-atlevel;
00897 CkSetQueueing(m, CK_QUEUEING_IFIFO);
00898 thisProxy.StartCollectInfo(m, lData->nChildren, lData->children);
00899 }
00900 }
00901 }
00902
00903
00904
00905 void HybridBaseLB::StartCollectInfo(DummyMsg *m)
00906 {
00907 int i;
00908 delete m;
00909 LevelData *lData = levelData[0];
00910
00911
00912 lData->resumeAfterMigration = 1;
00913
00914
00915 int migs = lData->outObjs.size() + newObjs.size();
00916 Location *locs = new Location[migs];
00917 int count=0;
00918 int me = CkMyPe();
00919 for (i=0; i<newObjs.size(); i++) {
00920 locs[count] = newObjs[i];
00921 locs[count].loc = me;
00922 count++;
00923 }
00924 for (i=0; i<lData->outObjs.size(); i++) {
00925 LDObjKey key;
00926 key.omID() = lData->outObjs[i].handle.omID();
00927 key.objID() = lData->outObjs[i].handle.objID();
00928 locs[count].key = key;
00929 locs[count].loc = -1;
00930 count++;
00931 }
00932
00933 DEBUGF(("[%d] level 0 has %d unmatched (out)%d+(new)%d. \n", CkMyPe(), migs, lData->outObjs.size(), newObjs.size()));
00934 thisProxy[lData->parent].CollectInfo(locs, migs, 0);
00935 delete [] locs;
00936 }
00937
00938 void HybridBaseLB::CollectInfo(Location *loc, int n, int fromlevel)
00939 {
00940 int atlevel = fromlevel + 1;
00941 LevelData *lData = levelData[atlevel];
00942 lData->info_recved++;
00943
00944 CkVec<Location> &matchedObjs = lData->matchedObjs;
00945 std::map<LDObjKey, int> &unmatchedObjs = lData->unmatchedObjs;
00946
00947
00948 #if 0
00949 for (int i=0; i<n; i++) {
00950
00951
00952 int found = 0;
00953 for (int obj=0; obj<unmatchedObjs.size(); obj++) {
00954 if (loc[i].key == unmatchedObjs[obj].key) {
00955
00956 CmiAssert(unmatchedObjs[obj].loc != -1 || loc[i].loc != -1);
00957 if (unmatchedObjs[obj].loc == -1) unmatchedObjs[obj].loc = loc[i].loc;
00958 matchedObjs.push_back(unmatchedObjs[obj]);
00959 unmatchedObjs.remove(obj);
00960 found = 1;
00961 break;
00962 }
00963 }
00964 if (!found) unmatchedObjs.push_back(loc[i]);
00965 }
00966 #else
00967 for (int i=0; i<n; i++) {
00968 std::map<LDObjKey, int>::iterator iter = unmatchedObjs.find(loc[i].key);
00969 if (iter != unmatchedObjs.end()) {
00970 CmiAssert(iter->second != -1 || loc[i].loc != -1);
00971 if (loc[i].loc == -1) loc[i].loc = iter->second;
00972 matchedObjs.push_back(loc[i]);
00973 unmatchedObjs.erase(iter);
00974 }
00975 else
00976 unmatchedObjs[loc[i].key] = loc[i].loc;
00977 }
00978 #endif
00979
00980 DEBUGF(("[%d] level %d has %d unmatched and %d matched. \n", CkMyPe(), atlevel, unmatchedObjs.size(), matchedObjs.size()));
00981
00982 if (lData->info_recved == lData->nChildren) {
00983 lData->info_recved = 0;
00984 if (_lb_args.debug() > 1)
00985 CkPrintf("[%d] CollectInfo at level %d started at %f\n",
00986 CkMyPe(), atlevel, CkWallTimer());
00987 if (lData->parent != -1) {
00988
00989 CkVec<Location> unmatchedbuf;
00990 for(std::map<LDObjKey, int>::const_iterator it = unmatchedObjs.begin(); it != unmatchedObjs.end(); ++it)
00991 {
00992 unmatchedbuf.push_back(Location(it->first, it->second));
00993 }
00994
00995 thisProxy[lData->parent].CollectInfo(unmatchedbuf.getVec(), unmatchedbuf.size(), atlevel);
00996 }
00997 else {
00998
00999 CmiAssert(unmatchedObjs.size() == 0);
01000
01001 thisProxy.PropagateInfo(matchedObjs.getVec(), matchedObjs.size(), atlevel, lData->nChildren, lData->children);
01002 lData->statsData->clear();
01003 }
01004 }
01005 }
01006
01007 void HybridBaseLB::PropagateInfo(Location *loc, int n, int fromlevel)
01008 {
01009 #if CMK_LBDB_ON
01010 int i, obj;
01011 int atlevel = fromlevel - 1;
01012 LevelData *lData = levelData[atlevel];
01013 CkVec<Location> &matchedObjs = lData->matchedObjs;
01014
01015 std::map<LDObjKey, int> &unmatchedObjs = lData->unmatchedObjs;
01016
01017 if (atlevel > 0) {
01018 if (_lb_args.debug() > 1)
01019 CkPrintf("[%d] PropagateInfo at level %d started at %f\n",
01020 CkMyPe(), atlevel, CkWallTimer());
01021
01022 #if 0
01023 for (i=0; i<n; i++) {
01024
01025
01026 for (obj=0; obj<unmatchedObjs.size(); obj++) {
01027 if (loc[i].key == unmatchedObjs[obj].key) {
01028
01029 CmiAssert(unmatchedObjs[obj].loc != -1 || loc[i].loc != -1);
01030 if (unmatchedObjs[obj].loc == -1) unmatchedObjs[obj].loc = loc[i].loc;
01031 matchedObjs.push_back(unmatchedObjs[obj]);
01032 unmatchedObjs.remove(obj);
01033 break;
01034 }
01035 }
01036 }
01037 #else
01038 for (int i=0; i<n; i++) {
01039
01040 const LDObjKey key = loc[i].key;
01041 std::map<LDObjKey, int>::iterator iter = unmatchedObjs.find(key);
01042 if (iter != unmatchedObjs.end()) {
01043
01044 CmiAssert(iter->second != -1 || loc[i].loc != -1);
01045 if (loc[i].loc == -1) loc[i].loc = iter->second;
01046 matchedObjs.push_back(loc[i]);
01047 unmatchedObjs.erase(iter);
01048 }
01049 }
01050 #endif
01051 CmiAssert(unmatchedObjs.size() == 0);
01052 DEBUGF(("[%d] level %d PropagateInfo had %d matchedObjs. \n", CkMyPe(), atlevel, matchedObjs.size()));
01053
01054
01055 thisProxy.PropagateInfo(matchedObjs.getVec(), matchedObjs.size(), atlevel, lData->nChildren, lData->children);
01056
01057 lData->statsData->clear();
01058 matchedObjs.free();
01059 }
01060 else {
01061
01062 CkVec<MigrationRecord> & outObjs = lData->outObjs;
01063 int migs = outObjs.size() + newObjs.size();
01064 for (i=0; i<outObjs.size(); i++) {
01065 if (outObjs[i].toPe == -1) {
01066 for (obj=0; obj<n; obj++) {
01067 if (loc[obj].key.omID() == outObjs[i].handle.omID() &&
01068 loc[obj].key.objID() == outObjs[i].handle.objID()) {
01069 outObjs[i].toPe = loc[obj].loc;
01070 break;
01071 }
01072 }
01073 CmiAssert(obj < n);
01074 }
01075 CmiAssert(outObjs[i].toPe != -1);
01076
01077 theLbdb->Migrate(outObjs[i].handle,outObjs[i].toPe);
01078 }
01079
01080 lData->migrates_expected = 0;
01081 future_migrates_expected = 0;
01082 for (i=0; i<newObjs.size(); i++) {
01083 if (newObjs[i].loc == -1) {
01084 for (obj=0; obj<n; obj++) {
01085 if (loc[obj].key == newObjs[i].key) {
01086 newObjs[i].loc = loc[obj].loc;
01087 break;
01088 }
01089 }
01090 CmiAssert(obj < n);
01091 }
01092 CmiAssert(newObjs[i].loc != -1);
01093 lData->migrates_expected++;
01094 }
01095 DEBUGF(("[%d] expecting %d\n", CkMyPe(), lData->migrates_expected));
01096 if (lData->migrationDone()) {
01097 MigrationDone(1);
01098 }
01099 }
01100 #endif
01101 }
01102
01103 void HybridBaseLB::MigrationDone(int balancing)
01104 {
01105 #if CMK_LBDB_ON
01106 LevelData *lData = levelData[0];
01107
01108 DEBUGF(("[%d] HybridBaseLB::MigrationDone!\n", CkMyPe()));
01109
01110 theLbdb->incStep();
01111
01112
01113 for (int i=0; i<tree->numLevels(); i++)
01114 levelData[i]->clear();
01115 newObjs.free();
01116
01117 DEBUGF(("[%d] calling ResumeClients.\n", CkMyPe()));
01118 if (balancing && _lb_args.syncResume()) {
01119
01120 CkCallback cb(CkIndex_HybridBaseLB::ResumeClients((CkReductionMsg*)NULL),
01121 thisProxy);
01122 contribute(sizeof(double), &maxLoad, CkReduction::max_double, cb);
01123 }
01124 else
01125 thisProxy[CkMyPe()].ResumeClients(balancing);
01126
01127 maxLoad = 0.0;
01128 #endif
01129 }
01130
01131 void HybridBaseLB::ResumeClients(CkReductionMsg *msg)
01132 {
01133
01134
01135
01136
01137
01138
01139 ResumeClients(1);
01140 delete msg;
01141 }
01142
01143 void HybridBaseLB::ResumeClients(int balancing)
01144 {
01145 #if CMK_LBDB_ON
01146 DEBUGF(("[%d] ResumeClients. \n", CkMyPe()));
01147
01148 if (CkMyPe() == 0 && balancing) {
01149 double end_lb_time = CkWallTimer();
01150 if (_lb_args.debug())
01151 CkPrintf("[%s] Load balancing step %d finished at %f duration %f\n",
01152 lbName(), step()-1,end_lb_time,end_lb_time - start_lb_time);
01153 }
01154
01155
01156 theLbdb->ClearLoads();
01157
01158 theLbdb->ResumeClients();
01159 #endif
01160 }
01161
01162 void HybridBaseLB::work(LDStats* stats)
01163 {
01164 #if CMK_LBDB_ON
01165 CkPrintf("[%d] HybridBaseLB::work called!\n", CkMyPe());
01166 #endif
01167 }
01168
01169 LBMigrateMsg * HybridBaseLB::createMigrateMsg(LDStats* stats)
01170 {
01171 #if CMK_LBDB_ON
01172 int i;
01173
01174 LevelData *lData = levelData[currentLevel];
01175
01176 CkVec<MigrateInfo*> migrateInfo;
01177
01178
01179
01180 for (i=0; i<stats->n_objs; i++) {
01181 LDObjData &objData = stats->objData[i];
01182 int frompe = stats->from_proc[i];
01183 int tope = stats->to_proc[i];
01184 CmiAssert(tope != -1);
01185 if (frompe != tope) {
01186
01187
01188 #if 0
01189
01190 if (frompe == lData->nChildren) {
01191 frompe = -1;
01192 CmiAssert(tope != -1 && tope != lData->nChildren);
01193 }
01194 else
01195 frompe = lData->children[frompe];
01196 if (tope != -1) {
01197 CmiAssert(tope < lData->nChildren);
01198 tope = lData->children[tope];
01199 }
01200 #endif
01201 MigrateInfo *migrateMe = new MigrateInfo;
01202 migrateMe->obj = objData.handle;
01203 migrateMe->from_pe = frompe;
01204 migrateMe->to_pe = tope;
01205 migrateMe->async_arrival = objData.asyncArrival;
01206 migrateInfo.insertAtEnd(migrateMe);
01207 }
01208 else
01209 CmiAssert(frompe != lData->nChildren);
01210 }
01211
01212
01213 CkVec<MigrationRecord> &outObjs = lData->outObjs;
01214 for (i=0; i<outObjs.size(); i++) {
01215 MigrateInfo *migrateMe = new MigrateInfo;
01216 migrateMe->obj = outObjs[i].handle;
01217 migrateMe->from_pe = outObjs[i].fromPe;
01218 migrateMe->to_pe = -1;
01219
01220 migrateInfo.insertAtEnd(migrateMe);
01221 }
01222
01223
01224 int migrate_count=migrateInfo.length();
01225 DEBUGF(("[%d] level: %d has %d migrations. \n", CkMyPe(), currentLevel, migrate_count));
01226
01227
01228 LBMigrateMsg * msg = new(migrate_count,0,0,0) LBMigrateMsg;
01229 msg->level = currentLevel;
01230 msg->n_moves = migrate_count;
01231 for(i=0; i < migrate_count; i++) {
01232 MigrateInfo* item = (MigrateInfo*) migrateInfo[i];
01233 msg->moves[i] = *item;
01234 delete item;
01235 migrateInfo[i] = 0;
01236 DEBUGF(("[%d] obj (%d %d %d %d) migrate from %d to %d\n", CkMyPe(), item->obj.objID().id[0], item->obj.objID().id[1], item->obj.objID().id[2], item->obj.objID().id[3], item->from_pe, item->to_pe));
01237 }
01238
01239 if (_lb_args.printSummary()) printSummary(stats, stats->nprocs());
01240
01241
01242 for(i=0; i < migrate_count; i++) {
01243 MigrateInfo* move = &msg->moves[i];
01244 if (move->to_pe != -1) {
01245 if (move->from_pe == lData->nChildren) {
01246
01247 move->from_pe = -1;
01248 CmiAssert(move->to_pe != -1 && move->to_pe != lData->nChildren);
01249 }
01250 else
01251 move->from_pe = lData->children[move->from_pe];
01252 CmiAssert(move->to_pe < lData->nChildren);
01253 move->to_pe = lData->children[move->to_pe];
01254 }
01255 }
01256
01257 return msg;
01258 #else
01259 return NULL;
01260 #endif
01261 }
01262
01263
01264 LBMigrateMsg * HybridBaseLB::createMigrateMsg(CkVec<MigrateInfo *> &migrateInfo,int count)
01265 {
01266 int i;
01267
01268
01269 LevelData *lData = levelData[currentLevel];
01270 CkVec<MigrationRecord> &outObjs = lData->outObjs;
01271 for (i=0; i<outObjs.size(); i++) {
01272 MigrateInfo *migrateMe = new MigrateInfo;
01273 migrateMe->obj = outObjs[i].handle;
01274 migrateMe->from_pe = outObjs[i].fromPe;
01275 migrateMe->to_pe = -1;
01276 migrateInfo.insertAtEnd(migrateMe);
01277 }
01278
01279 if (_lb_args.printSummary()) printSummary(NULL, count);
01280
01281 int migrate_count=migrateInfo.length();
01282
01283
01284 LBMigrateMsg* msg = new(migrate_count,0,0,0) LBMigrateMsg;
01285 msg->level = currentLevel;
01286 msg->n_moves = migrate_count;
01287 for(i=0; i < migrate_count; i++) {
01288 MigrateInfo* item = migrateInfo[i];
01289 msg->moves[i] = *item;
01290 delete item;
01291 migrateInfo[i] = 0;
01292 }
01293 return msg;
01294 }
01295
01296 int HybridBaseLB::NeighborIndex(int pe, int atlevel)
01297 {
01298 int peslot = -1;
01299 for(int i=0; i < levelData[atlevel]->nChildren; i++) {
01300 if (pe == levelData[atlevel]->children[i]) {
01301 peslot = i;
01302 break;
01303 }
01304 }
01305 return peslot;
01306 }
01307
01308 void HybridBaseLB::printSummary(LDStats *stats, int count)
01309 {
01310 double stime = CkWallTimer();
01311 #if 1
01312 if (currentLevel == 1 && stats!=NULL) {
01313 LBInfo info(count);
01314 info.getInfo(stats, count, 1);
01315 double mLoad, mCpuLoad, totalLoad;
01316 info.getSummary(mLoad, mCpuLoad, totalLoad);
01317 int nmsgs, nbytes;
01318 stats->computeNonlocalComm(nmsgs, nbytes);
01319
01320 thisProxy[0].reportLBQulity(mLoad, mCpuLoad, totalLoad, nmsgs, nbytes/1024);
01321 }
01322 #endif
01323
01324 if (currentLevel == tree->numLevels()-2) {
01325 double mem = (1.0*useMem())/1024;
01326 thisProxy[0].reportLBMem(mem);
01327 }
01328 CkPrintf("[%d] Print Summary takes %f seconds. \n", CkMyPe(), CkWallTimer()-stime);
01329 }
01330
01331
01332 void HybridBaseLB::reportLBQulity(double mload, double mCpuLoad, double totalload, int nmsgs, double bytes)
01333 {
01334 static int pecount=0;
01335 CmiAssert(CkMyPe() == 0);
01336 if (mload > maxLoad) maxLoad = mload;
01337 if (mCpuLoad > maxCpuLoad) maxCpuLoad = mCpuLoad;
01338 totalLoad += totalload;
01339 maxCommCount += nmsgs;
01340 maxCommBytes += bytes;
01341 pecount++;
01342 if (pecount == tree->numNodes(1)) {
01343 CkPrintf("[%d] Load Summary: max (with comm): %f max (obj only): %f total: %f at step %d nonlocal: %d msgs, %.2fKB reported from %d PEs.\n", CkMyPe(), maxLoad, maxCpuLoad, totalLoad, step(), maxCommCount, maxCommBytes, pecount);
01344 maxLoad = 0.0;
01345 maxCpuLoad = 0.0;
01346 totalLoad = 0.0;
01347 maxCommCount = 0;
01348 maxCommBytes = 0.0;
01349 pecount = 0;
01350 }
01351 }
01352
01353
01354 void HybridBaseLB::reportLBMem(double mem)
01355 {
01356 static int pecount=0;
01357 CmiAssert(CkMyPe() == 0);
01358 if (mem > maxMem) maxMem = mem;
01359 pecount++;
01360 if (pecount == tree->numNodes(tree->numLevels()-2)) {
01361 CkPrintf("[%d] Load Summary: maxMem: %fKB reported at step %d from %d PEs.\n", CkMyPe(), maxMem, step(), pecount);
01362 maxMem = 0.0;
01363 pecount = 0;
01364 }
01365 }
01366
01367 int HybridBaseLB::useMem()
01368 {
01369 int i;
01370 int memused = 0;
01371 for (i=0; i<levelData.size(); i++)
01372 if (levelData[i]) memused+=levelData[i]->useMem();
01373 memused += newObjs.size() * sizeof(Location);
01374 return memused;
01375 }
01376
01377 #include "HybridBaseLB.def.h"
01378