AlgSeven.C

Go to the documentation of this file.
00001 
00007 /*****************************************************************************
00008  * $Source: /home/cvs/namd/cvsroot/namd2/src/AlgSeven.C,v $
00009  * $Author: jim $
00010  * $Date: 2013/06/07 22:34:36 $
00011  * $Revision: 1.60 $
00012  *****************************************************************************/
00013 
00014 #include "common.h"
00015 #include "InfoStream.h"
00016 #include "Node.h"
00017 #include "Alg7.h"
00018 
00019 #define TINYLOAD 0.0005
00020 
00021 Alg7::Alg7(computeInfo *computeArray, patchInfo *patchArray, 
00022            processorInfo *processorArray, int nComps, 
00023            int nPatches, int nPes) :
00024   Rebalancer(computeArray, patchArray, 
00025              processorArray, nComps, 
00026              nPatches, nPes)
00027 {
00028 strategyName = "Alg7";
00029 strategy();
00030 }
00031 
00032 extern int isPmeProcessor(int);
00033 
00034 void Alg7::togrid(processorInfo* goodP[3][3][2], processorInfo* poorP[3][3][2],
00035                         processorInfo *p, computeInfo *c) {
00036       if(p->available == false) return;
00037 
00038       int nPatches, nProxies, badForComm;
00039       numAvailable(c,p,&nPatches,&nProxies,&badForComm);
00040 
00041       if (c->load + p->load < overLoad*averageLoad) {
00042         processorInfo* &altp = goodP[nPatches][nProxies][badForComm];   
00043 
00044 #if USE_TOPOMAP 
00045         if(!altp)
00046           altp = p;
00047         else {
00048           //Find processors that are patch neighbors on the BGL torus
00049           int neighbor = 0, neighbor_alt = 0;
00050           
00051           /*
00052             if((tmgr->isNeighbor(altp->Id, patches[c->patch1].processor) ||
00053             tmgr->isNeighbor(altp->Id, patches[c->patch2].processor)))
00054             neighbor_alt = 1;
00055             
00056             if(tmgr->isNeighbor(p->Id, patches[c->patch1].processor) ||
00057             tmgr->isNeighbor(p->Id, patches[c->patch2].processor))
00058             neighbor = 1;
00059           */
00060           
00061           if(tmgr.areNeighbors(altp->Id, patches[c->patch1].processor,
00062                                     patches[c->patch2].processor, 4))
00063             neighbor_alt = 1;
00064           
00065           if(tmgr.areNeighbors(p->Id, patches[c->patch1].processor, 
00066                                     patches[c->patch2].processor, 4))
00067             neighbor = 1;
00068           
00069           if(neighbor_alt == 1 && neighbor == 1) {
00070             //Both are neighbors, only replace if lighter
00071             if (p->load < altp->load ) {
00072               altp = p;
00073             }
00074           }
00075           else if(neighbor_alt == 0 && neighbor == 1)
00076             //Previous was not a neighbor, kick him out
00077             altp = p;
00078           else if(neighbor_alt == 1 && neighbor == 0)
00079             ;      //Give preference to good neighbors
00080           else {
00081             //Both not neighbors, choose nearby node to minimize hop bytes
00082             /*
00083               if (!altp || p->load < altp->load ) {
00084               altp = p;
00085               }
00086             */
00087 
00088             int alt_dist = 0, dist = 0;     
00089             int ax,ay,az, x,y,z, p1x,p1y,p1z, p2x,p2y,p2z;
00090             
00091             tmgr.rankToCoordinates(altp->Id, ax,ay,az);
00092             tmgr.rankToCoordinates(p->Id, x,y,z);
00093             tmgr.rankToCoordinates(patches[c->patch1].processor, p1x, p1y, p1z);
00094             tmgr.rankToCoordinates(patches[c->patch2].processor, p2x, p2y, p2z);
00095  
00096             alt_dist = abs(p1x - ax) + abs(p2x - ax) +
00097               abs(p1y - ay) + abs(p1z - az) +
00098               abs(p2y - ay) + abs(p2z - az);
00099             
00100             dist = abs(p1x - x) + abs(p2x - x) +
00101               abs(p1y - y) + abs(p1z - z) +
00102               abs(p2y - y) + abs(p2z - z);
00103             
00104             if(alt_dist > dist)
00105               altp = p;   
00106           }
00107         }
00108 #else 
00109         if (!altp || p->load < altp->load ) {   
00110           altp = p;
00111         }
00112 #endif    
00113       }
00114 
00115       {
00116         processorInfo* &altp = poorP[nPatches][nProxies][badForComm];
00117         if (!altp || p->load < altp->load ) {
00118           altp = p;
00119         }
00120       }
00121 }
00122 
00123 void Alg7::strategy()
00124 {
00125   // double bestSize0, bestSize1, bestSize2;
00126   computeInfo *c;
00127   int numAssigned;
00128   processorInfo* goodP[3][3][2];  // goodP[# of real patches][# of proxies]
00129   processorInfo* poorP[3][3][2];  // fallback option
00130 
00131   double startTime = CmiWallTimer();
00132 
00133   // iout << iINFO << "calling makeHeaps. \n";
00134   adjustBackgroundLoadAndComputeAverage();
00135   makeHeaps();
00136   // iout << iINFO << "Before assignment\n" << endi;
00137   // printLoads();
00138 
00139   /*
00140   int numOverloaded = 0;
00141   for (int ip=0; ip<P; ip++) {
00142     if ( processors[ip].backgroundLoad > averageLoad ) ++numOverloaded;
00143   }
00144   if ( numOverloaded ) {
00145     iout << iWARN << numOverloaded
00146       << " processors are overloaded due to background load.\n" << endi;
00147   }
00148   */
00149               
00150   numAssigned = 0;
00151 
00152   //   for (int i=0; i<numPatches; i++)
00153   //     { std::cout << "(" << patches[i].Id << "," << patches[i].processor ;}
00154   overLoad = 1.2;
00155   for (int ic=0; ic<numComputes; ic++) {
00156 
00157     // place computes w/ patches on heavily background loaded nodes first
00158     // place pair before self, because self is more flexible
00159     c = (computeInfo *) computeBgPairHeap->deleteMax();
00160     if ( ! c ) c = (computeInfo *) computeBgSelfHeap->deleteMax();
00161     if ( ! c ) c = (computeInfo *) computePairHeap->deleteMax();
00162     if ( ! c ) c = (computeInfo *) computeSelfHeap->deleteMax();
00163 
00164     if (c->processor != -1) continue; // skip to the next compute;
00165 
00166     if ( ! c ) NAMD_bug("Alg7: computesHeap empty!");
00167     int i,j,k;
00168     for(i=0;i<3;i++)
00169       for(j=0;j<3;j++) {
00170         for(k=0;k<2;k++) {
00171           goodP[i][j][k]=0;
00172           poorP[i][j][k]=0;
00173         }
00174       }
00175 
00176     // first try for at least one proxy
00177     {
00178       Iterator nextProc;
00179       processorInfo *p;
00180 
00181       p = &processors[patches[c->patch1].processor];
00182       togrid(goodP, poorP, p, c);
00183 
00184       p = &processors[patches[c->patch2].processor];
00185       togrid(goodP, poorP, p, c);
00186 
00187       p = (processorInfo *)patches[c->patch1].
00188                             proxiesOn.iterator((Iterator *)&nextProc);
00189       while (p) {
00190         togrid(goodP, poorP, p, c);
00191         p = (processorInfo *)patches[c->patch1].
00192                             proxiesOn.next((Iterator*)&nextProc);
00193       }
00194 
00195       p = (processorInfo *)patches[c->patch2].
00196                             proxiesOn.iterator((Iterator *)&nextProc);
00197       while (p) {
00198         togrid(goodP, poorP, p, c);
00199         p = (processorInfo *)patches[c->patch2].
00200                             proxiesOn.next((Iterator*)&nextProc);
00201       }
00202       p = 0;
00203       // prefer to place compute with existing proxies over home patches
00204       if ((p = goodP[0][2][0])    // No home, two proxies
00205        || (p = goodP[1][1][0])    // One home, one proxy
00206        || (p = goodP[2][0][0])    // Two home, no proxies
00207        || (p = goodP[0][1][0])    // No home, one proxy
00208        || (p = goodP[1][0][0])    // One home, no proxies
00209        || (p = goodP[0][0][0])    // No home, no proxies
00210        || (p = goodP[0][1][1])    // No home, one proxy
00211        || (p = goodP[1][0][1])    // One home, no proxies
00212        || (p = goodP[0][0][1])    // No home, no proxies
00213          ) {
00214         assign(c,p); numAssigned++;
00215         continue;
00216       }
00217     }
00218 
00219     // no luck, do it the long way
00220 
00221     heapIterator nextProcessor;
00222     processorInfo *p = (processorInfo *) 
00223       pes->iterator((heapIterator *) &nextProcessor);
00224     while (p) {
00225       togrid(goodP, poorP, p, c);
00226       p = (processorInfo *) pes->next(&nextProcessor);
00227     }
00228 
00229     //    if (numAssigned >= 0) {  Else is commented out below
00230 
00231     p = 0;
00232       // prefer to place compute with existing proxies over home patches
00233       if ((p = goodP[0][2][0])    // No home, two proxies
00234        || (p = goodP[1][1][0])    // One home, one proxy
00235        || (p = goodP[2][0][0])    // Two home, no proxies
00236        || (p = goodP[0][1][0])    // No home, one proxy
00237        || (p = goodP[1][0][0])    // One home, no proxies
00238        || (p = goodP[0][0][0])    // No home, no proxies
00239        || (p = goodP[0][1][1])    // No home, one proxy
00240        || (p = goodP[1][0][1])    // One home, no proxies
00241        || (p = goodP[0][0][1])    // No home, no proxies
00242        ) {
00243       assign(c,p); numAssigned++;
00244    } else if (   // overloaded processors
00245           (p = poorP[0][2][0])    // No home, two proxies
00246        || (p = poorP[1][1][0])    // One home, one proxy
00247        || (p = poorP[2][0][0])    // Two home, no proxies
00248        || (p = poorP[0][1][0])    // No home, one proxy
00249        || (p = poorP[1][0][0])    // One home, no proxies
00250        || (p = poorP[0][0][0])    // No home, no proxies
00251        || (p = poorP[0][1][1])    // No home, one proxy
00252        || (p = poorP[1][0][1])    // One home, no proxies
00253        || (p = poorP[0][0][1])    // No home, no proxies
00254        ) {
00255       //iout << iWARN << "overload assign to " << p->Id << "\n" << endi;
00256       assign(c,p); numAssigned++;
00257     } else {
00258       NAMD_bug("*** Alg 7 No receiver found 1 ***");
00259       break;
00260     }
00261   }
00262 
00263   printLoads();
00264 
00265   if ( computeMax() <= origMaxLoad ) {
00266     // binary-search refinement procedure
00267     multirefine(1.05);
00268     printLoads();
00269   }
00270 
00271 }
00272 

Generated on Wed Nov 22 01:17:12 2017 for NAMD by  doxygen 1.4.7