NAMD
ReductionMgr.h
Go to the documentation of this file.
1 
7 #ifndef REDUCTIONMGR_H
8 #define REDUCTIONMGR_H
9 
10 #include "charm++.h"
11 
12 #include "main.h"
13 #include "NamdTypes.h"
14 #include "BOCgroup.h"
15 #include "ProcessorPrivate.h"
16 #include <atomic>
17 
18 #define VECTOR(A) A ## _X, A ## _Y, A ## _Z
19 #define TENSOR(A) A ## _XX, A ## _XY, A ## _XZ, \
20  A ## _YX, A ## _YY, A ## _YZ, \
21  A ## _ZX, A ## _ZY, A ## _ZZ
22 
23 #define ADD_VECTOR(R,RL,D,DL) \
24  R->item( RL ## _X ) += D[ DL ## _X ]; \
25  R->item( RL ## _Y ) += D[ DL ## _Y ]; \
26  R->item( RL ## _Z ) += D[ DL ## _Z ]
27 
28 #define ADD_VECTOR_OBJECT(R,RL,D) \
29  R->item( RL ## _X ) += D.x; \
30  R->item( RL ## _Y ) += D.y; \
31  R->item( RL ## _Z ) += D.z
32 
33 #define ADD_TENSOR(R,RL,D,DL) \
34  R->item( RL ## _XX) += D[ DL ## _XX ]; \
35  R->item( RL ## _XY) += D[ DL ## _XY ]; \
36  R->item( RL ## _XZ) += D[ DL ## _XZ ]; \
37  R->item( RL ## _YX) += D[ DL ## _YX ]; \
38  R->item( RL ## _YY) += D[ DL ## _YY ]; \
39  R->item( RL ## _YZ) += D[ DL ## _YZ ]; \
40  R->item( RL ## _ZX) += D[ DL ## _ZX ]; \
41  R->item( RL ## _ZY) += D[ DL ## _ZY ]; \
42  R->item( RL ## _ZZ) += D[ DL ## _ZZ ]
43 
44 #define ADD_TENSOR_OBJECT(R,RL,D) \
45  R->item( RL ## _XX) += D.xx; \
46  R->item( RL ## _XY) += D.xy; \
47  R->item( RL ## _XZ) += D.xz; \
48  R->item( RL ## _YX) += D.yx; \
49  R->item( RL ## _YY) += D.yy; \
50  R->item( RL ## _YZ) += D.yz; \
51  R->item( RL ## _ZX) += D.zx; \
52  R->item( RL ## _ZY) += D.zy; \
53  R->item( RL ## _ZZ) += D.zz
54 
55 #define GET_VECTOR(O,R,A) \
56  O.x = R->item( A ## _X ); \
57  O.y = R->item( A ## _Y ); \
58  O.z = R->item( A ## _Z )
59 
60 #define GET_TENSOR(O,R,A) \
61  O.xx = R->item( A ## _XX); \
62  O.xy = R->item( A ## _XY); \
63  O.xz = R->item( A ## _XZ); \
64  O.yx = R->item( A ## _YX); \
65  O.yy = R->item( A ## _YY); \
66  O.yz = R->item( A ## _YZ); \
67  O.zx = R->item( A ## _ZX); \
68  O.zy = R->item( A ## _ZY); \
69  O.zz = R->item( A ## _ZZ)
70 
71 typedef enum
72 {
73  // energy
91  // REDUCTION_THOLE_ENERGY - Drude model "correction" to electrostatic energy
92  // REDUCTION_ANISO_ENERGY - Drude model add into bond energy
112  // pressure
113  TENSOR(REDUCTION_VIRIAL_NORMAL),
114  TENSOR(REDUCTION_VIRIAL_NBOND),
115  TENSOR(REDUCTION_VIRIAL_SLOW),
116  TENSOR(REDUCTION_VIRIAL_AMD_DIHE),
117 #ifdef ALTVIRIAL
118  TENSOR(REDUCTION_ALT_VIRIAL_NORMAL),
119  TENSOR(REDUCTION_ALT_VIRIAL_NBOND),
120  TENSOR(REDUCTION_ALT_VIRIAL_SLOW),
121 #endif
122  TENSOR(REDUCTION_INT_VIRIAL_NORMAL),
123  TENSOR(REDUCTION_INT_VIRIAL_NBOND),
124  TENSOR(REDUCTION_INT_VIRIAL_SLOW),
125  VECTOR(REDUCTION_EXT_FORCE_NORMAL),
126  VECTOR(REDUCTION_EXT_FORCE_NBOND),
127  VECTOR(REDUCTION_EXT_FORCE_SLOW),
128  // momentum
129  VECTOR(REDUCTION_MOMENTUM),
130  TENSOR(REDUCTION_MOMENTUM_SQUARED), // Multigrator
131  VECTOR(REDUCTION_ANGULAR_MOMENTUM),
132  VECTOR(REDUCTION_HALFSTEP_MOMENTUM),
134  // used for minimization
139  // used for pair interaction calculations
140  VECTOR(REDUCTION_PAIR_VDW_FORCE),
141  VECTOR(REDUCTION_PAIR_ELECT_FORCE),
142  // checksum
149  REDUCTION_THOLE_CHECKSUM, // Drude model
150  REDUCTION_ANISO_CHECKSUM, // Drude model
155 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
157 #endif
161  // semaphore (must be last)
163 } ReductionTag;
164 
165 typedef enum {
167  TENSOR(MULTIGRATOR_REDUCTION_MOMENTUM_SQUARED),
168  // semaphore
171 
172 // Later this can be dynamic
173 enum {
180  REDUCTIONS_AMD, // for accelMD
185  // semaphore (must be last)
187 };
188 
189 // Later this can be dynamic
190 #define REDUCTION_MAX_CHILDREN 4
191 
193 class ReductionSubmitMsg;
194 class SubmitReduction;
197 class RequireReduction;
200 
201 // Queue element which stores data for a particular sequence number
203 public:
208  ReductionSetData(int seqNum, int size) {
209  sequenceNumber = seqNum;
210  submitsRecorded = 0;
211  data = new BigReal[size];
212  for ( int i = 0; i < size; ++i ) { data[i] = 0; }
213  next = 0;
214  }
216  delete [] data;
217  }
218 };
219 
220 // Stores the submit queue for a particular set of reductions
222 public:
226  int dataSize;
228  ReductionSetData* getData(int seqNum);
229  ReductionSetData* removeData(int seqNum); // removes from queue
230  int requireRegistered; // is a thread subscribed on this node?
231  int threadIsWaiting; // is there a thread waiting on this?
232  int waitingForSequenceNumber; // sequence number waited for
233  CthThread waitingThread;
234  ReductionSet(int setID, int size,int numChildren);
235  ~ReductionSet();
237 };
238 
239 // Top level class
240 // don't derive from CBase_ReductionMgr to avoid .decl.h file
241 class ReductionMgr : public Group
242 {
243 private:
244  friend class SubmitReduction;
245  friend class SubmitReductionCharm;
246  friend class SubmitReductionShared;
247  friend class RequireReduction;
248  friend class RequireReductionCharm;
250 
251  ReductionSet * (reductionSets[REDUCTION_MAX_SET_ID]);
252 
253  int myParent; // parent node or -1 if none
254 #if 0
255  int firstChild, lastChild; // firstChild <= children < lastChild
256  int isMyChild(int nodeID) const {
257  return ( nodeID >= firstChild && nodeID < lastChild );
258  }
259 #endif
260  int numChildren;
261  int *children;
262  int isMyChild(int nodeID) const {
263  int i;
264  for(i=0;i<numChildren;i++)
265  if (children[i]==nodeID) return 1;
266  return 0;
267  }
268  int childIndex(int nodeID) const {
269  int i;
270  for(i=0;i<numChildren;i++)
271  if (children[i]==nodeID) return i;
272  return -1;
273  }
274  int isRoot(void) const { return ( myParent == -1 ); }
275 
276  ReductionSet* getSet(int setID, int size);
277  void delSet(int setID);
278 
279  void mergeAndDeliver(ReductionSet *set, int seqNum);
280 
281  void submit(SubmitReductionCharm*);
282  void remove(SubmitReductionCharm*);
283 
285  void remove(RequireReductionCharm*);
286 
287 public:
288 
289  // Singleton Access method
290  inline static ReductionMgr *Object(void) {
291  return CkpvAccess(ReductionMgr_instance);
292  }
293 
294  ReductionMgr();
295  ~ReductionMgr();
296 
297  void buildSpanTree(const int pe,
298  const int max_intranode_children,
299  const int max_internode_children,
300  int* parent,
301  int* num_children,
302  int** children);
303 
304  /*
305  * Client Interface
306  *
307  * These functions are called by the various clients of the reduction to get
308  * submission and require objects used to call the actual reduction. If
309  * GPUresidentSingleProcessMode is true, these will return shared memory variants
310  * otherwise, they will return the usual Charm++ based variants.
311  *
312  */
313  SubmitReduction* willSubmit(int setID, int size = -1);
314  RequireReduction* willRequire(int setID, int size = -1);
315 
316  // message entry points
319  void remoteSubmit(ReductionSubmitMsg *msg);
320 
321 };
322 
323 /*
324  * @brief Parent class for reduction clients submissions
325  */
327 protected:
328  BigReal *data; // managed explicitly by master
329 public:
330  /*
331  * @brief Returns a reference to an element of the reduction set
332  *
333  * @param i Index of element to return
334  * @returns Reference to given element in reduction set
335  */
336  BigReal& item(int i) {
337  return data[i];
338  }
339 
340  /*
341  * @brief Updates the reduction set if the given element is larger that current value
342  *
343  * This function will update the specified element of the reduction set with the maximum of the given value
344  * and that elements current value
345  *
346  * @param i Index of element to test against
347  * @param v Potential new value
348  */
349  void max(int i, BigReal v) {
350  if ( v > data[i] ) {
351  data[i] = v;
352  }
353  }
354 
355  /*
356  * @brief Adds an array of elements to the reduction set
357  *
358  * @param nitems The number of items to add
359  * @param arr Pointer to array of BigReals container data to add
360  */
361  void add(int nitems, const BigReal *arr) {
362  for (int i=0; i<nitems; i++) data[i] += arr[i];
363  }
364 
365  /*
366  * @brief Submits the reduction values held by this object
367  *
368  * This function will have a different implementation for the Charm++ and shared memory backends
369  *
370  */
371  virtual void submit(void) = 0;
372 
373  virtual ~SubmitReduction(void) {};
374 };
375 
376 /*
377  * @brief Charm++ class for reduction clients submissions
378  *
379  * This class will perform reductions with the usual Charm++
380  * mechanisms
381  */
383 private:
384  friend class ReductionMgr;
385 protected:
389 
390 public:
391  void submit(void) override {
392  master->submit(this);
393  }
394  ~SubmitReductionCharm(void) { master->remove(this); }
395 };
396 
397 /*
398  * @brief Parent class for reduction require clients
399  */
401 protected:
403 public:
404  BigReal item(int i) const { return data[i]; }
405  virtual void require(const bool clearData = true) = 0;
406 
407  virtual ~RequireReduction() {};
408 };
409 
410 /*
411  * @brief Charm++ class for reduction require clients
412  *
413  * This class will perform reductions with the usual Charm++
414  * mechanisms
415  */
417 private:
418  friend class ReductionMgr;
419  RequireReductionCharm(void) { currentData = 0; data = 0; }
420  int reductionSetID;
421  int sequenceNumber;
423  ReductionSetData *currentData;
424 public:
425  void require(const bool clearData) override {
426  master->require(this);
427  }
428  ~RequireReductionCharm(void) { delete currentData; master->remove(this); }
429 };
430 
431 /*
432  * @brief Single reduction value using locks to avoid race conditions
433  */
435 public:
436  double reducedValue;
437  CmiNodeLock valueLock;
438  ReductionValue();
439  ReductionValue(double );
440  ~ReductionValue();
441  double operator+=(double other);
442  double operator+=(int other);
443  double operator+=(unsigned int other);
444  double operator=(double& other);
445  operator double();
446  operator int();
447  void increment_no_lock(double rvalue);
448 };
449 
450 /*
451  * @brief Set of reduction values used for single node reductions
452  */
454 public:
456  NodeReduction();
457  ~NodeReduction();
458  void zero();
459  void zero_lock();
460  void setVal(const NodeReduction *other);
461  ReductionValue& operator[](int index);
462  ReductionValue& item(int index);
463 };
464 
465 /*
466  * @brief Shared memory class for reduction client submissions
467  */
469 private:
470  NodeReduction* nodeReduction;
472 public:
473  /*
474  * For shared memory reductions, the submit function copies data from this objects
475  * local storage to the singleton NodeReduction object. Instead of using a
476  * different lock for each object, it will use the lock of the zeroth element.
477  *
478  * This function also zeros out its own data after it has been contributed
479  */
480  void submit(void) override {
481  CmiLock(nodeReduction->set[0].valueLock);
482  for (int i = 0; i < REDUCTION_MAX_RESERVED; i++) {
483  if (data[i] != 0.0) {
484  nodeReduction->item(i).increment_no_lock(data[i]);
485  data[i] = 0.0;
486  }
487  }
488  CmiUnlock(nodeReduction->set[0].valueLock);
489  }
491  SubmitReductionShared(void);
492 };
493 
494 /*
495  * @brief Shared memory class for reduction client requires
496  */
498 private:
499  NodeReduction* nodeReduction;
501 
502 public:
503  /*
504  * For shared memory reductions, the submit function copies data from the singleton
505  * reduction object to its own data buffer. Similar to the submit function, it uses
506  * a single lock to perform the copy.
507  *
508  * This function will optionally zero out the data from the singleton
509  */
510  void require(const bool clearData) override {
511  CmiLock(nodeReduction->set[0].valueLock);
512  for (int i = 0; i < REDUCTION_MAX_RESERVED; i++) {
513  my_data[i] = (BigReal) nodeReduction->item(i);
514  }
515  if (clearData) {
516  nodeReduction->zero();
517  }
518  CmiUnlock(nodeReduction->set[0].valueLock);
519  };
520 
523 };
524 
525 
526 #endif
527 
void max(int i, BigReal v)
Definition: ReductionMgr.h:349
void buildSpanTree(const int pe, const int max_intranode_children, const int max_internode_children, int *parent, int *num_children, int **children)
Definition: ReductionMgr.C:122
int nextSequenceNumber
Definition: ReductionMgr.h:224
ReductionValue & operator[](int index)
Definition: ReductionMgr.C:654
ReductionSetData * next
Definition: ReductionMgr.h:207
ReductionSetData(int seqNum, int size)
Definition: ReductionMgr.h:208
void submit(void) override
Definition: ReductionMgr.h:480
int * addToRemoteSequenceNumber
Definition: ReductionMgr.h:236
friend class RequireReductionCharm
Definition: ReductionMgr.h:248
MultigratorReductionTag
Definition: ReductionMgr.h:165
virtual void require(const bool clearData=true)=0
virtual void submit(void)=0
ReductionSetData * getData(int seqNum)
Definition: ReductionMgr.C:91
BigReal & item(int i)
Definition: ReductionMgr.h:336
ReductionSet(int setID, int size, int numChildren)
Definition: ReductionMgr.C:60
void remoteRegister(ReductionRegisterMsg *msg)
Definition: ReductionMgr.C:426
SubmitReduction * willSubmit(int setID, int size=-1)
Definition: ReductionMgr.C:368
static ReductionMgr * Object(void)
Definition: ReductionMgr.h:290
double operator+=(double other)
Definition: ReductionMgr.C:609
void require(const bool clearData) override
Definition: ReductionMgr.h:425
CmiNodeLock valueLock
Definition: ReductionMgr.h:437
void submit(void) override
Definition: ReductionMgr.h:391
void zero_lock()
Definition: ReductionMgr.C:671
void add(int nitems, const BigReal *arr)
Definition: ReductionMgr.h:361
ReductionValue & item(int index)
Definition: ReductionMgr.C:658
CthThread waitingThread
Definition: ReductionMgr.h:233
int waitingForSequenceNumber
Definition: ReductionMgr.h:232
int requireRegistered
Definition: ReductionMgr.h:230
ReductionSetData * removeData(int seqNum)
Definition: ReductionMgr.C:106
int submitsRegistered
Definition: ReductionMgr.h:225
ReductionValue set[REDUCTION_MAX_RESERVED]
Definition: ReductionMgr.h:455
double operator=(double &other)
void remoteSubmit(ReductionSubmitMsg *msg)
Definition: ReductionMgr.C:460
void require(const bool clearData) override
Definition: ReductionMgr.h:510
#define TENSOR(A)
Definition: ReductionMgr.h:19
ReductionTag
Definition: ReductionMgr.h:71
BigReal item(int i) const
Definition: ReductionMgr.h:404
void increment_no_lock(double rvalue)
Definition: ReductionMgr.C:634
void setVal(const NodeReduction *other)
Definition: ReductionMgr.C:681
RequireReduction * willRequire(int setID, int size=-1)
Definition: ReductionMgr.C:539
#define VECTOR(A)
Definition: ReductionMgr.h:18
virtual ~SubmitReduction(void)
Definition: ReductionMgr.h:373
ReductionMgr * master
Definition: ReductionMgr.h:388
void remoteUnregister(ReductionRegisterMsg *msg)
Definition: ReductionMgr.C:445
double reducedValue
Definition: ReductionMgr.h:436
virtual ~RequireReduction()
Definition: ReductionMgr.h:407
double BigReal
Definition: common.h:123
ReductionSetData * dataQueue
Definition: ReductionMgr.h:227
BigReal * data
Definition: ReductionMgr.h:328