AtomMap.C

Go to the documentation of this file.
00001 
00007 /*
00008    Tracks location of Atoms on node.  Singleton.
00009 */
00010 
00011 #include "ProcessorPrivate.h"
00012 #include "AtomMap.h"
00013 
00014 #define MIN_DEBUG_LEVEL 4
00015 // #define DEBUGM
00016 #include "Debug.h"
00017 
00018 #ifdef MEM_OPT_VERSION
00019 #define MAXBITS 20
00020 #define MAXNUMATOMS (1<<MAXBITS)
00021 #endif
00022 
00023 
00024 void AtomMapper::registerIDsCompAtomExt(const CompAtomExt *begin, const CompAtomExt *end) {
00025   if ( mapped ) return;
00026   mapped = 1;
00027 #ifdef MEM_OPT_VERSION
00028   if ( ! map->onlyUseTbl ) {
00029     int n = end - begin;
00030     entries.resize(n);
00031     AtomMapEntry *e = entries.begin();
00032     for ( int i=0; i<n; ++i, ++e ) {
00033       e->pid = pid;
00034       e->index = i;
00035       AtomID aid = begin[i].id;
00036       short aid_upper = aid >> MAXBITS;
00037       e->aid_upper = aid_upper;
00038       int aid_hash = aid & (MAXNUMATOMS-1);
00039       AtomMapEntry **me = map->entries + aid_hash;
00040       while ( *me && (*me)->aid_upper < aid_upper ) me = &((*me)->next);
00041       e->next = *me;
00042       *me = e;
00043     }
00044   } else
00045 #endif
00046   if ( map->registerIDsCompAtomExt(pid, begin, end) ) NAMD_bug("atom map failed");
00047 }
00048 
00049 
00050 void AtomMapper::registerIDsFullAtom(const FullAtom *begin, const FullAtom *end) {
00051   if ( mapped ) return;
00052   mapped = 1;
00053 #ifdef MEM_OPT_VERSION
00054   if ( ! map->onlyUseTbl ) {
00055     int n = end - begin;
00056     entries.resize(n);
00057     AtomMapEntry *e = entries.begin();
00058     for ( int i=0; i<n; ++i, ++e ) {
00059       e->pid = pid;
00060       e->index = i;
00061       AtomID aid = begin[i].id;
00062       short aid_upper = aid >> MAXBITS;
00063       e->aid_upper = aid_upper;
00064       int aid_hash = aid & (MAXNUMATOMS-1);
00065       AtomMapEntry **me = map->entries + aid_hash;
00066       while ( *me && (*me)->aid_upper < aid_upper ) me = &((*me)->next);
00067       e->next = *me;
00068       *me = e;
00069     }
00070   } else
00071 #endif
00072   if ( map->registerIDsFullAtom(pid, begin, end) ) NAMD_bug("atom map failed");
00073 }
00074 
00075 
00076 void AtomMapper::unregisterIDsCompAtomExt(const CompAtomExt *begin, const CompAtomExt *end) {
00077   if ( ! mapped ) return;
00078   mapped = 0;
00079 #ifdef MEM_OPT_VERSION
00080   if ( ! map->onlyUseTbl ) {
00081     int n = end - begin;
00082     if ( entries.size() != n ) {
00083       CkPrintf("AtomMapper entries.size() %d != %d\n", entries.size(), n);
00084       NAMD_bug("AtomMapper::unregisterIDsCompAtomExt size mismatch");
00085     }
00086     AtomMapEntry *e = entries.begin();
00087     for ( int i=0; i<n; ++i, ++e ) {
00088       AtomID aid = begin[i].id;
00089       int aid_hash = aid & (MAXNUMATOMS-1);
00090       AtomMapEntry **me = map->entries + aid_hash;
00091       while ( *me != e ) me = &((*me)->next);
00092       *me = e->next;
00093     }
00094   } else
00095 #endif
00096   if ( map->unregisterIDsCompAtomExt(pid, begin, end) ) NAMD_bug("atom map failed");
00097 }
00098 
00099 
00100 void AtomMapper::unregisterIDsFullAtom(const FullAtom *begin, const FullAtom *end) {
00101   if ( ! mapped ) return;
00102   mapped = 0;
00103 #ifdef MEM_OPT_VERSION
00104   if ( ! map->onlyUseTbl ) {
00105     int n = end - begin;
00106     if ( entries.size() != n ) {
00107       CkPrintf("AtomMapper entries.size() %d != %d\n", entries.size(), n);
00108       NAMD_bug("AtomMapper::unregisterIDsFullAtom size mismatch");
00109     }
00110     AtomMapEntry *e = entries.begin();
00111     for ( int i=0; i<n; ++i, ++e ) {
00112       AtomID aid = begin[i].id;
00113       int aid_hash = aid & (MAXNUMATOMS-1);
00114       AtomMapEntry **me = map->entries + aid_hash;
00115       while ( *me != e ) me = &((*me)->next);
00116       *me = e->next;
00117     }
00118   } else
00119 #endif
00120   if ( map->unregisterIDsFullAtom(pid, begin, end) ) NAMD_bug("atom map failed");
00121 }
00122 
00123 
00124 // Singleton method
00125 AtomMap *AtomMap::Instance() {
00126   if (CkpvAccess(AtomMap_instance) == 0) {
00127     CkpvAccess(AtomMap_instance) = new AtomMap; // this is never deleted!
00128   }
00129   return CkpvAccess(AtomMap_instance);
00130 }
00131 
00132 //----------------------------------------------------------------------
00133 AtomMap::AtomMap(void)
00134 {
00135   localIDTable = NULL;
00136   tableSz = 0;
00137 
00138 #ifdef MEM_OPT_VERSION
00139   entries = NULL;
00140   onlyUseTbl = false;
00141 #endif
00142 }
00143 
00144 void
00145 AtomMap::checkMap(void)
00146 { }
00147   
00148 
00149 //----------------------------------------------------------------------
00150 AtomMap::~AtomMap(void)
00151 {
00152   delete [] localIDTable;  // Delete on a NULL pointer should be ok
00153 
00154 #ifdef MEM_OPT_VERSION
00155   delete [] entries;
00156 #endif
00157 }
00158 
00159 //----------------------------------------------------------------------
00160 // Creates fixed size table
00161 void AtomMap::allocateMap(int nAtomIds)
00162 {
00163 #ifdef MEM_OPT_VERSION
00164   if ( nAtomIds > MAXNUMATOMS ) {
00165     entries = new AtomMapEntry*[MAXNUMATOMS];
00166     memset(entries,0,MAXNUMATOMS*sizeof(AtomMapEntry*));
00167     return;
00168   } // else use non-memopt strategy
00169   onlyUseTbl = true;    
00170 #endif
00171   if ( nAtomIds <= tableSz ) return;
00172   LocalID *oldTable = localIDTable;
00173   localIDTable = new LocalID[nAtomIds];
00174   for(int i=0; i < tableSz; i++)
00175     localIDTable[i] = oldTable[i];
00176   for(int i=tableSz; i < nAtomIds; i++)
00177     localIDTable[i].pid = localIDTable[i].index = notUsed;
00178   delete [] oldTable;
00179   tableSz = nAtomIds;
00180 }
00181 
00182 //
00183 int AtomMap::unregisterIDsCompAtomExt(PatchID pid, const CompAtomExt *begin, const CompAtomExt *end)
00184 {
00185   if (localIDTable == NULL)
00186     return -1;
00187   else 
00188   {
00189     for(const CompAtomExt *a = begin; a != end; ++a)
00190     {
00191         unsigned int ali = a->id;
00192         if (localIDTable[ali].pid == pid) {
00193             localIDTable[ali].pid = notUsed;
00194             localIDTable[ali].index = notUsed;
00195         }
00196     }
00197     return 0;
00198   }
00199 }
00200 
00201 //----------------------------------------------------------------------
00202 int AtomMap::unregisterIDsFullAtom(PatchID pid, const FullAtom *begin, const FullAtom *end)
00203 {
00204   if (localIDTable == NULL)
00205     return -1;
00206   else 
00207   {
00208     for(const FullAtom *a = begin; a != end; ++a)
00209     {
00210         unsigned int ali = a->id;
00211         if (localIDTable[ali].pid == pid) {
00212             localIDTable[ali].pid = notUsed;
00213             localIDTable[ali].index = notUsed;
00214         }
00215     }
00216     return 0;
00217   }
00218 }
00219 
00220 //It's possible to register the same atom for a new patch before it is moved 
00221 //from the old patch on the same processor!
00222 
00223 //----------------------------------------------------------------------
00224 int AtomMap::registerIDsCompAtomExt(PatchID pid, const CompAtomExt *begin, const CompAtomExt *end)
00225 {
00226   if (localIDTable == NULL)
00227     return -1;
00228   else 
00229   {
00230     for(const CompAtomExt *a = begin; a != end; ++a)
00231     {
00232         unsigned int ali = a->id;
00233         localIDTable[ali].pid = pid;
00234         localIDTable[ali].index = a - begin;
00235     }
00236     return 0;
00237   }
00238 }
00239 
00240 //----------------------------------------------------------------------
00241 int AtomMap::registerIDsFullAtom(PatchID pid, const FullAtom *begin, const FullAtom *end)
00242 {
00243   if (localIDTable == NULL)
00244     return -1;
00245   else 
00246   {
00247     for(const FullAtom *a = begin; a != end; ++a)
00248     {
00249         unsigned int ali = a->id;
00250         localIDTable[ali].pid = pid;
00251         localIDTable[ali].index = a - begin;
00252     }
00253     return 0;
00254   }
00255 }
00256 
00257 
00258 #ifdef MEM_OPT_VERSION
00259 LocalID AtomMap::localID(AtomID id)
00260 {
00261         if(onlyUseTbl){
00262                 return localIDTable[id];
00263         }else{
00264 
00265       short aid_upper = id >> MAXBITS;
00266       int aid_hash = id & (MAXNUMATOMS-1);
00267       AtomMapEntry *me = entries[aid_hash];
00268       while ( me && me->aid_upper < aid_upper ) me = me->next;
00269       LocalID rval;
00270       if ( me && me->aid_upper == aid_upper ) {
00271         rval.pid = me->pid;
00272         rval.index = me->index;
00273       } else {
00274         rval.pid = notUsed;
00275         rval.index = notUsed;
00276       }
00277       return rval;
00278         }
00279 }
00280 #endif
00281 

Generated on Sat Sep 23 01:17:11 2017 for NAMD by  doxygen 1.4.7