Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

AlgSeven.C

Go to the documentation of this file.
00001 
00007 /*****************************************************************************
00008  * $Source: /home/cvs/namd/cvsroot/namd2/src/AlgSeven.C,v $
00009  * $Author: bhatele $
00010  * $Date: 2007/11/01 17:39:53 $
00011  * $Revision: 1.55 $
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 == CmiFalse) 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
00137   //    << "Before assignment\n" << endi;
00138   //   printLoads();
00139 
00140   /*
00141   int numOverloaded = 0;
00142   for (int ip=0; ip<P; ip++) {
00143     if ( processors[ip].backgroundLoad > averageLoad ) ++numOverloaded;
00144   }
00145   if ( numOverloaded ) {
00146     iout << iWARN << numOverloaded
00147       << " processors are overloaded due to background load.\n" << endi;
00148   }
00149   */
00150               
00151   numAssigned = 0;
00152 
00153   //   for (int i=0; i<numPatches; i++)
00154   //     { std::cout << "(" << patches[i].Id << "," << patches[i].processor ;}
00155   overLoad = 1.2;
00156   for (int ic=0; ic<numComputes; ic++) {
00157 
00158     // place computes w/ patches on heavily background loaded nodes first
00159     // place pair before self, because self is more flexible
00160     c = (computeInfo *) computeBgPairHeap->deleteMax();
00161     if ( ! c ) c = (computeInfo *) computeBgSelfHeap->deleteMax();
00162     if ( ! c ) c = (computeInfo *) computePairHeap->deleteMax();
00163     if ( ! c ) c = (computeInfo *) computeSelfHeap->deleteMax();
00164 
00165     if (c->processor != -1) continue; // skip to the next compute;
00166 
00167     if ( ! c ) NAMD_bug("Alg7: computesHeap empty!");
00168     int i,j,k;
00169     for(i=0;i<3;i++)
00170       for(j=0;j<3;j++) {
00171         for(k=0;k<2;k++) {
00172           goodP[i][j][k]=0;
00173           poorP[i][j][k]=0;
00174         }
00175       }
00176 
00177     // first try for at least one proxy
00178     {
00179       Iterator nextProc;
00180       processorInfo *p;
00181 
00182       p = &processors[patches[c->patch1].processor];
00183       togrid(goodP, poorP, p, c);
00184 
00185       p = &processors[patches[c->patch2].processor];
00186       togrid(goodP, poorP, p, c);
00187 
00188       p = (processorInfo *)patches[c->patch1].
00189                             proxiesOn.iterator((Iterator *)&nextProc);
00190       while (p) {
00191         togrid(goodP, poorP, p, c);
00192         p = (processorInfo *)patches[c->patch1].
00193                             proxiesOn.next((Iterator*)&nextProc);
00194       }
00195 
00196       p = (processorInfo *)patches[c->patch2].
00197                             proxiesOn.iterator((Iterator *)&nextProc);
00198       while (p) {
00199         togrid(goodP, poorP, p, c);
00200         p = (processorInfo *)patches[c->patch2].
00201                             proxiesOn.next((Iterator*)&nextProc);
00202       }
00203       p = 0;
00204       // prefer to place compute with existing proxies over home patches
00205       if ((p = goodP[0][2][0])    // No home, two proxies
00206        || (p = goodP[1][1][0])    // One home, one proxy
00207        || (p = goodP[2][0][0])    // Two home, no proxies
00208        || (p = goodP[0][1][0])    // No home, one proxy
00209        || (p = goodP[1][0][0])    // One home, no proxies
00210        || (p = goodP[0][0][0])    // No home, no proxies
00211        || (p = goodP[0][1][1])    // No home, one proxy
00212        || (p = goodP[1][0][1])    // One home, no proxies
00213        || (p = goodP[0][0][1])    // No home, no proxies
00214          ) {
00215         assign(c,p); numAssigned++;
00216         continue;
00217       }
00218     }
00219 
00220     // no luck, do it the long way
00221 
00222     heapIterator nextProcessor;
00223     processorInfo *p = (processorInfo *) 
00224       pes->iterator((heapIterator *) &nextProcessor);
00225     while (p) {
00226       togrid(goodP, poorP, p, c);
00227       p = (processorInfo *) pes->next(&nextProcessor);
00228     }
00229 
00230     //    if (numAssigned >= 0) {  Else is commented out below
00231 
00232     p = 0;
00233       // prefer to place compute with existing proxies over home patches
00234       if ((p = goodP[0][2][0])    // No home, two proxies
00235        || (p = goodP[1][1][0])    // One home, one proxy
00236        || (p = goodP[2][0][0])    // Two home, no proxies
00237        || (p = goodP[0][1][0])    // No home, one proxy
00238        || (p = goodP[1][0][0])    // One home, no proxies
00239        || (p = goodP[0][0][0])    // No home, no proxies
00240        || (p = goodP[0][1][1])    // No home, one proxy
00241        || (p = goodP[1][0][1])    // One home, no proxies
00242        || (p = goodP[0][0][1])    // No home, no proxies
00243        ) {
00244       assign(c,p); numAssigned++;
00245    } else if (   // overloaded processors
00246           (p = poorP[0][2][0])    // No home, two proxies
00247        || (p = poorP[1][1][0])    // One home, one proxy
00248        || (p = poorP[2][0][0])    // Two home, no proxies
00249        || (p = poorP[0][1][0])    // No home, one proxy
00250        || (p = poorP[1][0][0])    // One home, no proxies
00251        || (p = poorP[0][0][0])    // No home, no proxies
00252        || (p = poorP[0][1][1])    // No home, one proxy
00253        || (p = poorP[1][0][1])    // One home, no proxies
00254        || (p = poorP[0][0][1])    // No home, no proxies
00255        ) {
00256       //iout << iWARN << "overload assign to " << p->Id << "\n" << endi;
00257       assign(c,p); numAssigned++;
00258     } else {
00259       NAMD_bug("*** Alg 7 No receiver found 1 ***");
00260       break;
00261     }
00262   }
00263 
00264   printLoads();
00265 
00266   // binary-search refinement procedure
00267   multirefine(1.05);
00268   printLoads();
00269 
00270 }
00271 

Generated on Sat Nov 7 04:07:46 2009 for NAMD by  doxygen 1.3.9.1