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
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
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
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
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
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
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
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
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
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
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
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 {
00492
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
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
00608
00609
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 }
00637 }
00638 }
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