void CentralLB::ReceiveStats(CkMarshalledCLBStatsMessage &msg) { #if CMK_LBDB_ON if (statsMsgsList == NULL) { statsMsgsList = new CLBStatsMsg*[CkNumPes()]; CmiAssert(statsMsgsList != NULL); for(int i=0; i < CkNumPes(); i++) statsMsgsList[i] = 0; } if (statsData == NULL) statsData = new LDStats; // loop through all CLBStatsMsg in the incoming msg int count = msg.getCount(); for (int num = 0; num < count; num++) { CLBStatsMsg *m = msg.getMessage(num); CmiAssert(m!=NULL); const int pe = m->from_pe; DEBUGF(("Stats msg received, %d %d %d %p step %d\n", pe,stats_msg_count,m->n_objs,m,step())); #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_)) /* * if(m->step < step()){ * //TODO: if a processor is redoing an old load balance step.. * //tell it that the step is done and that it should not perform any migrations * thisProxy[pe].ReceiveDummyMigration(); * }*/ #endif if(!CmiNodeAlive(pe)){ DEBUGF(("[%d] ReceiveStats called from invalidProcessor %d\n",CkMyPe(),pe)); continue; } if (m->avail_vector!=NULL) { LBDatabaseObj()->set_avail_vector(m->avail_vector, m->next_lb); } if (statsMsgsList[pe] != 0) { CkPrintf("*** Unexpected CLBStatsMsg in ReceiveStats from PE %d ***\n", pe); } else { statsMsgsList[pe] = m; #if USE_REDUCTION depositData(m); #else // store per processor data right away struct ProcStats &procStat = statsData->procs[pe]; procStat.pe = pe; procStat.total_walltime = m->total_walltime; procStat.idletime = m->idletime; procStat.bg_walltime = m->bg_walltime; #if CMK_LB_CPUTIMER procStat.total_cputime = m->total_cputime; procStat.bg_cputime = m->bg_cputime; #endif procStat.pe_speed = m->pe_speed; //procStat.utilization = 1.0; procStat.available = CmiTrue; procStat.n_objs = m->n_objs; statsData->n_objs += m->n_objs; statsData->n_comm += m->n_comm; #endif #if defined(TEMP_LDB) procStat.pe_temp=m->pe_temp; procStat.pe_speed=m->pe_speed; #endif stats_msg_count++; } } // end of for const int clients = CkNumValidPes(); DEBUGF(("THIS POINT count = %d, clients = %d\n",stats_msg_count,clients)); if (stats_msg_count == clients) { DEBUGF(("[%d] All stats messages received \n",CmiMyPe())); statsData->nprocs() = stats_msg_count; thisProxy[CkMyPe()].LoadBalance(); } #endif }
static void _exitHandler(envelope *env) { DEBUGF(("exitHandler called on %d msgtype: %d\n", CkMyPe(), env->getMsgtype())); switch(env->getMsgtype()) { case StartExitMsg: CkAssert(CkMyPe()==0); if (!_CkExitFnVec.isEmpty()) { CkExitFn fn = _CkExitFnVec.deq(); fn(); break; } // else goto next case ExitMsg: CkAssert(CkMyPe()==0); if(_exitStarted) { CmiFree(env); return; } _exitStarted = 1; CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler); CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler); env->setMsgtype(ReqStatMsg); env->setSrcPe(CkMyPe()); // if exit in ring, instead of broadcasting, send in ring if (_ringexit){ DEBUGF(("[%d] Ring Exit \n",CkMyPe())); const int stride = CkNumPes()/_ringtoken; int pe = 0; while (pe<CkNumPes()) { CmiSyncSend(pe, env->getTotalsize(), (char *)env); pe += stride; } CmiFree(env); }else{ CmiSyncBroadcastAllAndFree(env->getTotalsize(), (char *)env); } break; case ReqStatMsg: #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_)) _messageLoggingExit(); #endif DEBUGF(("ReqStatMsg on %d\n", CkMyPe())); CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler); CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler); /*FAULT_EVAC*/ if(CmiNodeAlive(CkMyPe())){ #if CMK_WITH_STATS _sendStats(); #endif _mainDone = 1; // This is needed because the destructors for // readonly variables will be called when the program // exits. If the destructor is called while _mainDone // is 0, it will assume that the readonly variable was // declared locally. On all processors other than 0, // _mainDone is never set to 1 before the program exits. #if CMK_TRACE_ENABLED if (_ringexit) traceClose(); #endif } if (_ringexit) { int stride = CkNumPes()/_ringtoken; int pe = CkMyPe()+1; if (pe < CkNumPes() && pe % stride != 0) CmiSyncSendAndFree(pe, env->getTotalsize(), (char *)env); else CmiFree(env); } else CmiFree(env); //everyone exits here - there may be issues with leftover messages in the queue #if CMK_WITH_STATS if(CkMyPe()) #endif { DEBUGF(("[%d] Calling converse exit \n",CkMyPe())); ConverseExit(); if(CharmLibInterOperate) CpvAccess(interopExitFlag) = 1; } break; #if CMK_WITH_STATS case StatMsg: CkAssert(CkMyPe()==0); _allStats[env->getSrcPe()] = (Stats*) EnvToUsr(env); _numStatsRecd++; DEBUGF(("StatMsg on %d with %d\n", CkMyPe(), _numStatsRecd)); /*FAULT_EVAC*/ if(_numStatsRecd==CkNumValidPes()) { _printStats(); DEBUGF(("[%d] Calling converse exit \n",CkMyPe())); ConverseExit(); if(CharmLibInterOperate) CpvAccess(interopExitFlag) = 1; } break; #endif default: CmiAbort("Internal Error(_exitHandler): Unknown-msg-type. Contact Developers.\n"); } }