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