void ccs_getinfo(char *msg) { int nNode=CmiNumNodes(); int len=(1+nNode)*sizeof(ChMessageInt_t); ChMessageInt_t *table=(ChMessageInt_t *)malloc(len); int n; table[0]=ChMessageInt_new(nNode); for (n=0;n<nNode;n++) table[1+n]=ChMessageInt_new(CmiNodeSize(n)); CcsSendReply(len,(const char *)table); free(table); CmiFree(msg); }
void TorusLB::strategy() { int index; // compute the average load by (compute load + background load) / numPesAvailable computeAverage(); // two heaps of self and pair computes makeTwoHeaps(); const int beginGroup = processors[0].Id; const int endGroup = beginGroup + P; #define INGROUP(PROC) ((PROC) >= beginGroup && (PROC) < endGroup) computeInfo *c; processorInfo *p, *minp; Iterator nextP; overLoad = 1.2; for(int I=0; I<numComputes; I++) { c = (computeInfo *) computePairHeap->deleteMax(); if ( ! c ) c = (computeInfo *) computeSelfHeap->deleteMax(); if(c->processor != -1) continue; // go to the next compute if(!c) CkAbort("TorusLB: Compute Heap empty!\n"); for(int j=0; j<6; j++) { bestPe[j] = 0; goodPe[j] = 0; badPe[j] = 0; } // Look at pes which have the compute's patches // HYBRID check if processor is in local group #define SELECT_REALPE(X) if INGROUP((X)) { \ selectPes(&processors[(X) - beginGroup], c); \ } const int realPe1 = patches[c->patch1].processor; SELECT_REALPE(realPe1) const int realPe2 = patches[c->patch2].processor; if ( realPe2 != realPe1 ) { SELECT_REALPE(realPe2) } // Try the processors which have the patches' proxies p = (processorInfo *)(patches[c->patch1].proxiesOn.iterator((Iterator *)&nextP)); while(p) { // patch 1 if INGROUP(p->Id) selectPes(p, c); p = (processorInfo *)(patches[c->patch1].proxiesOn.next((Iterator *)&nextP)); } p = (processorInfo *)(patches[c->patch2].proxiesOn.iterator((Iterator *)&nextP)); while(p) { // patch 2 if INGROUP(p->Id) selectPes(p, c); p = (processorInfo *)(patches[c->patch2].proxiesOn.next((Iterator *)&nextP)); } // see if we have found a processor to place the compute on p = 0; if((p = bestPe[5]) #if USE_TOPOMAP || (p = goodPe[5]) #endif || (p = bestPe[4]) #if USE_TOPOMAP || (p = goodPe[4]) #endif || (p = bestPe[3]) #if USE_TOPOMAP || (p = goodPe[3]) #endif || (p = bestPe[1]) #if USE_TOPOMAP || (p = goodPe[1]) #endif || (p = bestPe[2]) #if USE_TOPOMAP || (p = goodPe[2]) #endif || (p = bestPe[0]) #if USE_TOPOMAP || (p = goodPe[0]) #endif ) { assign(c, p); continue; } // Try all pes on the nodes of the home patches if ( CmiNumNodes() > 1 ) { // else not useful double minLoad = overLoad * averageLoad; minp = 0; int realNode1 = CmiNodeOf(realPe1); int nodeSize = CmiNodeSize(realNode1); if ( nodeSize > 1 ) { // else did it already int firstpe = CmiNodeFirst(realNode1); for ( int rpe = firstpe; rpe < firstpe+nodeSize; ++rpe ) { if INGROUP(rpe) { p = &processors[rpe - beginGroup]; if ( p->available && ( p->load + c->load < minLoad ) ) { minLoad = p->load + c->load; minp = p; } } } } if ( realPe2 != realPe1 ) { int realNode2 = CmiNodeOf(realPe2); if ( realNode2 != realNode1 ) { // else did it already nodeSize = CmiNodeSize(realNode2); if ( nodeSize > 1 ) { int firstpe = CmiNodeFirst(realNode2); for ( int rpe = firstpe; rpe < firstpe+nodeSize; ++rpe ) { if INGROUP(rpe) { p = &processors[rpe - beginGroup]; if ( p->available && ( p->load + c->load < minLoad ) ) { minLoad = p->load + c->load; minp = p; } } } }