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

PatchMap.C

Go to the documentation of this file.
00001 
00007 #include <stddef.h>
00008 #if !defined(WIN32) || defined(__CYGWIN__)
00009 #include <unistd.h>
00010 #endif
00011 #include <stdio.h>
00012 
00013 #include "InfoStream.h"
00014 #include "ObjectArena.h"
00015 #include "PatchMgr.h"
00016 #include "PatchMap.inl"
00017 #include "Patch.h"
00018 #include "Lattice.h"
00019 #include "HomePatchList.h"
00020 #include "AtomMap.h"
00021 #include "memusage.h"
00022 //#define DEBUGM
00023 #define MIN_DEBUG_LEVEL 5
00024 #include "Debug.h"
00025 
00026 int *PatchMap::nPatchesOnNode = 0;
00027 PatchMap::PatchData *PatchMap::patchData = 0;
00028 ObjectArena<ComputeID> *PatchMap::computeIdArena = 0;
00029 
00030 // Safe singleton creation
00031 PatchMap *PatchMap::Instance() {
00032   if (CkpvAccess(PatchMap_instance) == 0) {
00033      CkpvAccess(PatchMap_instance) = new PatchMap;
00034   }
00035   return(CkpvAccess(PatchMap_instance));
00036 }
00037 
00038 PatchMap::PatchMap(void)
00039 {
00040   nPatches = 0;
00041   nNodesWithPatches = 0;
00042   int npes = CkNumPes();
00043   if ( ! CkMyRank() ) {
00044     nPatchesOnNode = new int[npes];
00045     memset(nPatchesOnNode,0,npes*sizeof(int));
00046     patchData = NULL;
00047     computeIdArena = NULL;
00048   }
00049   patchBounds_a = 0;
00050   patchBounds_b = 0;
00051   patchBounds_c = 0;
00052   myPatch = 0;
00053   myHomePatch = 0;
00054 
00055   aDim = bDim = cDim = 0;
00056   aAway = bAway = cAway = 1;
00057   aPeriodic = bPeriodic = cPeriodic = 0;
00058   aMaxIndex = bMaxIndex = cMaxIndex = 0;
00059 }
00060 
00061 int PatchMap::sizeGrid(ScaledPosition xmin, ScaledPosition xmax,
00062                                 const Lattice &lattice, BigReal patchSize,
00063                                 double maxNumPatches, int staticAtomAssignment,
00064                                 int asplit, int bsplit, int csplit)
00065 {
00066   aPeriodic = lattice.a_p();
00067   bPeriodic = lattice.b_p();
00068   cPeriodic = lattice.c_p();
00069 
00070   aAway = asplit;
00071   bAway = bsplit;
00072   cAway = csplit;
00073 
00074   int minNumPatches = 1;
00075   if ( aPeriodic ) minNumPatches *= aAway;
00076   if ( bPeriodic ) minNumPatches *= bAway;
00077   if ( cPeriodic ) minNumPatches *= cAway;
00078   if ( maxNumPatches < minNumPatches ) maxNumPatches = minNumPatches;
00079 
00080   if ( aPeriodic ) {
00081     BigReal sysDim = lattice.a_r().unit() * lattice.a();
00082     aDim = (int)(sysDim * aAway / patchSize);
00083   } else {
00084     BigReal sysDim = xmax.x - xmin.x;
00085     aDim = (int)(sysDim * aAway / patchSize);
00086     if ((aDim * patchSize) < (sysDim * aAway)) aDim++;
00087     if ( aDim < aAway + 1 ) aDim = aAway + 1;
00088   }
00089 
00090   if ( bPeriodic ) {
00091     BigReal sysDim = lattice.b_r().unit() * lattice.b();
00092     bDim = (int)(sysDim * bAway / patchSize);
00093   } else {
00094     BigReal sysDim = xmax.y - xmin.y;
00095     bDim = (int)(sysDim * bAway / patchSize);
00096     if ((bDim * patchSize) < (sysDim * bAway)) bDim++;
00097     if ( bDim < bAway + 1 ) bDim = bAway + 1;
00098   }
00099 
00100   if ( cPeriodic ) {
00101     BigReal sysDim = lattice.c_r().unit() * lattice.c();
00102     cDim = (int)(sysDim * cAway / patchSize);
00103   } else {
00104     BigReal sysDim = xmax.z - xmin.z;
00105     cDim = (int)(sysDim * cAway / patchSize);
00106     if ((cDim * patchSize) < (sysDim * cAway)) cDim++;
00107     if ( cDim < cAway + 1 ) cDim = cAway + 1;
00108   }
00109 
00110   if ( aDim < 0 || bDim < 0 || cDim < 0 ) {
00111     NAMD_die("Bug in PatchMap::sizeGrid - negative grid dimension.");
00112   }
00113 
00114   if ( staticAtomAssignment ) {
00115     if ( aPeriodic || bPeriodic || cPeriodic )
00116       NAMD_die("Static atom assignment is incompatible with periodic boundary conditions.");
00117     aDim = aAway + 1;
00118     bDim = bAway + 1;
00119     cDim = cAway + 1;
00120   }
00121 
00122   const int amin = (aPeriodic ? aAway : 1);
00123   const int bmin = (bPeriodic ? bAway : 1);
00124   const int cmin = (cPeriodic ? cAway : 1);
00125 
00126   // CkPrintf("searching %d-away %d-away %d-away max %d\n",aAway,bAway,cAway,(int)maxNumPatches);
00127 
00128   if ( aDim < amin ) aDim = amin;
00129   if ( bDim < bmin ) bDim = bmin;
00130   if ( cDim < cmin ) cDim = cmin;
00131 
00132   if ( maxNumPatches > aDim*bDim*cDim ) {
00133     maxNumPatches = aDim*bDim*cDim;
00134   }
00135 
00136   int abest = amin;
00137   int bbest = bmin;
00138   int cbest = cmin;
00139   int cdim = maxNumPatches;
00140   cdim /= aDim;  cdim /= bDim;
00141   if ( cdim < cmin ) cdim = cmin;
00142   for ( ; cdim <= cDim; ++cdim ) {
00143     int bdim = maxNumPatches;
00144     bdim /= aDim;  bdim /= cdim;
00145     if ( bdim < bmin ) bdim = bmin;
00146     for ( ; bdim <= bDim; ++bdim ) {
00147       int adim = maxNumPatches;
00148       adim /= bdim;  adim /= cdim;
00149       if ( adim < amin ) adim = amin;
00150       for ( ; adim <= aDim; ++adim ) {
00151         if ( adim*bdim*cdim > maxNumPatches ) break;
00152         // CkPrintf("testing %d * %d * %d == %d\n",adim,bdim,cdim,adim*bdim*cdim);
00153         if ( adim*bdim*cdim > abest*bbest*cbest ) {
00154           abest = adim;  bbest = bdim;  cbest = cdim;
00155         }
00156         if ( abest*bbest*cbest == maxNumPatches ) break;
00157       }
00158       if ( abest*bbest*cbest == maxNumPatches ) break;
00159     }
00160     if ( abest*bbest*cbest == maxNumPatches ) break;
00161   }
00162   aDim = abest;
00163   bDim = bbest;
00164   cDim = cbest;
00165 
00166   // CkPrintf("found %d * %d * %d == %d\n",aDim,bDim,cDim,aDim*bDim*cDim);
00167   return aDim*bDim*cDim;
00168 }
00169 
00170 void PatchMap::makePatches(ScaledPosition xmin, ScaledPosition xmax,
00171                                 const Lattice &lattice, BigReal patchSize,
00172                                 double maxNumPatches, int staticAtomAssignment,
00173                                 int asplit, int bsplit, int csplit)
00174 {
00175   sizeGrid(xmin,xmax,lattice,patchSize,maxNumPatches,staticAtomAssignment,asplit,bsplit,csplit);
00176 
00177   iout << iINFO << "PATCH GRID IS ";
00178   iout << aDim;
00179   if ( aPeriodic ) iout << " (PERIODIC)";
00180   iout << " BY ";
00181   iout << bDim;
00182   if ( bPeriodic ) iout << " (PERIODIC)";
00183   iout << " BY ";
00184   iout << cDim;
00185   if ( cPeriodic ) iout << " (PERIODIC)";
00186   iout << "\n";
00187   iout << iINFO << "PATCH GRID IS ";
00188   iout << aAway << "-AWAY BY ";
00189   iout << bAway << "-AWAY BY ";
00190   iout << cAway << "-AWAY\n";
00191   iout << endi;
00192 
00193   aMaxIndex = ( ! aPeriodic || aDim == 2 ) ? 10000 : aDim;
00194   bMaxIndex = ( ! bPeriodic || bDim == 2 ) ? 10000 : bDim;
00195   cMaxIndex = ( ! cPeriodic || cDim == 2 ) ? 10000 : cDim;
00196 
00197   aLength = aPeriodic ? 1.0 :
00198       ( aDim > aAway + 1 ? aDim * (patchSize / aAway) : xmax.x - xmin.x );
00199   bLength = bPeriodic ? 1.0 :
00200       ( bDim > bAway + 1 ? bDim * (patchSize / bAway) : xmax.y - xmin.y );
00201   cLength = cPeriodic ? 1.0 :
00202       ( cDim > cAway + 1 ? cDim * (patchSize / cAway) : xmax.z - xmin.z );
00203 
00204   aOrigin = aPeriodic ? -0.5 : 0.5 * (xmin.x + xmax.x - aLength);
00205   bOrigin = bPeriodic ? -0.5 : 0.5 * (xmin.y + xmax.y - bLength);
00206   cOrigin = cPeriodic ? -0.5 : 0.5 * (xmin.z + xmax.z - cLength);
00207 
00208   nPatches=aDim*bDim*cDim;
00209   patchData = new PatchData[nPatches];
00210 
00211   patchBounds_a = new BigReal[2*aDim+1];
00212   patchBounds_b = new BigReal[2*bDim+1];
00213   patchBounds_c = new BigReal[2*cDim+1];
00214   for ( int i=0; i<(2*aDim+1); ++i ) {
00215     patchBounds_a[i] = ((0.5*(double)i)/(double)aDim) * aLength + aOrigin;
00216   }
00217   for ( int i=0; i<(2*bDim+1); ++i ) {
00218     patchBounds_b[i] = ((0.5*(double)i)/(double)bDim) * bLength + bOrigin;
00219   }
00220   for ( int i=0; i<(2*cDim+1); ++i ) {
00221     patchBounds_c[i] = ((0.5*(double)i)/(double)cDim) * cLength + cOrigin;
00222   }
00223 
00224   for(int i=0; i<nPatches; ++i)
00225   {
00226     PatchData &p = patchData[i];
00227     p.basenode = -1;
00228     p.numCids = 0;
00229     p.aIndex = index_a(i);
00230     p.bIndex = index_b(i);
00231     p.cIndex = index_c(i);
00232 #ifdef MEM_OPT_VERSION
00233     p.numAtoms = 0;
00234     p.numFixedAtoms = 0;
00235 #endif
00236     p.numCids = 0;
00237     int max_computes = 30;
00238     p.cids = new int[max_computes];
00239     for ( int j = 0; j < max_computes; ++j ) p.cids[j] = -1;
00240     p.numCidsAllocated = max_computes;
00241   }
00242 
00243   if ( ! myPatch ) {
00244     myPatch = new Patch*[nPatches];
00245   }
00246   memset(myPatch,0,nPatches*sizeof(Patch*));
00247   if ( ! myHomePatch ) {
00248     myHomePatch = new HomePatch*[nPatches];
00249   }
00250   memset(myHomePatch,0,nPatches*sizeof(HomePatch*));
00251 }
00252 
00253 void PatchMap::checkMap(void)
00254 {
00255   int patchCount=0;
00256   for (int i=0; i<nPatches; i++) {
00257     if (myPatch[i]) {
00258       patchCount++;
00259       if ( myPatch[i]->getPatchID() != i) {
00260         DebugM(4, "patchID("<<myPatch[i]->getPatchID()
00261           <<") != patchID(" 
00262           <<i<<")\n");
00263       }
00264     }
00265   }
00266   DebugM(4, "Patch Count = " <<patchCount<<"\n");
00267 }
00268   
00269 
00270 PatchMap::~PatchMap(void)
00271 {
00272   if ( ! CkMyRank() ) {
00273     if (patchData && ! computeIdArena ) {
00274       for (int i=0; i<nPatches; i++) {
00275         delete [] patchData[i].cids;
00276       }
00277     }
00278     delete [] patchData;
00279     delete [] nPatchesOnNode;
00280     delete computeIdArena;
00281   }
00282   delete [] patchBounds_a;
00283   delete [] patchBounds_b;
00284   delete [] patchBounds_c;
00285   delete [] myPatch;
00286   delete [] myHomePatch;
00287 }
00288 
00289 #undef PACK
00290 #define PACK(type,data) { memcpy(b, &data,sizeof(type)); b += sizeof(type); }
00291 #define PACKN(type,data,cnt) { memcpy(b, data,(cnt)*sizeof(type)); b += (cnt)*sizeof(type); }
00292 
00293 int PatchMap::packSize(void)
00294 {
00295   int i, size = 0;
00296   size += 14 * sizeof(int) + 6 * sizeof(BigReal);
00297   size += (2*(aDim+bDim+cDim)+3) * sizeof(BigReal);
00298   size += CkNumPes() * sizeof(int);
00299   for(i=0;i<nPatches;++i)
00300   {
00301     size += sizeof(PatchData);
00302     size += patchData[i].numCidsAllocated * sizeof(ComputeID);
00303   }
00304   return size;
00305 }
00306 
00307 void PatchMap::pack (char *buffer)
00308 {
00309   DebugM(4,"Packing PatchMap on node " << CkMyPe() << std::endl);
00310   int i,j;
00311 
00312   // fill in the data
00313   char *b = buffer;
00314   PACK(int,nPatches);
00315   DebugM(3,"nPatches = " << nPatches << std::endl);
00316   PACK(int,aDim); PACK(int,bDim); PACK(int,cDim);
00317   PACK(int,aAway); PACK(int,bAway); PACK(int,cAway);
00318   PACK(int,aPeriodic); PACK(int,bPeriodic); PACK(int,cPeriodic);
00319   PACK(int,aMaxIndex); PACK(int,bMaxIndex); PACK(int,cMaxIndex);
00320   PACK(BigReal,aOrigin); PACK(BigReal,bOrigin); PACK(BigReal,cOrigin);
00321   PACK(BigReal,aLength); PACK(BigReal,bLength); PACK(BigReal,cLength);
00322   PACK(int,nNodesWithPatches);
00323   PACKN(BigReal,patchBounds_a,2*aDim+1);
00324   PACKN(BigReal,patchBounds_b,2*bDim+1);
00325   PACKN(BigReal,patchBounds_c,2*cDim+1);
00326   PACKN(int,nPatchesOnNode,CkNumPes());
00327   PACKN(PatchData,patchData,nPatches);
00328   for(i=0;i<nPatches;++i) {
00329     DebugM(3,"Packing Patch " << i << " is on node " << patchData[i].node << 
00330         " with " << patchData[i].numCids << " cids.\n");
00331     PACKN(ComputeID,patchData[i].cids,patchData[i].numCids);
00332   }
00333   //DebugM(3,buffer + size - b << " == 0 ?" << std::endl);
00334 }
00335 
00336 #undef UNPACK
00337 #define UNPACK(type,data) { memcpy(&data, b, sizeof(type)); b += sizeof(type); }
00338 #define UNPACKN(type,data,cnt) { memcpy(data, b, (cnt)*sizeof(type)); b += (cnt)*sizeof(type); }
00339 #define SKIPN(type,cnt) { b += (cnt)*sizeof(type); }
00340 
00341 void PatchMap::unpack (char *ptr)
00342 {
00343   DebugM(4,"Unpacking PatchMap on node " << CkMyPe() << std::endl);
00344 
00345   int i,j;
00346   char *b = (char*)ptr;
00347   {
00348     // defeat some over-zealous compilers
00349     int nPatches_tmp;
00350     UNPACK(int,nPatches_tmp);
00351     nPatches = nPatches_tmp;
00352   }
00353   DebugM(3,"nPatches = " << nPatches << std::endl);
00354 
00355   if ( ! myPatch ) {
00356     myPatch = new Patch*[nPatches];
00357   }
00358   memset(myPatch,0,nPatches*sizeof(Patch*));
00359   if ( ! myHomePatch ) {
00360     myHomePatch = new HomePatch*[nPatches];
00361   }
00362   memset(myHomePatch,0,nPatches*sizeof(HomePatch*));
00363 
00364   UNPACK(int,aDim); UNPACK(int,bDim); UNPACK(int,cDim);
00365   UNPACK(int,aAway); UNPACK(int,bAway); UNPACK(int,cAway);
00366   UNPACK(int,aPeriodic); UNPACK(int,bPeriodic); UNPACK(int,cPeriodic);
00367   UNPACK(int,aMaxIndex); UNPACK(int,bMaxIndex); UNPACK(int,cMaxIndex);
00368   UNPACK(BigReal,aOrigin); UNPACK(BigReal,bOrigin); UNPACK(BigReal,cOrigin);
00369   UNPACK(BigReal,aLength); UNPACK(BigReal,bLength); UNPACK(BigReal,cLength);
00370   UNPACK(int,nNodesWithPatches);
00371 
00372 
00373 //  CkPrintf("[%d] has bounds a %d b %d c %d npatches %d mem %d\n",CkMyPe(),aDim, bDim, cDim, nPatches, memusage_MB() );
00374 
00375   if ( ! patchBounds_a ) patchBounds_a = new BigReal[2*aDim+1];
00376   if ( ! patchBounds_b ) patchBounds_b = new BigReal[2*bDim+1];
00377   if ( ! patchBounds_c ) patchBounds_c = new BigReal[2*cDim+1];
00378   UNPACKN(BigReal,patchBounds_a,2*aDim+1);
00379   UNPACKN(BigReal,patchBounds_b,2*bDim+1);
00380   UNPACKN(BigReal,patchBounds_c,2*cDim+1);
00381  
00382   if ( CkMyRank() ) return;
00383 
00384   UNPACKN(int,nPatchesOnNode,CkNumPes());
00385 
00386   if ( ! patchData ) patchData = new PatchData[nPatches];
00387   else if ( ! computeIdArena ) {
00388     for(i=0;i<nPatches;++i) {
00389       delete [] patchData[i].cids;
00390     }
00391   }
00392   UNPACKN(PatchData,patchData,nPatches);
00393 
00394   delete computeIdArena;
00395   computeIdArena = new ObjectArena<ComputeID>;
00396   computeIdArena->setBlockSize(1024);
00397 
00398   for(i=0;i<nPatches;++i) {
00399     DebugM(3,"Unpacking Patch " << i << " is on node " << patchData[i].node << 
00400         " with " << patchData[i].numCids << " cids.\n");
00401     patchData[i].cids = computeIdArena->getNewArray(patchData[i].numCids);
00402     patchData[i].numCidsAllocated = patchData[i].numCids;
00403     UNPACKN(ComputeID,patchData[i].cids,patchData[i].numCids);
00404   }
00405 }
00406 
00407 //----------------------------------------------------------------------
00408 int PatchMap::numHomePatches(void)
00409 {
00410   return CkpvAccess(PatchMap_patchMgr)->homePatches.size();
00411 }
00412 
00413 //----------------------------------------------------------------------
00414 HomePatchList *PatchMap::homePatchList() {
00415   return &(CkpvAccess(PatchMap_patchMgr)->homePatches);
00416 }
00417 
00418 //----------------------------------------------------------------------
00419 void PatchMap::homePatchIDList(PatchIDList &pids) {
00420   pids.resize(0);
00421   int i;
00422   for ( i=0; i<nPatches; ++i ) {
00423     if ( patchData[i].node == CkMyPe() ) {
00424       pids.add(i);
00425     }
00426   }
00427 }
00428 
00429 //----------------------------------------------------------------------
00430 void PatchMap::basePatchIDList(int pe, PatchIDList &pids) {
00431   pids.resize(0);
00432   int i;
00433   for ( i=0; i<nPatches; ++i ) {
00434     if ( patchData[i].basenode == pe ) {
00435       pids.add(i);
00436     }
00437   }
00438 }
00439 
00440 //----------------------------------------------------------------------
00441 void PatchMap::assignNode(PatchID pid, NodeID node) {
00442   patchData[pid].node=node;
00443   if ( nPatchesOnNode[node] == 0 ) nNodesWithPatches += 1;
00444   nPatchesOnNode[node] += 1;
00445 }
00446 
00447 //----------------------------------------------------------------------
00448 void PatchMap::assignBaseNode(PatchID pid, NodeID node) {
00449   patchData[pid].basenode=node;
00450 }
00451 
00452 void PatchMap::assignBaseNode(PatchID pid) {
00453   
00454   int i = 1;
00455 
00456   NodeID node = patchData[pid].node;
00457 
00458   if ( CkNumPes() > 2*nPatches+1 ) {
00459 
00460     int newnode =  ( CkNumPes() + node - 1 ) % CkNumPes();    
00461     bool success = 0;
00462 
00463     while ( i < CkNumPes() && !success) {
00464       if ( nPatchesOnNode[newnode] == 0 )
00465         success = 1;
00466 
00467       //we know till pid, we have assigned all base nodes
00468       for (int count = 0; count < pid; count ++)
00469         if (patchData[count].basenode > 0 && patchData[count].basenode == newnode) {
00470           success = 0;
00471           break;
00472         }
00473           
00474       //no patch or a patche's base node on this newnode. this is a good node
00475       if (success) break;
00476 
00477       newnode = ( CkNumPes() + node - i - 1 ) % CkNumPes();
00478       i ++;
00479     }
00480     patchData[pid].basenode = newnode;
00481 
00482   } else {
00483     patchData[pid].basenode=node;
00484   }
00485 }
00486 
00487 //----------------------------------------------------------------------
00488 void PatchMap::newCid(int pid, int cid)
00489 {
00490   if (patchData[pid].numCids >= patchData[pid].numCidsAllocated)
00491   { // allocate more
00492 //    NAMD_die("PatchMap::newCid - not enough compute ID's allocated.");
00493     ComputeID *old = patchData[pid].cids;
00494     patchData[pid].numCidsAllocated += 10;
00495     patchData[pid].cids = new int[patchData[pid].numCidsAllocated];
00496     int i;
00497     for (i=0; i<patchData[pid].numCids; i++) 
00498         patchData[pid].cids[i] = old[i];
00499     for (i=patchData[pid].numCids; i<patchData[pid].numCidsAllocated; i++) 
00500         patchData[pid].cids[i] = -1;
00501     delete [] old;
00502   }
00503   patchData[pid].cids[patchData[pid].numCids]=cid;
00504   patchData[pid].numCids++;
00505 }
00506 
00507 //----------------------------------------------------------------------
00508 int PatchMap::oneAwayNeighbors(int pid, PatchID *neighbor_ids)
00509 {
00510   int xi, yi, zi;
00511   int xinc, yinc, zinc;
00512   int n=0;
00513 
00514   for(zinc=-1;zinc<=1;zinc++)
00515   {
00516     zi = patchData[pid].cIndex + zinc;
00517     if ((zi < 0) || (zi >= cDim))
00518       if ( ! cPeriodic ) continue;
00519     for(yinc=-1;yinc<=1;yinc++)
00520     {
00521       yi = patchData[pid].bIndex + yinc;
00522       if ((yi < 0) || (yi >= bDim))
00523         if ( ! bPeriodic ) continue;
00524       for(xinc=-1;xinc<=1;xinc++)
00525       {
00526         if ((xinc==0) && (yinc==0) && (zinc==0))
00527           continue;
00528 
00529         xi = patchData[pid].aIndex + xinc;
00530         if ((xi < 0) || (xi >= aDim))
00531           if ( ! aPeriodic ) continue;
00532 
00533         if (neighbor_ids)
00534           neighbor_ids[n]=this->pid(xi,yi,zi);
00535 #if 0
00536         if ( transform_ids )
00537         {
00538           int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
00539           int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
00540           int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
00541           transform_ids[n] = Lattice::index(xt,yt,zt);
00542         }
00543 #endif
00544         n++;
00545       }
00546     }
00547   }
00548   DebugM(3,"Patch " << pid << " has " << n << " first neighbors.\n");
00549   return n;
00550 }
00551 
00552 
00553 //----------------------------------------------------------------------
00554 // Only returns half of neighbors!
00555 int PatchMap::oneOrTwoAwayNeighbors(int pid, PatchID *neighbor_ids, PatchID *downstream_ids, int *transform_ids)
00556 {
00557   int xi, yi, zi;
00558   int xinc, yinc, zinc;
00559   int n=0;
00560   const int xs = patchData[pid].aIndex;
00561   const int ys = patchData[pid].bIndex;
00562   const int zs = patchData[pid].cIndex;
00563 
00564   for(zinc=0;zinc<=cAway;zinc++)
00565   {
00566     zi = zs + zinc;
00567     if ((zi < 0) || (zi >= cDim))
00568       if ( ! cPeriodic ) continue;
00569     for(yinc=(zinc>0 ? -bAway : 0);yinc<=bAway;yinc++)
00570     {
00571       yi = ys + yinc;
00572       if ((yi < 0) || (yi >= bDim))
00573         if ( ! bPeriodic ) continue;
00574       for(xinc=((zinc>0 || yinc>0) ? -aAway : 0);xinc<=aAway;xinc++)
00575       {
00576         if ((xinc==0) && (yinc==0) && (zinc==0))
00577           continue;
00578 
00579         xi = xs + xinc;
00580         if ((xi < 0) || (xi >= aDim))
00581           if ( ! aPeriodic ) continue;
00582 
00583         neighbor_ids[n] = this->pid(xi,yi,zi);
00584         if ( transform_ids )
00585         {
00586           int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
00587           int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
00588           int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
00589           transform_ids[n] = Lattice::index(xt,yt,zt);
00590         }
00591         if ( downstream_ids )
00592         {
00593           int xd = ( xi < xs ? xi : xs );
00594           int yd = ( yi < ys ? yi : ys );
00595           int zd = ( zi < zs ? zi : zs );
00596           downstream_ids[n] = this->pid(xd,yd,zd);
00597         }
00598         n++;
00599       }
00600     }
00601   }
00602   DebugM(3,"Patch " << pid << " has " << n << " second neighbors.\n");
00603   return n;
00604 }
00605 
00606 //----------------------------------------------------------------------
00607 // Return all patches in corresponding octet (2x2x2 block of patches)
00608 // regardless of periodic boundary conditions
00609 // Used for LCPO Computes
00610 int PatchMap::getPatchesInOctet(int pid, PatchID *pids, int *transform_ids)
00611 {
00612   int xi, yi, zi;
00613   int xinc, yinc, zinc;
00614   int n=0;
00615   const int xs = patchData[pid].aIndex;
00616   const int ys = patchData[pid].bIndex;
00617   const int zs = patchData[pid].cIndex;
00618 
00619   for(zinc=0; zinc<2; zinc++) {
00620     zi = zs + zinc;
00621     for(yinc=0; yinc<2; yinc++) {
00622       yi = ys + yinc;
00623       for(xinc=0; xinc<2; xinc++) {
00624               xi = xs + xinc;
00625         int aIndex = MODULO(xi,aDim);
00626         int bIndex = MODULO(yi,bDim);
00627         int cIndex = MODULO(zi,cDim);
00628         pids[n] = ((cIndex*bDim)+bIndex)*aDim + aIndex;
00629         if ( transform_ids ) {
00630                 int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
00631                 int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
00632                 int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
00633                 transform_ids[n] = Lattice::index(xt,yt,zt);
00634               }
00635               n++;
00636       } // for x
00637     } // for y
00638   } // for z
00639   DebugM(3,"Patch " << pid << " has " << n << " second neighbors.\n");
00640   return n;
00641 }
00642 
00643 
00644 //----------------------------------------------------------------------
00645 int PatchMap::upstreamNeighbors(int pid, PatchID *neighbor_ids)
00646 {
00647   int xi, yi, zi;
00648   int xinc, yinc, zinc;
00649   int n=0;
00650 
00651   for(zinc=0;zinc<=1;zinc++)
00652   {
00653     zi = patchData[pid].cIndex + zinc;
00654     if ((zi < 0) || (zi >= cDim))
00655       if ( ! cPeriodic ) continue;
00656     for(yinc=0;yinc<=1;yinc++)
00657     {
00658       yi = patchData[pid].bIndex + yinc;
00659       if ((yi < 0) || (yi >= bDim))
00660         if ( ! bPeriodic ) continue;
00661       for(xinc=0;xinc<=1;xinc++)
00662       {
00663         if ((xinc==0) && (yinc==0) && (zinc==0))
00664           continue;
00665 
00666         xi = patchData[pid].aIndex + xinc;
00667         if ((xi < 0) || (xi >= aDim))
00668           if ( ! aPeriodic ) continue;
00669 
00670         if (neighbor_ids)
00671           neighbor_ids[n]=this->pid(xi,yi,zi);
00672 #if 0
00673         if ( transform_ids )
00674         {
00675           int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
00676           int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
00677           int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
00678           transform_ids[n] = Lattice::index(xt,yt,zt);
00679         }
00680 #endif
00681         n++;
00682       }
00683     }
00684   }
00685   DebugM(3,"Patch " << pid << " has " << n << " upstream neighbors.\n");
00686   return n;
00687 }
00688 
00689 //----------------------------------------------------------------------
00690 int PatchMap::downstreamNeighbors(int pid, PatchID *neighbor_ids)
00691 {
00692   int xi, yi, zi;
00693   int xinc, yinc, zinc;
00694   int n=0;
00695 
00696   for(zinc=-1;zinc<=0;zinc++)
00697   {
00698     zi = patchData[pid].cIndex + zinc;
00699     if ((zi < 0) || (zi >= cDim))
00700       if ( ! cPeriodic ) continue;
00701     for(yinc=-1;yinc<=0;yinc++)
00702     {
00703       yi = patchData[pid].bIndex + yinc;
00704       if ((yi < 0) || (yi >= bDim))
00705         if ( ! bPeriodic ) continue;
00706       for(xinc=-1;xinc<=0;xinc++)
00707       {
00708         if ((xinc==0) && (yinc==0) && (zinc==0))
00709           continue;
00710 
00711         xi = patchData[pid].aIndex + xinc;
00712         if ((xi < 0) || (xi >= aDim))
00713           if ( ! aPeriodic ) continue;
00714 
00715         if (neighbor_ids)
00716           neighbor_ids[n]=this->pid(xi,yi,zi);
00717 #if 0
00718         if ( transform_ids )
00719         {
00720           int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
00721           int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
00722           int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
00723           transform_ids[n] = Lattice::index(xt,yt,zt);
00724         }
00725 #endif
00726         n++;
00727       }
00728     }
00729   }
00730   DebugM(3,"Patch " << pid << " has " << n << " upstream neighbors.\n");
00731   return n;
00732 }
00733 
00734 //----------------------------------------------------------------------
00735 void PatchMap::printPatchMap(void)
00736 {
00737   CkPrintf("---------------------------------------");
00738   CkPrintf("---------------------------------------\n");
00739 
00740   CkPrintf("nPatches = %d\n",nPatches);
00741   for(int i=0;i<nPatches;i++)
00742   {
00743     CkPrintf("Patch %d:\n",i);
00744     CkPrintf("  node = %d\n",patchData[i].node);
00745     CkPrintf("  xi,yi,zi = %d, %d, %d\n",
00746             patchData[i].aIndex,patchData[i].bIndex,patchData[i].cIndex);
00747     CkPrintf("  numCids = %d\n",patchData[i].numCids);
00748     CkPrintf("  numCidsAllocated = %d\n",patchData[i].numCidsAllocated);
00749     for(int j=0; j < patchData[i].numCids; j++)
00750     {
00751       CkPrintf(" %10d ",patchData[i].cids[j]);
00752       if (!((j+1) % 6))
00753         CkPrintf("\n");
00754     }
00755     CkPrintf("\n---------------------------------------");
00756     CkPrintf("---------------------------------------\n");
00757   }
00758 
00759 }
00760 
00761 //----------------------------------------------------------------------
00762 void PatchMap::registerPatch(PatchID pid, HomePatch *pptr) {
00763   registerPatch(pid,(Patch*)pptr);
00764   if (myHomePatch[pid] != 0) {
00765     iout << iPE << iERRORF 
00766       << "homePatchID("<<pid<<") is being re-registered!\n" << endi;
00767   }
00768   myHomePatch[pid] = pptr;
00769 }
00770 
00771 //----------------------------------------------------------------------
00772 void PatchMap::unregisterPatch(PatchID pid, HomePatch *pptr) {
00773   unregisterPatch(pid,(Patch*)pptr);
00774   if (pptr == myHomePatch[pid]) {
00775       DebugM(4, "UnregisterHomePatch("<<pid<<") at " << pptr << "\n");
00776       myHomePatch[pid] = NULL;
00777   }
00778 }
00779 
00780 //----------------------------------------------------------------------
00781 void PatchMap::registerPatch(PatchID pid, Patch *pptr)
00782 {
00783   if (myPatch[pid] != 0) {
00784     iout << iPE << iERRORF 
00785       << "patchID("<<pid<<") is being re-registered!\n" << endi;
00786   }
00787   myPatch[pid] = pptr;
00788 }
00789 
00790 //----------------------------------------------------------------------
00791 void PatchMap::unregisterPatch(PatchID pid, Patch *pptr)
00792 {
00793   if (pptr == myPatch[pid]) {
00794       DebugM(4, "UnregisterPatch("<<pid<<") at " << pptr << "\n");
00795       myPatch[pid] = NULL;
00796   }
00797 }
00798 

Generated on Fri May 25 04:07:16 2012 for NAMD by  doxygen 1.3.9.1