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

Generated on Thu Sep 21 01:17:14 2017 for NAMD by  doxygen 1.4.7