NAMD
ComputeSelfTuples.h
Go to the documentation of this file.
1 
7 #ifndef COMPUTESELFTUPLES_H
8 #define COMPUTESELFTUPLES_H
9 
10 #include "ComputeHomeTuples.h"
11 #include "LdbCoordinator.h"
12 
13 #ifdef USE_HOMETUPLES
14 template <class T, class S, class P> class SelfTuples : public HomeTuples<T, S, P> {
15 
16  public:
17  SelfTuples(int type=-1) : HomeTuples<T,S,P>(type) {}
18 
19  private:
20 
21  virtual void loadTuples(TuplePatchList& tuplePatchList, const char* isBasePatch, AtomMap *atomMap,
22  const std::vector<int>& pids = std::vector<int>()) {
23  if (isBasePatch != NULL) {
24  iout << iWARN << "Non-NULL isBasePatch detected in SelfTuples::loadTuples()" << endi;
25  }
26 
27  int numTuples;
28 
29  #ifdef MEM_OPT_VERSION
30  typename ElemTraits<T>::signature *allSigs;
31  #else
32  int32 **tuplesByAtom;
33  /* const (need to propagate const) */ S *tupleStructs;
34  #endif
35 
36  const P *tupleValues;
37  Node *node = Node::Object();
38  PatchMap *patchMap = PatchMap::Object();
39  // AtomMap *atomMap = AtomMap::Object();
40 
41  #ifdef MEM_OPT_VERSION
42  allSigs = ElemTraits<T>::get_sig_pointer(node->molecule);
43  #else
44  T::getMoleculePointers(node->molecule,
45  &numTuples, &tuplesByAtom, &tupleStructs);
46  #endif
47 
48  T::getParameterPointers(node->parameters, &tupleValues);
49 
50  this->tupleList.clear();
51 
52  LocalID aid[T::size];
53  int partition[T::size];
54 
55  const int lesOn = node->simParameters->lesOn;
56  const int soluteScalingOn = node->simParameters->soluteScalingOn;
57  const int fepOn = node->simParameters->singleTopology;
58  const int sdScaling = node->simParameters->sdScaling;
59  Real invLesFactor = lesOn ?
60  1.0/node->simParameters->lesFactor :
61  1.0;
62  const Real soluteScalingFactor = node->simParameters->soluteScalingFactor;
63  const Bool soluteScalingAll = node->simParameters->soluteScalingAll;
64  BigReal OneMinusLambda = 1.0 - node->simParameters->alchLambda;
65  BigReal Lambda = node->simParameters->alchLambda;
66  const int num_unpert_bonds = node->molecule->num_alch_unpert_Bonds;
67  const int num_unpert_angles = node->molecule->num_alch_unpert_Angles;
68  const int num_unpert_dihedrals = node->molecule->num_alch_unpert_Dihedrals;
69  Bond *unpert_bonds = node->molecule->alch_unpert_bonds;
70  Angle *unpert_angles = node->molecule->alch_unpert_angles;
71  Dihedral *unpert_dihedrals = node->molecule->alch_unpert_dihedrals;
72 
73  // cycle through each patch and gather all tuples
74  // There should be only one!
75  TuplePatchListIter ai(tuplePatchList);
76  if (pids.size() == 0) ai = ai.begin();
77 
78  int numPid = (pids.size() == 0) ? tuplePatchList.size() : pids.size();
79 
80  for (int ipid=0;ipid < numPid;ipid++) {
81  Patch *patch;
82  int numAtoms;
83  CompAtomExt *atomExt;
84  // Take next patch
85  if (pids.size() == 0) {
86  patch = (*ai).p;
87  numAtoms = patch->getNumAtoms();
88  atomExt = (*ai).xExt;
89  ai++;
90  } else {
91  TuplePatchElem *tpe = tuplePatchList.find(TuplePatchElem(pids[ipid]));
92  patch = tpe->p;
93  numAtoms = patch->getNumAtoms();
94  atomExt = tpe->xExt;
95  }
96  // cycle through each atom in the patch and load up tuples
97  int step = patch->flags.step;
98  for (int j=0; j < numAtoms; j++)
99  {
100 #ifdef MEM_OPT_VERSION
101  typename ElemTraits<T>::signature *thisAtomSig =
102  &allSigs[ElemTraits<T>::get_sig_id(atomExt[j])];
103  TupleSignature *allTuples;
104  T::getTupleInfo(thisAtomSig, &numTuples, &allTuples);
105  for(int k=0; k<numTuples; k++) {
106  T t(atomExt[j].id, &allTuples[k], tupleValues);
107 #else
108  /* get list of all tuples for the atom */
109  int32 *curTuple = tuplesByAtom[atomExt[j].id];
110  for( ; *curTuple != -1; ++curTuple) {
111  T t(&tupleStructs[*curTuple],tupleValues);
112 #endif
113  register int i;
114  aid[0] = atomMap->localID(t.atomID[0]);
115  int homepatch = aid[0].pid;
116  int samepatch = 1;
117  partition[0] = fepOn ? node->molecule->get_fep_type(t.atomID[0]) : 0; //using atom partition to determine if a bonded term to be scaled by lambda or 1-lambda in single topology relative FEP.
118  int has_les = lesOn ? node->molecule->get_fep_type(t.atomID[0]) : 0;
119  int has_ss = soluteScalingOn ? node->molecule->get_ss_type(t.atomID[0]) : 0;
120  int is_fep_ss = partition[0] > 2;
121  int is_fep_sd = 0;
122  int fep_tuple_type = 0;
123  for (i=1; i < T::size; i++) {
124  aid[i] = atomMap->localID(t.atomID[i]);
125  samepatch = samepatch && ( homepatch == aid[i].pid );
126  partition[i] = fepOn ? node->molecule->get_fep_type(t.atomID[i]) : 0;
127  has_les |= lesOn ? node->molecule->get_fep_type(t.atomID[i]) : 0;
128  has_ss |= soluteScalingOn ? node->molecule->get_ss_type(t.atomID[i]) : 0;
129  if (fepOn) {
130  is_fep_ss &= partition[i] > 2;
131  is_fep_sd |= (abs(partition[i] - partition[0]) == 2);
132  fep_tuple_type = partition[i]; }
133  }
134  if (sdScaling && is_fep_sd) { //check if this bonded term is one of Shobana term. This segment looks ugly and not GPU friendly, and might not appear in GPU code.
135  for (i=0; i < num_unpert_bonds; i++) {
136  if (T::size == 2
137  && t.atomID[0]==unpert_bonds[i].atom1
138  && t.atomID[1]==unpert_bonds[i].atom2) is_fep_sd = 0;
139  }
140  for (i=0; i < num_unpert_angles; i++) {
141  if (T::size == 3
142  && t.atomID[0]==unpert_angles[i].atom1
143  && t.atomID[1]==unpert_angles[i].atom2
144  && t.atomID[2]==unpert_angles[i].atom3) is_fep_sd = 0;
145  }
146  for (i=0; i < num_unpert_dihedrals; i++) {
147  if (T::size == 4
148  && t.atomID[0]==unpert_dihedrals[i].atom1
149  && t.atomID[1]==unpert_dihedrals[i].atom2
150  && t.atomID[2]==unpert_dihedrals[i].atom3
151  && t.atomID[3]==unpert_dihedrals[i].atom4) is_fep_sd = 0;
152  }
153  }
154  if (T::size < 4 && !soluteScalingAll) has_ss = false;
155  if ( samepatch ) {
156  t.scale = (!has_les && !has_ss) ? 1.0 : ( has_les ? invLesFactor : soluteScalingFactor );
157  if (is_fep_ss) t.scale = (fep_tuple_type == 4) ? OneMinusLambda : Lambda;
158  if (is_fep_sd && sdScaling) t.scale = (fep_tuple_type == 4 || fep_tuple_type == 2) ? OneMinusLambda : Lambda;
159  TuplePatchElem *p;
160  p = tuplePatchList.find(TuplePatchElem(homepatch));
161  for(i=0; i < T::size; i++) {
162  t.p[i] = p;
163  t.localIndex[i] = aid[i].index;
164  }
165 #ifdef MEM_OPT_VERSION
166  //avoid adding Tuples whose atoms are all fixed
167  if(node->simParameters->fixedAtomsOn &&
169  int allfixed = 1;
170  for(i=0; i<T::size; i++){
171  CompAtomExt *one = &(p->xExt[aid[i].index]);
172  allfixed = allfixed & one->atomFixed;
173  }
174  if(!allfixed) this->tupleList.push_back(t);
175  } else {
176  this->tupleList.push_back(t);
177  }
178 #else
179 
180  this->tupleList.push_back(t);
181 #endif
182  }
183  }
184  }
185  }
186  }
187 
188 };
189 #endif
190 
191 template <class T, class S, class P> class ComputeSelfTuples :
192  public ComputeHomeTuples<T,S,P> {
193 
194 #ifndef USE_HOMETUPLES
195  private:
196 
197  virtual void loadTuples(void) {
198  int numTuples;
199 
200  #ifdef MEM_OPT_VERSION
201  typename ElemTraits<T>::signature *allSigs;
202  #else
203  int32 **tuplesByAtom;
204  /* const (need to propagate const) */ S *tupleStructs;
205  #endif
206 
207  const P *tupleValues;
208  Node *node = Node::Object();
209 
210  #ifdef MEM_OPT_VERSION
211  allSigs = ElemTraits<T>::get_sig_pointer(node->molecule);
212  #else
213  T::getMoleculePointers(node->molecule,
214  &numTuples, &tuplesByAtom, &tupleStructs);
215  #endif
216 
217  T::getParameterPointers(node->parameters, &tupleValues);
218 
219  this->tupleList.resize(0);
220 
221  LocalID aid[T::size];
222  int partition[T::size];
223 
224  const int lesOn = node->simParameters->lesOn;
225  const int soluteScalingOn = node->simParameters->soluteScalingOn;
226  const int fepOn = node->simParameters->singleTopology;
227  const int sdScaling = node->simParameters->sdScaling;
228  Real invLesFactor = lesOn ?
229  1.0/node->simParameters->lesFactor :
230  1.0;
231  const Real soluteScalingFactor = node->simParameters->soluteScalingFactor;
232  const Bool soluteScalingAll = node->simParameters->soluteScalingAll;
233  BigReal OneMinusLambda = 1.0 - node->simParameters->alchLambda;
234  BigReal Lambda = node->simParameters->alchLambda;
235  const int num_unpert_bonds = node->molecule->num_alch_unpert_Bonds;
236  const int num_unpert_angles = node->molecule->num_alch_unpert_Angles;
237  const int num_unpert_dihedrals = node->molecule->num_alch_unpert_Dihedrals;
238  Bond *unpert_bonds = node->molecule->alch_unpert_bonds;
239  Angle *unpert_angles = node->molecule->alch_unpert_angles;
240  Dihedral *unpert_dihedrals = node->molecule->alch_unpert_dihedrals;
241 
242  // cycle through each patch and gather all tuples
243  // There should be only one!
244  TuplePatchListIter ai(this->tuplePatchList);
245 
246  for ( ai = ai.begin(); ai != ai.end(); ai++ )
247  {
248 
249  // CompAtomExt *atom = (*ai).x;
250  Patch *patch = (*ai).p;
251  int numAtoms = patch->getNumAtoms();
252  CompAtomExt *atomExt = (*ai).xExt; //patch->getCompAtomExtInfo();
253 
254  // cycle through each atom in the patch and load up tuples
255  for (int j=0; j < numAtoms; j++)
256  {
257  #ifdef MEM_OPT_VERSION
258  typename ElemTraits<T>::signature *thisAtomSig =
259  &allSigs[ElemTraits<T>::get_sig_id(atomExt[j])];
260  TupleSignature *allTuples;
261  T::getTupleInfo(thisAtomSig, &numTuples, &allTuples);
262  for(int k=0; k<numTuples; k++) {
263  T t(atomExt[j].id, &allTuples[k], tupleValues);
264  #else
265  /* get list of all tuples for the atom */
266  int32 *curTuple = tuplesByAtom[atomExt[j].id];
267  /* cycle through each tuple */
268  for( ; *curTuple != -1; ++curTuple) {
269  T t(&tupleStructs[*curTuple],tupleValues);
270  #endif
271  register int i;
272  aid[0] = this->atomMap->localID(t.atomID[0]);
273  int homepatch = aid[0].pid;
274  int samepatch = 1;
275  partition[0] = fepOn ? node->molecule->get_fep_type(t.atomID[0]) : 0;
276  int has_les = lesOn ? node->molecule->get_fep_type(t.atomID[0]) : 0;
277  int has_ss = soluteScalingOn ? node->molecule->get_ss_type(t.atomID[0]) : 0;
278  int is_fep_ss = partition[0] > 2;
279  int is_fep_sd = 0;
280  int fep_tuple_type = 0;
281  for (i=1; i < T::size; i++) {
282  aid[i] = this->atomMap->localID(t.atomID[i]);
283  samepatch = samepatch && ( homepatch == aid[i].pid );
284  partition[i] = fepOn ? node->molecule->get_fep_type(t.atomID[i]) : 0;
285  has_les |= lesOn ? node->molecule->get_fep_type(t.atomID[i]) : 0;
286  has_ss |= soluteScalingOn ? node->molecule->get_ss_type(t.atomID[i]) : 0;
287  if (fepOn) {
288  is_fep_ss &= partition[i] > 2;
289  is_fep_sd |= (abs(partition[i] - partition[0]) == 2);
290  fep_tuple_type = partition[i]; }
291  }
292  if (T::size < 4 && !soluteScalingAll) has_ss = false;
293  if (sdScaling && is_fep_sd) {
294  for (i=0; i < num_unpert_bonds; i++) {
295  if (T::size == 2
296  && t.atomID[0]==unpert_bonds[i].atom1
297  && t.atomID[1]==unpert_bonds[i].atom2) is_fep_sd = 0;
298  }
299  for (i=0; i < num_unpert_angles; i++) {
300  if (T::size == 3
301  && t.atomID[0]==unpert_angles[i].atom1
302  && t.atomID[1]==unpert_angles[i].atom2
303  && t.atomID[2]==unpert_angles[i].atom3) is_fep_sd = 0;
304  }
305  for (i=0; i < num_unpert_dihedrals; i++) {
306  if (T::size == 4
307  && t.atomID[0]==unpert_dihedrals[i].atom1
308  && t.atomID[1]==unpert_dihedrals[i].atom2
309  && t.atomID[2]==unpert_dihedrals[i].atom3
310  && t.atomID[3]==unpert_dihedrals[i].atom4) is_fep_sd = 0;
311  }
312  }
313  if ( samepatch ) {
314  t.scale = (!has_les && !has_ss) ? 1.0 : ( has_les ? invLesFactor : soluteScalingFactor );
315  if (is_fep_ss) t.scale = (fep_tuple_type == 4) ? OneMinusLambda : Lambda;
316  if (is_fep_sd && sdScaling) t.scale = (fep_tuple_type == 4 || fep_tuple_type == 2) ? OneMinusLambda : Lambda;
317  TuplePatchElem *p;
318  p = this->tuplePatchList.find(TuplePatchElem(homepatch));
319  for(i=0; i < T::size; i++) {
320  t.p[i] = p;
321  t.localIndex[i] = aid[i].index;
322  }
323  #ifdef MEM_OPT_VERSION
324  //avoid adding Tuples whose atoms are all fixed
325  if(node->simParameters->fixedAtomsOn &&
327  int allfixed = 1;
328  for(i=0; i<T::size; i++){
329  CompAtomExt *one = &(p->xExt[aid[i].index]);
330  allfixed = allfixed & one->atomFixed;
331  }
332  if(!allfixed) this->tupleList.add(t);
333  }else{
334  this->tupleList.add(t);
335  }
336  #else
337  this->tupleList.add(t);
338  #endif
339  }
340  }
341  }
342  }
343  }
344 #endif
345 
346  PatchID patchID;
347 
348  public:
349 
351  patchID = p;
352  }
353 
354  virtual ~ComputeSelfTuples() {
355  UniqueSetIter<TuplePatchElem> ap(this->tuplePatchList);
356  for (ap = ap.begin(); ap != ap.end(); ap++) {
357  ap->p->unregisterPositionPickup(this,&(ap->positionBox));
358  ap->p->unregisterAvgPositionPickup(this,&(ap->avgPositionBox));
359  ap->p->unregisterForceDeposit(this,&(ap->forceBox));
360  }
361  }
362 
363 
364  //======================================================================
365  // initialize() - Method is invoked only the first time
366  // atom maps, patchmaps etc are ready and we are about to start computations
367  //======================================================================
368  virtual void initialize(void) {
369 #ifdef USE_HOMETUPLES
370  this->tuples = new SelfTuples<T, S, P>();
371 #endif
372  // Start with empty list
373  this->tuplePatchList.clear();
374 
375  this->tuplePatchList.add(TuplePatchElem(ComputeHomeTuples<T,S,P>::patchMap->patch(patchID), this));
376 
377  this->setNumPatches(this->tuplePatchList.size());
378 
379  this->doLoadTuples = true;
380 
381  int myNode = CkMyPe();
382  if ( PatchMap::Object()->node(patchID) != myNode )
383  {
384  this->basePriority = COMPUTE_PROXY_PRIORITY + PATCH_PRIORITY(patchID);
385  }
386  else
387  {
388  this->basePriority = COMPUTE_HOME_PRIORITY + PATCH_PRIORITY(patchID);
389  }
390  }
391 
392  void doWork(void) {
393 // LdbCoordinator::Object()->startWork(this->ldObjHandle);
394 
395 #ifdef TRACE_COMPUTE_OBJECTS
396  double traceObjStartTime = CmiWallTimer();
397 #endif
398 
400 
401 #ifdef TRACE_COMPUTE_OBJECTS
402  traceUserBracketEvent(TRACE_COMPOBJ_IDOFFSET+this->cid, traceObjStartTime, CmiWallTimer());
403 #endif
404 
405 // LdbCoordinator::Object()->endWork(this->ldObjHandle);
406  }
407 
408 };
409 
410 
411 #endif
412 
static Node * Object()
Definition: Node.h:86
Elem * find(const Elem &elem)
Definition: UniqueSet.h:60
#define COMPUTE_PROXY_PRIORITY
Definition: Priorities.h:71
int num_alch_unpert_Dihedrals
Definition: Molecule.h:603
int getNumAtoms() const
Definition: Patch.h:105
int size(void) const
Definition: UniqueSet.h:58
void unregisterAvgPositionPickup(Compute *cid, Box< Patch, CompAtom > **const box)
Definition: Patch.C:139
Definition: Node.h:78
#define TRACE_COMPOBJ_IDOFFSET
Definition: Compute.h:77
void clear(void)
Definition: UniqueSet.h:62
int32 ComputeID
Definition: NamdTypes.h:278
static void partition(int *order, const FullAtom *atoms, int begin, int end)
Definition: SortAtoms.C:45
int32 atom3
Definition: structures.h:67
static PatchMap * Object()
Definition: PatchMap.h:27
Angle * alch_unpert_angles
Definition: Molecule.h:605
SimParameters * simParameters
Definition: Node.h:181
int num_alch_unpert_Bonds
Definition: Molecule.h:601
float Real
Definition: common.h:118
int32_t int32
Definition: common.h:38
void unregisterForceDeposit(Compute *cid, Box< Patch, Results > **const box)
Definition: Patch.C:238
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
int num_alch_unpert_Angles
Definition: Molecule.h:602
unsigned char get_ss_type(int anum) const
Definition: Molecule.h:1443
int add(const Elem &elem)
Definition: UniqueSet.h:52
#define iout
Definition: InfoStream.h:51
BigReal alchLambda
Dihedral * alch_unpert_dihedrals
Definition: Molecule.h:606
Definition: Patch.h:35
virtual ~ComputeSelfTuples()
Flags flags
Definition: Patch.h:128
UniqueSetIter< T > begin(void) const
Definition: UniqueSetIter.h:55
int32 index
Definition: NamdTypes.h:290
uint32 id
Definition: NamdTypes.h:156
int32 atom4
Definition: structures.h:68
int32 atom1
Definition: structures.h:50
#define COMPUTE_HOME_PRIORITY
Definition: Priorities.h:76
int32 atom2
Definition: structures.h:58
BigReal soluteScalingFactor
ComputeSelfTuples(ComputeID c, PatchID p)
int32 atom1
Definition: structures.h:57
int Bool
Definition: common.h:142
CompAtomList p
Definition: Patch.h:153
LocalID localID(AtomID id)
Definition: AtomMap.h:78
int32 atom3
Definition: structures.h:59
Bond * alch_unpert_bonds
Definition: Molecule.h:604
Box< Patch, CompAtom > * positionBox
UniqueSetIter< T > end(void) const
Definition: UniqueSetIter.h:64
virtual void doWork(void)
PatchID pid
Definition: NamdTypes.h:289
int32 atom2
Definition: structures.h:66
unsigned char get_fep_type(int anum) const
Definition: Molecule.h:1432
void unregisterPositionPickup(Compute *cid, Box< Patch, CompAtom > **const box)
Definition: Patch.C:121
Parameters * parameters
Definition: Node.h:180
Box< Patch, CompAtom > * avgPositionBox
virtual void initialize(void)
CompAtomExt * xExt
uint32 atomFixed
Definition: NamdTypes.h:158
int32 PatchID
Definition: NamdTypes.h:277
Molecule * molecule
Definition: Node.h:179
Box< Patch, Results > * forceBox
int32 atom1
Definition: structures.h:65
int32 atom2
Definition: structures.h:51
double BigReal
Definition: common.h:123
int step
Definition: PatchTypes.h:16
#define PATCH_PRIORITY(PID)
Definition: Priorities.h:25