NAMD
AtomMap.C
Go to the documentation of this file.
1 
7 /*
8  Tracks location of Atoms on node. Singleton.
9 */
10 
11 #include "ProcessorPrivate.h"
12 #include "AtomMap.h"
13 
14 #define MIN_DEBUG_LEVEL 4
15 // #define DEBUGM
16 #include "Debug.h"
17 
18 #ifdef MEM_OPT_VERSION
19 #define MAXBITS 20
20 #define MAXNUMATOMS (1<<MAXBITS)
21 #endif
22 
23 
25  if ( mapped ) return;
26  mapped = 1;
27 #ifdef MEM_OPT_VERSION
28  if ( ! map->onlyUseTbl ) {
29  int n = end - begin;
30  entries.resize(n);
31  AtomMapEntry *e = entries.begin();
32  for ( int i=0; i<n; ++i, ++e ) {
33  e->pid = pid;
34  e->index = i;
35  AtomID aid = begin[i].id;
36  short aid_upper = aid >> MAXBITS;
37  e->aid_upper = aid_upper;
38  int aid_hash = aid & (MAXNUMATOMS-1);
39  AtomMapEntry **me = map->entries + aid_hash;
40  while ( *me && (*me)->aid_upper < aid_upper ) me = &((*me)->next);
41  e->next = *me;
42  *me = e;
43  }
44  } else
45 #endif
46  if ( map->registerIDsCompAtomExt(pid, begin, end) ) NAMD_bug("atom map failed");
47 }
48 
49 
50 void AtomMapper::registerIDsFullAtom(const FullAtom *begin, const FullAtom *end) {
51  if ( mapped ) return;
52  mapped = 1;
53 #ifdef MEM_OPT_VERSION
54  if ( ! map->onlyUseTbl ) {
55  int n = end - begin;
56  entries.resize(n);
57  AtomMapEntry *e = entries.begin();
58  for ( int i=0; i<n; ++i, ++e ) {
59  e->pid = pid;
60  e->index = i;
61  AtomID aid = begin[i].id;
62  short aid_upper = aid >> MAXBITS;
63  e->aid_upper = aid_upper;
64  int aid_hash = aid & (MAXNUMATOMS-1);
65  AtomMapEntry **me = map->entries + aid_hash;
66  while ( *me && (*me)->aid_upper < aid_upper ) me = &((*me)->next);
67  e->next = *me;
68  *me = e;
69  }
70  } else
71 #endif
72  if ( map->registerIDsFullAtom(pid, begin, end) ) NAMD_bug("atom map failed");
73 }
74 
75 
77  if ( ! mapped ) return;
78  mapped = 0;
79 #ifdef MEM_OPT_VERSION
80  if ( ! map->onlyUseTbl ) {
81  int n = end - begin;
82  if ( entries.size() != n ) {
83  CkPrintf("AtomMapper entries.size() %d != %d\n", entries.size(), n);
84  NAMD_bug("AtomMapper::unregisterIDsCompAtomExt size mismatch");
85  }
86  AtomMapEntry *e = entries.begin();
87  for ( int i=0; i<n; ++i, ++e ) {
88  AtomID aid = begin[i].id;
89  int aid_hash = aid & (MAXNUMATOMS-1);
90  AtomMapEntry **me = map->entries + aid_hash;
91  while ( *me != e ) me = &((*me)->next);
92  *me = e->next;
93  }
94  } else
95 #endif
96  if ( map->unregisterIDsCompAtomExt(pid, begin, end) ) NAMD_bug("atom map failed");
97 }
98 
99 
100 void AtomMapper::unregisterIDsFullAtom(const FullAtom *begin, const FullAtom *end) {
101  if ( ! mapped ) return;
102  mapped = 0;
103 #ifdef MEM_OPT_VERSION
104  if ( ! map->onlyUseTbl ) {
105  int n = end - begin;
106  if ( entries.size() != n ) {
107  CkPrintf("AtomMapper entries.size() %d != %d\n", entries.size(), n);
108  NAMD_bug("AtomMapper::unregisterIDsFullAtom size mismatch");
109  }
110  AtomMapEntry *e = entries.begin();
111  for ( int i=0; i<n; ++i, ++e ) {
112  AtomID aid = begin[i].id;
113  int aid_hash = aid & (MAXNUMATOMS-1);
114  AtomMapEntry **me = map->entries + aid_hash;
115  while ( *me != e ) me = &((*me)->next);
116  *me = e->next;
117  }
118  } else
119 #endif
120  if ( map->unregisterIDsFullAtom(pid, begin, end) ) NAMD_bug("atom map failed");
121 }
122 
123 
124 // Singleton method
126  if (CkpvAccess(AtomMap_instance) == 0) {
127  CkpvAccess(AtomMap_instance) = new AtomMap; // this is never deleted!
128  }
129  return CkpvAccess(AtomMap_instance);
130 }
131 
132 //----------------------------------------------------------------------
134 {
135  localIDTable = NULL;
136  tableSz = 0;
137 
138 #ifdef MEM_OPT_VERSION
139  entries = NULL;
140  onlyUseTbl = false;
141 #endif
142 }
143 
144 void
146 { }
147 
148 
149 //----------------------------------------------------------------------
151 {
152  delete [] localIDTable; // Delete on a NULL pointer should be ok
153 
154 #ifdef MEM_OPT_VERSION
155  delete [] entries;
156 #endif
157 }
158 
159 //----------------------------------------------------------------------
160 // Creates fixed size table
161 void AtomMap::allocateMap(int nAtomIds)
162 {
163 #ifdef MEM_OPT_VERSION
164  if ( nAtomIds > MAXNUMATOMS ) {
165  entries = new AtomMapEntry*[MAXNUMATOMS];
166  memset(entries,0,MAXNUMATOMS*sizeof(AtomMapEntry*));
167  return;
168  } // else use non-memopt strategy
169  onlyUseTbl = true;
170 #endif
171  if ( nAtomIds <= tableSz ) return;
172  LocalID *oldTable = localIDTable;
173  localIDTable = new LocalID[nAtomIds];
174  for(int i=0; i < tableSz; i++)
175  localIDTable[i] = oldTable[i];
176  for(int i=tableSz; i < nAtomIds; i++)
177  localIDTable[i].pid = localIDTable[i].index = notUsed;
178  delete [] oldTable;
179  tableSz = nAtomIds;
180 }
181 
182 //
183 int AtomMap::unregisterIDsCompAtomExt(PatchID pid, const CompAtomExt *begin, const CompAtomExt *end)
184 {
185  if (localIDTable == NULL)
186  return -1;
187  else
188  {
189  for(const CompAtomExt *a = begin; a != end; ++a)
190  {
191  unsigned int ali = a->id;
192  if (localIDTable[ali].pid == pid) {
193  localIDTable[ali].pid = notUsed;
194  localIDTable[ali].index = notUsed;
195  }
196  }
197  return 0;
198  }
199 }
200 
201 //----------------------------------------------------------------------
202 int AtomMap::unregisterIDsFullAtom(PatchID pid, const FullAtom *begin, const FullAtom *end)
203 {
204  if (localIDTable == NULL)
205  return -1;
206  else
207  {
208  for(const FullAtom *a = begin; a != end; ++a)
209  {
210  unsigned int ali = a->id;
211  if (localIDTable[ali].pid == pid) {
212  localIDTable[ali].pid = notUsed;
213  localIDTable[ali].index = notUsed;
214  }
215  }
216  return 0;
217  }
218 }
219 
220 //It's possible to register the same atom for a new patch before it is moved
221 //from the old patch on the same processor!
222 
223 //----------------------------------------------------------------------
224 int AtomMap::registerIDsCompAtomExt(PatchID pid, const CompAtomExt *begin, const CompAtomExt *end)
225 {
226  if (localIDTable == NULL)
227  return -1;
228  else
229  {
230  for(const CompAtomExt *a = begin; a != end; ++a)
231  {
232  unsigned int ali = a->id;
233  localIDTable[ali].pid = pid;
234  localIDTable[ali].index = a - begin;
235  }
236  return 0;
237  }
238 }
239 
240 //----------------------------------------------------------------------
241 int AtomMap::registerIDsFullAtom(PatchID pid, const FullAtom *begin, const FullAtom *end)
242 {
243  if (localIDTable == NULL)
244  return -1;
245  else
246  {
247  for(const FullAtom *a = begin; a != end; ++a)
248  {
249  unsigned int ali = a->id;
250  localIDTable[ali].pid = pid;
251  localIDTable[ali].index = a - begin;
252  }
253  return 0;
254  }
255 }
256 
257 
258 #ifdef MEM_OPT_VERSION
260 {
261  if(onlyUseTbl){
262  return localIDTable[id];
263  }else{
264 
265  short aid_upper = id >> MAXBITS;
266  int aid_hash = id & (MAXNUMATOMS-1);
267  AtomMapEntry *me = entries[aid_hash];
268  while ( me && me->aid_upper < aid_upper ) me = me->next;
269  LocalID rval;
270  if ( me && me->aid_upper == aid_upper ) {
271  rval.pid = me->pid;
272  rval.index = me->index;
273  } else {
274  rval.pid = notUsed;
275  rval.index = notUsed;
276  }
277  return rval;
278  }
279 }
280 #endif
281 
void allocateMap(int nAtomIDs)
Definition: AtomMap.C:161
void checkMap()
Definition: AtomMap.C:145
int AtomID
Definition: NamdTypes.h:29
void registerIDsFullAtom(const FullAtom *begin, const FullAtom *end)
Definition: AtomMap.C:50
static AtomMap * Instance()
Definition: AtomMap.C:125
~AtomMap(void)
Definition: AtomMap.C:150
void registerIDsCompAtomExt(const CompAtomExt *begin, const CompAtomExt *end)
Definition: AtomMap.C:24
void NAMD_bug(const char *err_msg)
Definition: common.C:123
int index
Definition: NamdTypes.h:195
LocalID localID(AtomID id)
Definition: AtomMap.h:74
int PatchID
Definition: NamdTypes.h:182
AtomMap(void)
Definition: AtomMap.C:133
PatchID pid
Definition: NamdTypes.h:194
void unregisterIDsFullAtom(const FullAtom *begin, const FullAtom *end)
Definition: AtomMap.C:100
void unregisterIDsCompAtomExt(const CompAtomExt *begin, const CompAtomExt *end)
Definition: AtomMap.C:76