NAMD
PatchMap.C
Go to the documentation of this file.
1 
7 #include <stddef.h>
8 #if !defined(WIN32) || defined(__CYGWIN__)
9 #include <unistd.h>
10 #endif
11 #include <stdio.h>
12 
13 #include "InfoStream.h"
14 #include "ObjectArena.h"
15 #include "PatchMgr.h"
16 #include "PatchMap.inl"
17 #include "Patch.h"
18 #include "Lattice.h"
19 #include "HomePatchList.h"
20 #include "AtomMap.h"
21 #include "DataExchanger.h"
22 #include "memusage.h"
23 //#define DEBUGM
24 #define MIN_DEBUG_LEVEL 5
25 #include "Debug.h"
26 
27 int *PatchMap::nPatchesOnNode = 0;
28 PatchMap::PatchData *PatchMap::patchData = 0;
29 ObjectArena<ComputeID> *PatchMap::computeIdArena = 0;
30 
31 // Safe singleton creation
33  if (CkpvAccess(PatchMap_instance) == 0) {
34  CkpvAccess(PatchMap_instance) = new PatchMap;
35  }
36  return(CkpvAccess(PatchMap_instance));
37 }
38 
40 {
41  nPatches = 0;
42  nNodesWithPatches = 0;
43  int npes = CkNumPes();
44  if ( ! CkMyRank() ) {
45  nPatchesOnNode = new int[npes];
46  memset(nPatchesOnNode,0,npes*sizeof(int));
47  patchData = NULL;
48  computeIdArena = NULL;
49  }
50  patchBounds_a = 0;
51  patchBounds_b = 0;
52  patchBounds_c = 0;
53  myPatch = 0;
54  myHomePatch = 0;
55 
56  aDim = bDim = cDim = 0;
57  aAway = bAway = cAway = 1;
58  aPeriodic = bPeriodic = cPeriodic = 0;
59  aMaxIndex = bMaxIndex = cMaxIndex = 0;
60 }
61 
63  const Lattice &lattice, BigReal patchSize,
64  double maxNumPatches, int staticAtomAssignment,
65  int asplit, int bsplit, int csplit)
66 {
67  aPeriodic = lattice.a_p();
68  bPeriodic = lattice.b_p();
69  cPeriodic = lattice.c_p();
70 
71  aAway = asplit;
72  bAway = bsplit;
73  cAway = csplit;
74 
75  int minNumPatches = 1;
76  if ( aPeriodic ) minNumPatches *= aAway;
77  if ( bPeriodic ) minNumPatches *= bAway;
78  if ( cPeriodic ) minNumPatches *= cAway;
79  if ( maxNumPatches < minNumPatches ) maxNumPatches = minNumPatches;
80 
81  if ( aPeriodic ) {
82  BigReal sysDim = lattice.a_r().unit() * lattice.a();
83  aDim = (int)(sysDim * aAway / patchSize);
84  } else {
85  BigReal sysDim = xmax.x - xmin.x;
86  aDim = (int)(sysDim * aAway / patchSize);
87  if ((aDim * patchSize) < (sysDim * aAway)) aDim++;
88  if ( aDim < aAway + 1 ) aDim = aAway + 1;
89  }
90 
91  if ( bPeriodic ) {
92  BigReal sysDim = lattice.b_r().unit() * lattice.b();
93  bDim = (int)(sysDim * bAway / patchSize);
94  } else {
95  BigReal sysDim = xmax.y - xmin.y;
96  bDim = (int)(sysDim * bAway / patchSize);
97  if ((bDim * patchSize) < (sysDim * bAway)) bDim++;
98  if ( bDim < bAway + 1 ) bDim = bAway + 1;
99  }
100 
101  if ( cPeriodic ) {
102  BigReal sysDim = lattice.c_r().unit() * lattice.c();
103  cDim = (int)(sysDim * cAway / patchSize);
104  } else {
105  BigReal sysDim = xmax.z - xmin.z;
106  cDim = (int)(sysDim * cAway / patchSize);
107  if ((cDim * patchSize) < (sysDim * cAway)) cDim++;
108  if ( cDim < cAway + 1 ) cDim = cAway + 1;
109  }
110 
111  if ( aDim < 0 || bDim < 0 || cDim < 0 ) {
112  NAMD_die("Bug in PatchMap::sizeGrid - negative grid dimension.");
113  }
114 
115  if ( staticAtomAssignment ) {
116  if ( aPeriodic || bPeriodic || cPeriodic )
117  NAMD_die("Static atom assignment is incompatible with periodic boundary conditions.");
118  aDim = aAway + 1;
119  bDim = bAway + 1;
120  cDim = cAway + 1;
121  }
122 
123  const int amin = (aPeriodic ? aAway : 1);
124  const int bmin = (bPeriodic ? bAway : 1);
125  const int cmin = (cPeriodic ? cAway : 1);
126 
127  // CkPrintf("searching %d-away %d-away %d-away max %d\n",aAway,bAway,cAway,(int)maxNumPatches);
128 
129  if ( aDim < amin ) aDim = amin;
130  if ( bDim < bmin ) bDim = bmin;
131  if ( cDim < cmin ) cDim = cmin;
132 
133  if ( maxNumPatches > (double)aDim*bDim*cDim ) {
134  maxNumPatches = (double)aDim*bDim*cDim;
135  }
136 
137  int abest = amin;
138  int bbest = bmin;
139  int cbest = cmin;
140  int cdim = maxNumPatches;
141  cdim /= aDim; cdim /= bDim;
142  if ( cdim < cmin ) cdim = cmin;
143  for ( ; cdim <= cDim; ++cdim ) {
144  int bdim = maxNumPatches;
145  bdim /= aDim; bdim /= cdim;
146  if ( bdim < bmin ) bdim = bmin;
147  for ( ; bdim <= bDim; ++bdim ) {
148  int adim = maxNumPatches;
149  adim /= bdim; adim /= cdim;
150  if ( adim < amin ) adim = amin;
151  for ( ; adim <= aDim; ++adim ) {
152  if ( adim*bdim*cdim > maxNumPatches ) break;
153  // CkPrintf("testing %d * %d * %d == %d\n",adim,bdim,cdim,adim*bdim*cdim);
154  if ( adim*bdim*cdim > abest*bbest*cbest ) {
155  abest = adim; bbest = bdim; cbest = cdim;
156  }
157  if ( abest*bbest*cbest == maxNumPatches ) break;
158  }
159  if ( abest*bbest*cbest == maxNumPatches ) break;
160  }
161  if ( abest*bbest*cbest == maxNumPatches ) break;
162  }
163  aDim = abest;
164  bDim = bbest;
165  cDim = cbest;
166 
167  // CkPrintf("found %d * %d * %d == %d\n",aDim,bDim,cDim,aDim*bDim*cDim);
168  return aDim*bDim*cDim;
169 }
170 
172  const Lattice &lattice, BigReal patchSize,
173  double maxNumPatches, int staticAtomAssignment,
174  int replicaUniformPatchGrids, int lcpo,
175  int asplit, int bsplit, int csplit)
176 {
177  sizeGrid(xmin,xmax,lattice,patchSize,maxNumPatches,staticAtomAssignment,asplit,bsplit,csplit);
178 
179  if ( replicaUniformPatchGrids ) {
180  int oldpcount = aDim * bDim * cDim;
181  double dims[3];
182  dims[0] = aDim;
183  dims[1] = bDim;
184  dims[2] = cDim;
185  replica_min_double(dims,3);
186  aDim = dims[0];
187  bDim = dims[1];
188  cDim = dims[2];
189  int newpcount = aDim * bDim * cDim;
190  if ( newpcount > oldpcount ) {
191  NAMD_bug("replicaUniformPatchGrids increased patch count");
192  }
193  if ( newpcount < oldpcount ) {
194  iout << iINFO << "PATCH GRID REDUCED TO BE UNIFORM ACROSS REPLICAS\n";
195  }
196  }
197 
198  iout << iINFO << "PATCH GRID IS ";
199  iout << aDim;
200  if ( aPeriodic ) iout << " (PERIODIC)";
201  iout << " BY ";
202  iout << bDim;
203  if ( bPeriodic ) iout << " (PERIODIC)";
204  iout << " BY ";
205  iout << cDim;
206  if ( cPeriodic ) iout << " (PERIODIC)";
207  iout << "\n";
208  iout << iINFO << "PATCH GRID IS ";
209  iout << aAway << "-AWAY BY ";
210  iout << bAway << "-AWAY BY ";
211  iout << cAway << "-AWAY\n";
212  iout << endi;
213 
214  aMaxIndex = ( ! aPeriodic || aDim == 2 ) ? 10000 : aDim;
215  bMaxIndex = ( ! bPeriodic || bDim == 2 ) ? 10000 : bDim;
216  cMaxIndex = ( ! cPeriodic || cDim == 2 ) ? 10000 : cDim;
217 
218  aLength = aPeriodic ? 1.0 :
219  ( lcpo || aDim > aAway + 1 ? aDim * (patchSize / aAway) : xmax.x - xmin.x );
220  bLength = bPeriodic ? 1.0 :
221  ( lcpo || bDim > bAway + 1 ? bDim * (patchSize / bAway) : xmax.y - xmin.y );
222  cLength = cPeriodic ? 1.0 :
223  ( lcpo || cDim > cAway + 1 ? cDim * (patchSize / cAway) : xmax.z - xmin.z );
224 
225  aOrigin = aPeriodic ? -0.5 : 0.5 * (xmin.x + xmax.x - aLength);
226  bOrigin = bPeriodic ? -0.5 : 0.5 * (xmin.y + xmax.y - bLength);
227  cOrigin = cPeriodic ? -0.5 : 0.5 * (xmin.z + xmax.z - cLength);
228 
229  nPatches=aDim*bDim*cDim;
230  patchData = new PatchData[nPatches];
231 
232  patchBounds_a = new BigReal[2*aDim+1];
233  patchBounds_b = new BigReal[2*bDim+1];
234  patchBounds_c = new BigReal[2*cDim+1];
235  for ( int i=0; i<(2*aDim+1); ++i ) {
236  patchBounds_a[i] = ((0.5*(double)i)/(double)aDim) * aLength + aOrigin;
237  }
238  for ( int i=0; i<(2*bDim+1); ++i ) {
239  patchBounds_b[i] = ((0.5*(double)i)/(double)bDim) * bLength + bOrigin;
240  }
241  for ( int i=0; i<(2*cDim+1); ++i ) {
242  patchBounds_c[i] = ((0.5*(double)i)/(double)cDim) * cLength + cOrigin;
243  }
244 
245  for(int i=0; i<nPatches; ++i)
246  {
247  PatchData &p = patchData[i];
248  p.basenode = -1;
249  p.numCids = 0;
250  p.aIndex = index_a(i);
251  p.bIndex = index_b(i);
252  p.cIndex = index_c(i);
253 #ifdef MEM_OPT_VERSION
254  p.numAtoms = 0;
255  p.numFixedAtoms = 0;
256 #endif
257  p.numCids = 0;
258  int max_computes = 30;
259  p.cids = new int[max_computes];
260  for ( int j = 0; j < max_computes; ++j ) p.cids[j] = -1;
261  p.numCidsAllocated = max_computes;
262  }
263 
264  if ( ! myPatch ) {
265  myPatch = new Patch*[nPatches];
266  }
267  memset(myPatch,0,nPatches*sizeof(Patch*));
268  if ( ! myHomePatch ) {
269  myHomePatch = new HomePatch*[nPatches];
270  }
271  memset(myHomePatch,0,nPatches*sizeof(HomePatch*));
272 }
273 
275 {
276  int patchCount=0;
277  for (int i=0; i<nPatches; i++) {
278  if (myPatch[i]) {
279  patchCount++;
280  if ( myPatch[i]->getPatchID() != i) {
281  DebugM(4, "patchID("<<myPatch[i]->getPatchID()
282  <<") != patchID("
283  <<i<<")\n");
284  }
285  }
286  }
287  DebugM(4, "Patch Count = " <<patchCount<<"\n");
288 }
289 
290 
292 {
293  if ( ! CkMyRank() ) {
294  if (patchData && ! computeIdArena ) {
295  for (int i=0; i<nPatches; i++) {
296  delete [] patchData[i].cids;
297  }
298  }
299  delete [] patchData;
300  delete [] nPatchesOnNode;
301  delete computeIdArena;
302  }
303  delete [] patchBounds_a;
304  delete [] patchBounds_b;
305  delete [] patchBounds_c;
306  delete [] myPatch;
307  delete [] myHomePatch;
308 }
309 
310 #undef PACK
311 #define PACK(type,data) { memcpy(b, &data,sizeof(type)); b += sizeof(type); }
312 #define PACKN(type,data,cnt) { memcpy(b, data,(cnt)*sizeof(type)); b += (cnt)*sizeof(type); }
313 
315 {
316  int i, size = 0;
317  size += 14 * sizeof(int) + 6 * sizeof(BigReal);
318  size += (2*(aDim+bDim+cDim)+3) * sizeof(BigReal);
319  size += CkNumPes() * sizeof(int);
320  for(i=0;i<nPatches;++i)
321  {
322  size += sizeof(PatchData);
323  size += patchData[i].numCids * sizeof(ComputeID);
324  }
325  return size;
326 }
327 
328 void PatchMap::pack (char *buffer, int size)
329 {
330  DebugM(4,"Packing PatchMap on node " << CkMyPe() << std::endl);
331  int i,j;
332 
333  // fill in the data
334  char *b = buffer;
335  PACK(int,nPatches);
336  DebugM(3,"nPatches = " << nPatches << std::endl);
337  PACK(int,aDim); PACK(int,bDim); PACK(int,cDim);
338  PACK(int,aAway); PACK(int,bAway); PACK(int,cAway);
339  PACK(int,aPeriodic); PACK(int,bPeriodic); PACK(int,cPeriodic);
340  PACK(int,aMaxIndex); PACK(int,bMaxIndex); PACK(int,cMaxIndex);
341  PACK(BigReal,aOrigin); PACK(BigReal,bOrigin); PACK(BigReal,cOrigin);
342  PACK(BigReal,aLength); PACK(BigReal,bLength); PACK(BigReal,cLength);
343  PACK(int,nNodesWithPatches);
344  PACKN(BigReal,patchBounds_a,2*aDim+1);
345  PACKN(BigReal,patchBounds_b,2*bDim+1);
346  PACKN(BigReal,patchBounds_c,2*cDim+1);
347  PACKN(int,nPatchesOnNode,CkNumPes());
348  PACKN(PatchData,patchData,nPatches);
349  for(i=0;i<nPatches;++i) {
350  DebugM(3,"Packing Patch " << i << " is on node " << patchData[i].node <<
351  " with " << patchData[i].numCids << " cids.\n");
352  PACKN(ComputeID,patchData[i].cids,patchData[i].numCids);
353  }
354  if ( buffer + size != b ) {
355  NAMD_bug("PatchMap::pack does not match PatchMap::packSize");
356  }
357  //DebugM(3,buffer + size - b << " == 0 ?" << std::endl);
358 }
359 
360 #undef UNPACK
361 #define UNPACK(type,data) { memcpy(&data, b, sizeof(type)); b += sizeof(type); }
362 #define UNPACKN(type,data,cnt) { memcpy(data, b, (cnt)*sizeof(type)); b += (cnt)*sizeof(type); }
363 #define SKIPN(type,cnt) { b += (cnt)*sizeof(type); }
364 
365 void PatchMap::unpack (char *ptr)
366 {
367  DebugM(4,"Unpacking PatchMap on node " << CkMyPe() << std::endl);
368 
369  int i,j;
370  char *b = (char*)ptr;
371  {
372  // defeat some over-zealous compilers
373  int nPatches_tmp;
374  UNPACK(int,nPatches_tmp);
375  nPatches = nPatches_tmp;
376  }
377  DebugM(3,"nPatches = " << nPatches << std::endl);
378 
379  if ( ! myPatch ) {
380  myPatch = new Patch*[nPatches];
381  }
382  memset(myPatch,0,nPatches*sizeof(Patch*));
383  if ( ! myHomePatch ) {
384  myHomePatch = new HomePatch*[nPatches];
385  }
386  memset(myHomePatch,0,nPatches*sizeof(HomePatch*));
387 
388  UNPACK(int,aDim); UNPACK(int,bDim); UNPACK(int,cDim);
389  UNPACK(int,aAway); UNPACK(int,bAway); UNPACK(int,cAway);
390  UNPACK(int,aPeriodic); UNPACK(int,bPeriodic); UNPACK(int,cPeriodic);
391  UNPACK(int,aMaxIndex); UNPACK(int,bMaxIndex); UNPACK(int,cMaxIndex);
392  UNPACK(BigReal,aOrigin); UNPACK(BigReal,bOrigin); UNPACK(BigReal,cOrigin);
393  UNPACK(BigReal,aLength); UNPACK(BigReal,bLength); UNPACK(BigReal,cLength);
394  UNPACK(int,nNodesWithPatches);
395 
396 
397 // CkPrintf("[%d] has bounds a %d b %d c %d npatches %d mem %d\n",CkMyPe(),aDim, bDim, cDim, nPatches, memusage_MB() );
398 
399  if ( ! patchBounds_a ) patchBounds_a = new BigReal[2*aDim+1];
400  if ( ! patchBounds_b ) patchBounds_b = new BigReal[2*bDim+1];
401  if ( ! patchBounds_c ) patchBounds_c = new BigReal[2*cDim+1];
402  UNPACKN(BigReal,patchBounds_a,2*aDim+1);
403  UNPACKN(BigReal,patchBounds_b,2*bDim+1);
404  UNPACKN(BigReal,patchBounds_c,2*cDim+1);
405 
406  if ( CkMyRank() ) return;
407 
408  UNPACKN(int,nPatchesOnNode,CkNumPes());
409 
410  if ( ! patchData ) patchData = new PatchData[nPatches];
411  else if ( ! computeIdArena ) {
412  for(i=0;i<nPatches;++i) {
413  delete [] patchData[i].cids;
414  }
415  }
416  UNPACKN(PatchData,patchData,nPatches);
417 
418  delete computeIdArena;
419  computeIdArena = new ObjectArena<ComputeID>;
420  computeIdArena->setBlockSize(1024);
421 
422  for(i=0;i<nPatches;++i) {
423  DebugM(3,"Unpacking Patch " << i << " is on node " << patchData[i].node <<
424  " with " << patchData[i].numCids << " cids.\n");
425  patchData[i].cids = computeIdArena->getNewArray(patchData[i].numCids);
426  patchData[i].numCidsAllocated = patchData[i].numCids;
427  UNPACKN(ComputeID,patchData[i].cids,patchData[i].numCids);
428  }
429 }
430 
431 //----------------------------------------------------------------------
433 {
434  return CkpvAccess(PatchMap_patchMgr)->homePatches.size();
435 }
436 
437 //----------------------------------------------------------------------
439  return &(CkpvAccess(PatchMap_patchMgr)->homePatches);
440 }
441 
442 //----------------------------------------------------------------------
444  pids.resize(0);
445  int i;
446  for ( i=0; i<nPatches; ++i ) {
447  if ( patchData[i].node == CkMyPe() ) {
448  pids.add(i);
449  }
450  }
451 }
452 
453 //----------------------------------------------------------------------
455  pids.resize(0);
456  int i;
457  for ( i=0; i<nPatches; ++i ) {
458  if ( patchData[i].basenode == pe ) {
459  pids.add(i);
460  }
461  }
462 }
463 
464 //----------------------------------------------------------------------
466  patchData[pid].node=node;
467  if ( nPatchesOnNode[node] == 0 ) nNodesWithPatches += 1;
468  nPatchesOnNode[node] += 1;
469 }
470 
471 //----------------------------------------------------------------------
473  patchData[pid].basenode=node;
474 }
475 
477 
478  int i = 1;
479 
480  NodeID node = patchData[pid].node;
481 
482  if ( CkNumPes() > 2*nPatches+1 ) {
483 
484  int newnode = ( CkNumPes() + node - 1 ) % CkNumPes();
485  bool success = 0;
486 
487  while ( i < CkNumPes() && !success) {
488  if ( nPatchesOnNode[newnode] == 0 )
489  success = 1;
490 
491  //we know till pid, we have assigned all base nodes
492  for (int count = 0; count < pid; count ++)
493  if (patchData[count].basenode > 0 && patchData[count].basenode == newnode) {
494  success = 0;
495  break;
496  }
497 
498  //no patch or a patche's base node on this newnode. this is a good node
499  if (success) break;
500 
501  newnode = ( CkNumPes() + node - i - 1 ) % CkNumPes();
502  i ++;
503  }
504  patchData[pid].basenode = newnode;
505 
506  } else {
507  patchData[pid].basenode=node;
508  }
509 }
510 
511 //----------------------------------------------------------------------
512 void PatchMap::newCid(int pid, int cid)
513 {
514  if (patchData[pid].numCids >= patchData[pid].numCidsAllocated)
515  { // allocate more
516 // NAMD_die("PatchMap::newCid - not enough compute ID's allocated.");
517  ComputeID *old = patchData[pid].cids;
518  patchData[pid].numCidsAllocated += 10;
519  patchData[pid].cids = new int[patchData[pid].numCidsAllocated];
520  int i;
521  for (i=0; i<patchData[pid].numCids; i++)
522  patchData[pid].cids[i] = old[i];
523  for (i=patchData[pid].numCids; i<patchData[pid].numCidsAllocated; i++)
524  patchData[pid].cids[i] = -1;
525  delete [] old;
526  }
527  patchData[pid].cids[patchData[pid].numCids]=cid;
528  patchData[pid].numCids++;
529 }
530 
531 //----------------------------------------------------------------------
532 int PatchMap::oneAwayNeighbors(int pid, PatchID *neighbor_ids)
533 {
534  int xi, yi, zi;
535  int xinc, yinc, zinc;
536  int n=0;
537 
538  for(zinc=-1;zinc<=1;zinc++)
539  {
540  zi = patchData[pid].cIndex + zinc;
541  if ((zi < 0) || (zi >= cDim))
542  if ( ! cPeriodic ) continue;
543  for(yinc=-1;yinc<=1;yinc++)
544  {
545  yi = patchData[pid].bIndex + yinc;
546  if ((yi < 0) || (yi >= bDim))
547  if ( ! bPeriodic ) continue;
548  for(xinc=-1;xinc<=1;xinc++)
549  {
550  if ((xinc==0) && (yinc==0) && (zinc==0))
551  continue;
552 
553  xi = patchData[pid].aIndex + xinc;
554  if ((xi < 0) || (xi >= aDim))
555  if ( ! aPeriodic ) continue;
556 
557  if (neighbor_ids)
558  neighbor_ids[n]=this->pid(xi,yi,zi);
559 #if 0
560  if ( transform_ids )
561  {
562  int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
563  int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
564  int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
565  transform_ids[n] = Lattice::index(xt,yt,zt);
566  }
567 #endif
568  n++;
569  }
570  }
571  }
572  DebugM(3,"Patch " << pid << " has " << n << " first neighbors.\n");
573  return n;
574 }
575 
576 
577 //----------------------------------------------------------------------
578 // Only returns half of neighbors!
579 int PatchMap::oneOrTwoAwayNeighbors(int pid, PatchID *neighbor_ids, PatchID *downstream_ids, int *transform_ids)
580 {
581  int xi, yi, zi;
582  int xinc, yinc, zinc;
583  int n=0;
584  const int xs = patchData[pid].aIndex;
585  const int ys = patchData[pid].bIndex;
586  const int zs = patchData[pid].cIndex;
587 
588  for(zinc=0;zinc<=cAway;zinc++)
589  {
590  zi = zs + zinc;
591  if ((zi < 0) || (zi >= cDim))
592  if ( ! cPeriodic ) continue;
593  for(yinc=(zinc>0 ? -bAway : 0);yinc<=bAway;yinc++)
594  {
595  yi = ys + yinc;
596  if ((yi < 0) || (yi >= bDim))
597  if ( ! bPeriodic ) continue;
598  for(xinc=((zinc>0 || yinc>0) ? -aAway : 0);xinc<=aAway;xinc++)
599  {
600  if ((xinc==0) && (yinc==0) && (zinc==0))
601  continue;
602 
603  xi = xs + xinc;
604  if ((xi < 0) || (xi >= aDim))
605  if ( ! aPeriodic ) continue;
606 
607  neighbor_ids[n] = this->pid(xi,yi,zi);
608  if ( transform_ids )
609  {
610  int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
611  int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
612  int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
613  transform_ids[n] = Lattice::index(xt,yt,zt);
614  }
615  if ( downstream_ids )
616  {
617  int xd = ( xi < xs ? xi : xs );
618  int yd = ( yi < ys ? yi : ys );
619  int zd = ( zi < zs ? zi : zs );
620  downstream_ids[n] = this->pid(xd,yd,zd);
621  }
622  n++;
623  }
624  }
625  }
626  DebugM(3,"Patch " << pid << " has " << n << " second neighbors.\n");
627  return n;
628 }
629 
630 //----------------------------------------------------------------------
631 // Return all patches in corresponding octet (2x2x2 block of patches)
632 // regardless of periodic boundary conditions
633 // Used for LCPO Computes
634 int PatchMap::getPatchesInOctet(int pid, PatchID *pids, int *transform_ids)
635 {
636  int xi, yi, zi;
637  int xinc, yinc, zinc;
638  int n=0;
639  const int xs = patchData[pid].aIndex;
640  const int ys = patchData[pid].bIndex;
641  const int zs = patchData[pid].cIndex;
642 
643  for(zinc=0; zinc<2; zinc++) {
644  zi = zs + zinc;
645  for(yinc=0; yinc<2; yinc++) {
646  yi = ys + yinc;
647  for(xinc=0; xinc<2; xinc++) {
648  xi = xs + xinc;
649  int aIndex = MODULO(xi,aDim);
650  int bIndex = MODULO(yi,bDim);
651  int cIndex = MODULO(zi,cDim);
652  pids[n] = ((cIndex*bDim)+bIndex)*aDim + aIndex;
653  if ( transform_ids ) {
654  int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
655  int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
656  int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
657  transform_ids[n] = Lattice::index(xt,yt,zt);
658  }
659  n++;
660  } // for x
661  } // for y
662  } // for z
663  DebugM(3,"Patch " << pid << " has " << n << " second neighbors.\n");
664  return n;
665 }
666 
667 
668 //----------------------------------------------------------------------
669 int PatchMap::upstreamNeighbors(int pid, PatchID *neighbor_ids)
670 {
671  int xi, yi, zi;
672  int xinc, yinc, zinc;
673  int n=0;
674 
675  for(zinc=0;zinc<=1;zinc++)
676  {
677  zi = patchData[pid].cIndex + zinc;
678  if ((zi < 0) || (zi >= cDim))
679  if ( ! cPeriodic ) continue;
680  for(yinc=0;yinc<=1;yinc++)
681  {
682  yi = patchData[pid].bIndex + yinc;
683  if ((yi < 0) || (yi >= bDim))
684  if ( ! bPeriodic ) continue;
685  for(xinc=0;xinc<=1;xinc++)
686  {
687  if ((xinc==0) && (yinc==0) && (zinc==0))
688  continue;
689 
690  xi = patchData[pid].aIndex + xinc;
691  if ((xi < 0) || (xi >= aDim))
692  if ( ! aPeriodic ) continue;
693 
694  if (neighbor_ids)
695  neighbor_ids[n]=this->pid(xi,yi,zi);
696 #if 0
697  if ( transform_ids )
698  {
699  int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
700  int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
701  int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
702  transform_ids[n] = Lattice::index(xt,yt,zt);
703  }
704 #endif
705  n++;
706  }
707  }
708  }
709  DebugM(3,"Patch " << pid << " has " << n << " upstream neighbors.\n");
710  return n;
711 }
712 
713 //----------------------------------------------------------------------
714 int PatchMap::downstreamNeighbors(int pid, PatchID *neighbor_ids)
715 {
716  int xi, yi, zi;
717  int xinc, yinc, zinc;
718  int n=0;
719 
720  for(zinc=-1;zinc<=0;zinc++)
721  {
722  zi = patchData[pid].cIndex + zinc;
723  if ((zi < 0) || (zi >= cDim))
724  if ( ! cPeriodic ) continue;
725  for(yinc=-1;yinc<=0;yinc++)
726  {
727  yi = patchData[pid].bIndex + yinc;
728  if ((yi < 0) || (yi >= bDim))
729  if ( ! bPeriodic ) continue;
730  for(xinc=-1;xinc<=0;xinc++)
731  {
732  if ((xinc==0) && (yinc==0) && (zinc==0))
733  continue;
734 
735  xi = patchData[pid].aIndex + xinc;
736  if ((xi < 0) || (xi >= aDim))
737  if ( ! aPeriodic ) continue;
738 
739  if (neighbor_ids)
740  neighbor_ids[n]=this->pid(xi,yi,zi);
741 #if 0
742  if ( transform_ids )
743  {
744  int xt = 0; if ( xi < 0 ) xt = -1; if ( xi >= aDim ) xt = 1;
745  int yt = 0; if ( yi < 0 ) yt = -1; if ( yi >= bDim ) yt = 1;
746  int zt = 0; if ( zi < 0 ) zt = -1; if ( zi >= cDim ) zt = 1;
747  transform_ids[n] = Lattice::index(xt,yt,zt);
748  }
749 #endif
750  n++;
751  }
752  }
753  }
754  DebugM(3,"Patch " << pid << " has " << n << " upstream neighbors.\n");
755  return n;
756 }
757 
758 //----------------------------------------------------------------------
760 {
761  CkPrintf("---------------------------------------");
762  CkPrintf("---------------------------------------\n");
763 
764  CkPrintf("nPatches = %d\n",nPatches);
765  for(int i=0;i<nPatches;i++)
766  {
767  CkPrintf("Patch %d:\n",i);
768  CkPrintf(" node = %d\n",patchData[i].node);
769  CkPrintf(" xi,yi,zi = %d, %d, %d\n",
770  patchData[i].aIndex,patchData[i].bIndex,patchData[i].cIndex);
771  CkPrintf(" numCids = %d\n",patchData[i].numCids);
772  CkPrintf(" numCidsAllocated = %d\n",patchData[i].numCidsAllocated);
773  for(int j=0; j < patchData[i].numCids; j++)
774  {
775  CkPrintf(" %10d ",patchData[i].cids[j]);
776  if (!((j+1) % 6))
777  CkPrintf("\n");
778  }
779  CkPrintf("\n---------------------------------------");
780  CkPrintf("---------------------------------------\n");
781  }
782 
783 }
784 
785 //----------------------------------------------------------------------
787  registerPatch(pid,(Patch*)pptr);
788  if (myHomePatch[pid] != 0) {
789  iout << iPE << iERRORF
790  << "homePatchID("<<pid<<") is being re-registered!\n" << endi;
791  }
792  myHomePatch[pid] = pptr;
793 }
794 
795 //----------------------------------------------------------------------
797  unregisterPatch(pid,(Patch*)pptr);
798  if (pptr == myHomePatch[pid]) {
799  DebugM(4, "UnregisterHomePatch("<<pid<<") at " << pptr << "\n");
800  myHomePatch[pid] = NULL;
801  }
802 }
803 
804 //----------------------------------------------------------------------
806 {
807  if (myPatch[pid] != 0) {
808  iout << iPE << iERRORF
809  << "patchID("<<pid<<") is being re-registered!\n" << endi;
810  }
811  myPatch[pid] = pptr;
812 }
813 
814 //----------------------------------------------------------------------
816 {
817  if (pptr == myPatch[pid]) {
818  DebugM(4, "UnregisterPatch("<<pid<<") at " << pptr << "\n");
819  myPatch[pid] = NULL;
820  }
821 }
822 
#define UNPACKN(type, data, cnt)
Definition: PatchMap.C:362
static int index(int i=0, int j=0, int k=0)
Definition: Lattice.h:25
std::ostream & iINFO(std::ostream &s)
Definition: InfoStream.C:107
Type * getNewArray(int n)
Definition: ObjectArena.h:49
Vector a_r() const
Definition: Lattice.h:268
int ComputeID
Definition: NamdTypes.h:183
Definition: Vector.h:64
Vector c_r() const
Definition: Lattice.h:270
void basePatchIDList(int pe, PatchIDList &)
Definition: PatchMap.C:454
std::ostream & iPE(std::ostream &s)
Definition: InfoStream.C:40
int index_a(int pid) const
Definition: PatchMap.h:86
#define DebugM(x, y)
Definition: Debug.h:59
HomePatchList * homePatchList()
Definition: PatchMap.C:438
BigReal z
Definition: Vector.h:66
int packSize(void)
Definition: PatchMap.C:314
int upstreamNeighbors(int pid, PatchID *neighbor_ids)
Definition: PatchMap.C:669
#define iout
Definition: InfoStream.h:87
int numCids(int pid) const
Definition: PatchMap.h:120
int sizeGrid(ScaledPosition xmin, ScaledPosition xmax, const Lattice &lattice, BigReal patchSize, double maxNumPatches, int staticAtomAssignment, int asplit, int bsplit, int csplit)
Definition: PatchMap.C:62
int basenode(int pid) const
Definition: PatchMap.h:117
Vector b_r() const
Definition: Lattice.h:269
Definition: Patch.h:35
void unpack(char *buf)
Definition: PatchMap.C:365
void unregisterPatch(PatchID pid, HomePatch *pptr)
Definition: PatchMap.C:796
void assignBaseNode(PatchID, NodeID)
Definition: PatchMap.C:472
void newCid(int pid, int cid)
Definition: PatchMap.C:512
void setBlockSize(int n)
Definition: ObjectArena.h:23
void NAMD_bug(const char *err_msg)
Definition: common.C:123
int oneAwayNeighbors(int pid, PatchID *neighbor_ids=0)
Definition: PatchMap.C:532
#define UNPACK(type, data)
Definition: PatchMap.C:361
void homePatchIDList(PatchIDList &)
Definition: PatchMap.C:443
int oneOrTwoAwayNeighbors(int pid, PatchID *neighbor_ids, PatchID *downstream_ids=0, int *transform_ids=0)
Definition: PatchMap.C:579
int index_b(int pid) const
Definition: PatchMap.h:87
BigReal x
Definition: Vector.h:66
int PatchID
Definition: NamdTypes.h:182
int cid(int pid, int i) const
Definition: PatchMap.h:123
void NAMD_die(const char *err_msg)
Definition: common.C:83
void makePatches(ScaledPosition xmin, ScaledPosition xmax, const Lattice &lattice, BigReal patchSize, double maxNumPatches, int staticAtomAssignment, int replicaUniformPatchGrids, int lcpo, int asplit, int bsplit, int csplit)
Definition: PatchMap.C:171
int index_c(int pid) const
Definition: PatchMap.h:88
int add(const Elem &elem)
Definition: ResizeArray.h:97
#define iERRORF
Definition: DataStream.h:62
int downstreamNeighbors(int pid, PatchID *neighbor_ids)
Definition: PatchMap.C:714
void resize(int i)
Definition: ResizeArray.h:84
int node(int pid) const
Definition: PatchMap.h:114
void checkMap()
Definition: PatchMap.C:274
void replica_min_double(double *dat, int count)
int numHomePatches(void)
Definition: PatchMap.C:432
int pid(int aIndex, int bIndex, int cIndex)
Definition: PatchMap.inl:27
BigReal y
Definition: Vector.h:66
Vector b() const
Definition: Lattice.h:253
void assignNode(PatchID, NodeID)
Definition: PatchMap.C:465
infostream & endi(infostream &s)
Definition: InfoStream.C:38
~PatchMap(void)
Definition: PatchMap.C:291
void registerPatch(PatchID pid, HomePatch *pptr)
Definition: PatchMap.C:786
#define MODULO(I, J)
Definition: PatchMap.inl:25
int b_p() const
Definition: Lattice.h:274
void pack(char *buf, int size)
Definition: PatchMap.C:328
void printPatchMap(void)
Definition: PatchMap.C:759
PatchMap(void)
Definition: PatchMap.C:39
int a_p() const
Definition: Lattice.h:273
#define PACK(type, data)
Definition: PatchMap.C:311
int NodeID
Definition: NamdTypes.h:184
static PatchMap * Instance()
Definition: PatchMap.C:32
Vector a() const
Definition: Lattice.h:252
#define PACKN(type, data, cnt)
Definition: PatchMap.C:312
Vector unit(void) const
Definition: Vector.h:182
Vector c() const
Definition: Lattice.h:254
double BigReal
Definition: common.h:114
int c_p() const
Definition: Lattice.h:275
int getPatchesInOctet(int pid, PatchID *pids, int *transform_ids=0)
Definition: PatchMap.C:634