// pick objects to migrate "t" amount of work void HbmLB::ReceiveMigrationDelta(double t, int lblevel, int fromlevel) { #if CMK_LBDB_ON int i; int atlevel = fromlevel-1; LevelData *lData = levelData[atlevel]; if (atlevel != 0) { thisProxy.ReceiveMigrationDelta(t, lblevel, atlevel, lData->nChildren, lData->children); return; } // I am leave, find objects to migrate CkVec<int> migs; CkVec<LDObjData> &objData = myStats.objData; for (i=0; i<myStats.n_objs; i++) { LDObjData &oData = objData[i]; if (oData.wallTime < t) { migs.push_back(i); t -= oData.wallTime; if (t == 0.0) break; } } int nmigs = migs.size(); // send a message to int matchPE = CkMyPe() ^ (1<<(lblevel-1)); DEBUGF(("[%d] migrating %d objs to %d at lblevel %d! \n", CkMyPe(),nmigs,matchPE,lblevel)); thisProxy[matchPE].ReceiveMigrationCount(nmigs, lblevel); // migrate objects for (i=0; i<nmigs; i++) { int idx = migs[i]-i; LDObjData &oData = objData[idx]; CkVec<LDCommData> comms; collectCommData(idx, comms); thisProxy[matchPE].ObjMigrated(oData, comms.getVec(), comms.size()); theLbdb->Migrate(oData.handle, matchPE); // TODO modify LDStats DEBUGF(("myStats.removeObject: %d, %d, %d\n", migs[i], i, objData.size())); myStats.removeObject(idx); } #endif }
void HybridBaseLB::GetObjsToMigrate(int toPe, double load, LDStats *stats, int atlevel, CkVec<LDCommData>& comms, CkVec<LDObjData>& objs) { // TODO: sort max => low for (int obj=stats->n_objs-1; obj>=0; obj--) { LDObjData &objData = stats->objData[obj]; if (!objData.migratable) continue; if (objData.wallTime <= load) { if (_lb_args.debug()>2) { CkPrintf("[%d] send obj: %d to PE %d (load: %f).\n", CkMyPe(), obj, toPe, objData.wallTime); } objs.push_back(objData); // send comm data collectCommData(obj, comms, atlevel); load -= objData.wallTime; CreateMigrationOutObjs(atlevel, stats, obj); stats->removeObject(obj); if (load <= 0.0) break; } } }
// migrate only object LDStat in group // leaf nodes actually migrate objects void HybridBaseLB::ReceiveMigration(LBMigrateMsg *msg) { #if CMK_LBDB_ON #if CMK_MEM_CHECKPOINT CkResetInLdb(); #endif FindNeighbors(); int atlevel = msg->level - 1; DEBUGF(("[%d] ReceiveMigration\n", CkMyPe())); LevelData *lData = levelData[atlevel]; // only non NULL when level > 0 LDStats *statsData = lData->statsData; // do LDStats migration const int me = CkMyPe(); lData->migrates_expected = 0; for(int i=0; i < msg->n_moves; i++) { MigrateInfo& move = msg->moves[i]; // incoming if (move.from_pe != me && move.to_pe == me) { // I can not be the parent node DEBUGF(("[%d] expecting LDStats object from %d\n",me,move.from_pe)); // will receive a ObjData message lData->migrates_expected ++; } else if (move.from_pe == me) { // outgoing if (statsData) { // this is inner node // send objdata int obj; int found = 0; for (obj = 0; obj<statsData->n_objs; obj++) { if (move.obj.omID() == statsData->objData[obj].handle.omID() && move.obj.objID() == statsData->objData[obj].handle.objID()) { DEBUGF(("[%d] level: %d sending objData %d to %d. \n", CkMyPe(), atlevel, obj, move.to_pe)); found = 1; // TODO send comm data CkVec<LDCommData> comms; collectCommData(obj, comms, atlevel); if (move.to_pe != -1) { // this object migrates to another PE of the parent domain thisProxy[move.to_pe].ObjMigrated(statsData->objData[obj], comms.getVec(), comms.size(), atlevel); } lData->outObjs.push_back(MigrationRecord(move.obj, lData->children[statsData->from_proc[obj]], -1)); statsData->removeObject(obj); break; } } CmiAssert(found == 1); } else { // this is leave node if (move.to_pe == -1) { lData->outObjs.push_back(MigrationRecord(move.obj, CkMyPe(), -1)); } else { // migrate the object theLbdb->Migrate(move.obj,move.to_pe); } } } // end if } if (lData->migrationDone()) StatsDone(atlevel); #endif }