NAMD
ReductionMgr.C
Go to the documentation of this file.
1 
7 /*
8  The order of execution is expected to be:
9  0. instantiate object
10  ------------------ (processing barrier)
11  (mode 0) 1. register() and subscribe()
12  ------------------
13  (mode 1) 2. submit() and request()
14  ------------------
15  (mode 2) 3. unregister() and unsubscribe()
16  ------------------ (processing barrier)
17  4. destroy object
18  Doing this out-of-order will cause errors.
19 
20  Assumes that *only* one thread will require() a specific sequence's data.
21 */
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 
26 #include "InfoStream.h"
27 #include "PatchMap.h" // for patchMap
28 
29 #include "Node.h"
30 #include "SimParameters.h"
31 
32 #include "ReductionMgr.decl.h"
33 #include "ReductionMgr.h"
34 
35 #include "PatchData.h"
36 
37 // #define DEBUGM
38 #define MIN_DEBUG_LEVEL 4
39 #include "Debug.h"
40 #include <atomic>
41 
42 // Used to register and unregister reductions to downstream nodes
43 class ReductionRegisterMsg : public CMessage_ReductionRegisterMsg {
44 public:
46  int dataSize;
48 };
49 
50 // Used to send reduction data to downstream nodes
51 class ReductionSubmitMsg : public CMessage_ReductionSubmitMsg {
52 public:
56  int dataSize;
58 };
59 
60 ReductionSet::ReductionSet(int setID, int size, int numChildren) {
61  if ( setID == REDUCTIONS_BASIC || setID == REDUCTIONS_AMD || setID == REDUCTIONS_GPURESIDENT ) {
62  if ( size != -1 ) {
63  NAMD_bug("ReductionSet size specified for REDUCTIONS_BASIC or REDUCTIONS_AMD.");
64  }
66  }
67  if ( size == -1 ) NAMD_bug("ReductionSet size not specified.");
68  dataSize = size;
69  reductionSetID = setID;
72  dataQueue = 0;
74  threadIsWaiting = 0;
75  addToRemoteSequenceNumber = new int[numChildren];
76 }
77 
79 
80  ReductionSetData *current = dataQueue;
81 
82  while ( current ) {
83  ReductionSetData *next = current->next;
84  delete current;
85  current = next;
86  }
87  delete [] addToRemoteSequenceNumber;
88 }
89 
90 // possibly create and return data for a particular seqNum
92 
93  ReductionSetData **current = &dataQueue;
94 
95  while ( *current ) {
96  if ( (*current)->sequenceNumber == seqNum ) return *current;
97  current = &((*current)->next);
98  }
99 
100 //iout << "seq " << seqNum << " created on " << CkMyPe() << "\n" << endi;
101  *current = new ReductionSetData(seqNum, dataSize);
102  return *current;
103 }
104 
105 // possibly delete data for a particular seqNum
107 
108  ReductionSetData **current = &dataQueue;
109 
110  while ( *current ) {
111  if ( (*current)->sequenceNumber == seqNum ) break;
112  current = &((*current)->next);
113  }
114 
115  if ( ! *current ) { NAMD_die("ReductionSet::removeData on missing seqNum"); }
116 
117  ReductionSetData *toremove = *current;
118  *current = (*current)->next;
119  return toremove;
120 }
121 
122 void ReductionMgr::buildSpanTree(const int pe,
123  const int max_intranode_children,
124  const int max_internode_children,
125  int* parent,
126  int* num_children,
127  int** children)
128 {
129  // If pe is a first-node, children are same-node pes and perhaps some
130  // other first-nodes, and parents are other first-nodes. If pe is not a
131  // first-node, build the spanning tree among the children, and the parent
132  // is the corresponding first-node
133 
134  // No matter what, build list of PEs on my node first
135  const int num_pes = CkNumPes();
136  const int num_node_pes = CmiNumPesOnPhysicalNode(CmiPhysicalNodeID(pe));
137  int *node_pes = new int[num_node_pes];
138  int pe_index = -1;
139  const int first_pe = CmiGetFirstPeOnPhysicalNode(CmiPhysicalNodeID(pe));
140  int num_nodes = 0;
141  int *node_ids = new int[num_pes];
142  int first_pe_index = -1;
143  int my_parent_index;
144 
145  // Make sure PE 0 is a first-node
146  if (pe == 0 && first_pe != pe) {
147  NAMD_die("PE 0 is not the first physical node. This shouldn't happen");
148  }
149  // Get all the PEs on my node, and also build the list of all first-nodes
150  int i;
151  int node_pe_count=0;
152  for (i = 0; i < num_pes; i++) {
153  // Save first-nodes
154  if (CmiGetFirstPeOnPhysicalNode(CmiPhysicalNodeID(i)) == i) {
155  node_ids[num_nodes] = i;
156  if (i == first_pe)
157  first_pe_index = num_nodes;
158  num_nodes++;
159  }
160 
161  // Also, find pes on my node
162  const int i1 = (i + first_pe) % num_pes;
163  if (CmiPeOnSamePhysicalNode(first_pe,i1)) {
164  if ( node_pe_count == num_node_pes )
165  NAMD_bug("ReductionMgr::buildSpanTree found inconsistent physical node data from Charm++ runtime");
166  node_pes[node_pe_count] = i1;
167  if (pe == i1)
168  pe_index = node_pe_count;
169  node_pe_count++;
170  }
171  }
172  if ( pe_index < 0 || first_pe_index < 0 )
173  NAMD_bug("ReductionMgr::buildSpanTree found inconsistent physical node data from Charm++ runtime");
174 
175  // Any PE might have children on the same node, plus, if its a first-node,
176  // it may have several children on other nodes
177 
178  int first_loc_child_index = pe_index * max_intranode_children + 1;
179  int last_loc_child_index
180  = first_loc_child_index + max_intranode_children - 1;
181  if (first_loc_child_index > num_node_pes) {
182  first_loc_child_index = num_node_pes;
183  last_loc_child_index = num_node_pes;
184  } else {
185  if (last_loc_child_index >= num_node_pes)
186  last_loc_child_index = num_node_pes-1;
187  }
188 // CkPrintf("Local [%d] firstpe %d max %d num %d firstloc %d lastloc %d\n",
189 // pe,pe_index,max_intranode_children,num_node_pes,
190 // first_loc_child_index,last_loc_child_index);
191 
192  int first_rem_child_index = num_nodes;
193  int last_rem_child_index = num_nodes;
194  int rem_children=0;
195  int *rem_child_index = new int[max_internode_children];
196 
197  if (first_pe != pe) {
198  // I'm not a first_pe, so I have no more children, and my parent
199  // is someone else on my node
200  my_parent_index = (pe_index-1)/max_intranode_children;
201  *parent = node_pes[my_parent_index];
202  } else {
203  // I am a first_pe, so I may have additional children
204  // on other nodes, and my parent will be on another node
205 
206  int range_begin = 0;
207  int range_end = num_nodes;
208 
209  if (pe == 0) {
210  my_parent_index = -1;
211  *parent = -1;
212  } else {
213  my_parent_index = 0;
214  while ( first_pe_index != range_begin ) {
215  my_parent_index = range_begin;
216  ++range_begin;
217  for ( int i = 0; i < max_internode_children; ++i ) {
218  int split = range_begin + ( range_end - range_begin ) / ( max_internode_children - i );
219  if ( first_pe_index < split ) { range_end = split; break; }
220  else { range_begin = split; }
221  }
222  }
223  *parent = node_ids[my_parent_index];
224  }
225 
226  // now we know parent and need only repeat calculation of children
227  int prev_child_index = range_begin;
228  ++range_begin;
229  for ( int i = 0; i < max_internode_children; ++i ) {
230  if ( range_begin >= range_end ) break;
231  if ( range_begin > prev_child_index ) {
232  rem_child_index[rem_children++] = prev_child_index = range_begin;
233  }
234  range_begin += ( range_end - range_begin ) / ( max_internode_children - i );
235  }
236  }
237 
238  *num_children = 0;
239  //CkPrintf("TREE pe %d my_parent %d %d\n",pe,my_parent_index,*parent);
240 
241  int loc_children=0;
242  if (first_loc_child_index != num_node_pes) {
243  loc_children = last_loc_child_index - first_loc_child_index + 1;
244  *num_children += loc_children;
245 // CkPrintf("TREE pe %d %d local children\n",pe,loc_children);
246 // } else {
247 // CkPrintf("TREE pe %d No local children\n",pe);
248  }
249 
250  if (rem_children) {
251  *num_children += rem_children;
252 // CkPrintf("TREE pe %d %d rem children\n",pe,rem_children);
253 // } else {
254 // CkPrintf("TREE pe %d No rem children\n",pe);
255  }
256  if (*num_children == 0)
257  *children = 0;
258  else {
259  *children = new int[*num_children];
260 // CkPrintf("TREE pe %d children %d\n",pe,*num_children);
261  int k;
262  int child=0;
263  if (loc_children > 0) {
264  for(k=first_loc_child_index; k <= last_loc_child_index; k++) {
265 // CkPrintf("TREE pe %d loc child[%d,%d] %d\n",pe,child,k,node_pes[k]);
266  (*children)[child++]=node_pes[k];
267  }
268  }
269  if (rem_children > 0) {
270  for(k=0; k < rem_children; k++) {
271 // CkPrintf("TREE pe %d rem child[%d,%d] %d\n",pe,child,k,node_ids[rem_child_index[k]]);
272  (*children)[child++]=node_ids[rem_child_index[k]];
273  }
274  }
275  }
276  delete [] rem_child_index;
277  delete [] node_ids;
278  delete [] node_pes;
279 }
280 
281 // constructor
283  if (CkpvAccess(ReductionMgr_instance) == 0) {
284  CkpvAccess(ReductionMgr_instance) = this;
285  } else {
286  DebugM(1, "ReductionMgr::ReductionMgr() - another instance exists!\n");
287  }
288 
290  &myParent,&numChildren,&children);
291 
292 // CkPrintf("TREE [%d] parent %d %d children\n",
293 // CkMyPe(),myParent,numChildren);
294 // if (numChildren > 0) {
295 // for(int i=0; i < numChildren; i++) {
296 // CkPrintf("TREE [%d] child %d %d\n",CkMyPe(),i,children[i]);
297 // }
298 // }
299 
300  // fill in the spanning tree fields
301 #if 0 // Old spanning tree
302  if (CkMyPe() == 0) {
303  myParent = -1;
304  } else {
305  myParent = (CkMyPe()-1)/REDUCTION_MAX_CHILDREN;
306  }
307  firstChild = CkMyPe()*REDUCTION_MAX_CHILDREN + 1;
308  if (firstChild > CkNumPes()) firstChild = CkNumPes();
309  lastChild = firstChild + REDUCTION_MAX_CHILDREN;
310  if (lastChild > CkNumPes()) lastChild = CkNumPes();
311 #endif
312 
313  // initialize data
314  for(int i=0; i<REDUCTION_MAX_SET_ID; i++) {
315  reductionSets[i] = 0;
316  }
317 
318  DebugM(1,"ReductionMgr() instantiated.\n");
319 }
320 
321 // destructor
323  if (children != 0)
324  delete [] children;
325  for(int i=0; i<REDUCTION_MAX_SET_ID; i++) {
326  delete reductionSets[i];
327  }
328 
329 }
330 
331 // possibly create and return reduction set
332 ReductionSet* ReductionMgr::getSet(int setID, int size) {
333  if ( reductionSets[setID] == 0 ) {
334  reductionSets[setID] = new ReductionSet(setID,size,numChildren);
335  if ( ! isRoot() ) {
337  msg->reductionSetID = setID;
338  msg->dataSize = size;
339  msg->sourceNode = CkMyPe();
340  CProxy_ReductionMgr reductionProxy(thisgroup);
341  reductionProxy[myParent].remoteRegister(msg);
342  }
343  } else if ( setID == REDUCTIONS_BASIC || setID == REDUCTIONS_AMD || setID == REDUCTIONS_GPURESIDENT ) {
344  if ( size != -1 ) NAMD_bug("ReductionMgr::getSet size set");
345  } else if ( size < 0 || reductionSets[setID]->dataSize != size ) {
346  NAMD_bug("ReductionMgr::getSet size mismatch");
347  }
348  return reductionSets[setID];
349 }
350 
351 // possibly delete reduction set
352 void ReductionMgr::delSet(int setID) {
353  ReductionSet *set = reductionSets[setID];
354  if ( set && ! set->submitsRegistered & ! set->requireRegistered ) {
355  if ( ! isRoot() ) {
357  msg->reductionSetID = setID;
358  msg->sourceNode = CkMyPe();
359  CProxy_ReductionMgr reductionProxy(thisgroup);
360  reductionProxy[myParent].remoteUnregister(msg);
361  }
362  delete set;
363  reductionSets[setID] = 0;
364  }
365 }
366 
367 // register local submit
370 
371  SubmitReduction *handle;
372  // Only use the shared memory reductions for GPU-resident dynamics
373  if (simParams->GPUresidentSingleProcessMode && setID == REDUCTIONS_GPURESIDENT) {
374  handle = new SubmitReductionShared;
375  } else {
376  ReductionSet *set = getSet(setID, size);
377  ReductionSetData *data = set->getData(set->nextSequenceNumber);
378  if ( data->submitsRecorded ) {
379  NAMD_die("ReductionMgr::willSubmit called while reductions outstanding!");
380  }
381 
382  set->submitsRegistered++;
383 
384  SubmitReductionCharm* charm_handle = new SubmitReductionCharm;
385  charm_handle->reductionSetID = setID;
386  charm_handle->sequenceNumber = set->nextSequenceNumber;
387  charm_handle->master = this;
388  charm_handle->data = data->data;
389 
390  handle = (SubmitReduction*) charm_handle;
391  }
392 
393  return handle;
394 }
395 
396 // unregister local submit
397 void ReductionMgr::remove(SubmitReductionCharm* handle) {
398  int setID = handle->reductionSetID;
399  ReductionSet *set = reductionSets[setID];
400  if ( set->getData(set->nextSequenceNumber)->submitsRecorded ) {
401  NAMD_die("SubmitReduction deleted while reductions outstanding!");
402  }
403 
404  set->submitsRegistered--;
405 
406  delSet(setID);
407 }
408 
409 // local submit
410 void ReductionMgr::submit(SubmitReductionCharm* handle) {
411  int setID = handle->reductionSetID;
412  int seqNum = handle->sequenceNumber;
413  ReductionSet *set = reductionSets[setID];
414  ReductionSetData *data = set->getData(seqNum);
415 
416  data->submitsRecorded++;
417  if ( data->submitsRecorded == set->submitsRegistered ) {
418  mergeAndDeliver(set,seqNum);
419  }
420 
421  handle->sequenceNumber = ++seqNum;
422  handle->data = set->getData(seqNum)->data;
423 }
424 
425 // register submit from child
427 
428  int setID = msg->reductionSetID;
429  int size = msg->dataSize;
430  ReductionSet *set = getSet(setID,size);
431  if ( set->getData(set->nextSequenceNumber)->submitsRecorded ) {
432  NAMD_die("ReductionMgr::remoteRegister called while reductions outstanding on parent!");
433  }
434 
435  set->submitsRegistered++;
436  set->addToRemoteSequenceNumber[childIndex(msg->sourceNode)]
437  = set->nextSequenceNumber;
438 // CkPrintf("[%d] reduction register received from node[%d] %d\n",
439 // CkMyPe(),childIndex(msg->sourceNode),msg->sourceNode);
440 
441  delete msg;
442 }
443 
444 // unregister submit from child
446 
447  int setID = msg->reductionSetID;
448  ReductionSet *set = reductionSets[setID];
449  if ( set->getData(set->nextSequenceNumber)->submitsRecorded ) {
450  NAMD_die("SubmitReduction deleted while reductions outstanding on parent!");
451  }
452 
453  set->submitsRegistered--;
454 
455  delSet(setID);
456  delete msg;
457 }
458 
459 // data submitted from child
461  int setID = msg->reductionSetID;
462  ReductionSet *set = reductionSets[setID];
463  int seqNum = msg->sequenceNumber
464  + set->addToRemoteSequenceNumber[childIndex(msg->sourceNode)];
465 
466 //iout << "seq " << seqNum << " from " << msg->sourceNode << " received on " << CkMyPe() << "\n" << endi;
467  int size = msg->dataSize;
468  if ( size != set->dataSize ) {
469  NAMD_bug("ReductionMgr::remoteSubmit data sizes do not match.");
470  }
471 
472  BigReal *newData = msg->data;
473  ReductionSetData *data = set->getData(seqNum);
474  BigReal *curData = data->data;
475 #ifdef ARCH_POWERPC
476 #pragma disjoint (*curData, *newData)
477 #pragma unroll(4)
478 #endif
479  if ( setID == REDUCTIONS_MINIMIZER ) {
480  for ( int i = 0; i < size; ++i ) {
481  if ( newData[i] > curData[i] ) {
482  curData[i] = newData[i];
483  }
484  }
485  } else {
486  for ( int i = 0; i < size; ++i ) {
487  curData[i] += newData[i];
488  }
489  }
490 // CkPrintf("[%d] reduction Submit received from node[%d] %d\n",
491 // CkMyPe(),childIndex(msg->sourceNode),msg->sourceNode);
492  delete msg;
493 
494  data->submitsRecorded++;
495  if ( data->submitsRecorded == set->submitsRegistered ) {
496  mergeAndDeliver(set,seqNum);
497  }
498 }
499 
500 // common code for submission and delivery
501 void ReductionMgr::mergeAndDeliver(ReductionSet *set, int seqNum) {
502 
503 //iout << "seq " << seqNum << " complete on " << CkMyPe() << "\n" << endi;
504 
505  set->nextSequenceNumber++; // should match all clients
506 
507  ReductionSetData *data = set->getData(seqNum);
508  if ( data->submitsRecorded != set->submitsRegistered ) {
509  NAMD_bug("ReductionMgr::mergeAndDeliver not ready to deliver.");
510  }
511 
512  if ( isRoot() ) {
513  if ( set->requireRegistered ) {
514  if ( set->threadIsWaiting && set->waitingForSequenceNumber == seqNum) {
515  // awaken the thread so it can take the data
516  CthAwaken(set->waitingThread);
517  }
518  } else {
519  NAMD_die("ReductionSet::deliver will never deliver data");
520  }
521  } else {
522  // send data to parent
523  ReductionSubmitMsg *msg = new(set->dataSize) ReductionSubmitMsg;
524  msg->reductionSetID = set->reductionSetID;
525  msg->sourceNode = CkMyPe();
526  msg->sequenceNumber = seqNum;
527  msg->dataSize = set->dataSize;
528  for ( int i = 0; i < msg->dataSize; ++i ) {
529  msg->data[i] = data->data[i];
530  }
531  CProxy_ReductionMgr reductionProxy(thisgroup);
532  reductionProxy[myParent].remoteSubmit(msg);
533  delete set->removeData(seqNum);
534  }
535 
536 }
537 
538 // register require
541  RequireReduction *handle;
542  // Only use the shared memory reductions for GPU-resident dynamics
543  if (simParams->GPUresidentSingleProcessMode && setID == REDUCTIONS_GPURESIDENT) {
544  handle = new RequireReductionShared;
545  } else {
546  ReductionSet *set = getSet(setID,size);
547  set->requireRegistered++;
548  if ( set->getData(set->nextSequenceNumber)->submitsRecorded ) {
549  NAMD_die("ReductionMgr::willRequire called while reductions outstanding!");
550  }
551 
552  RequireReductionCharm* charm_handle = new RequireReductionCharm;
553  charm_handle->reductionSetID = setID;
554  charm_handle->sequenceNumber = set->nextSequenceNumber;
555  charm_handle->master = this;
556 
557  handle = (RequireReduction*) charm_handle;
558 
559  }
560  return handle;
561 }
562 
563 // unregister require
564 void ReductionMgr::remove(RequireReductionCharm* handle) {
565  int setID = handle->reductionSetID;
566  ReductionSet *set = reductionSets[setID];
567  if ( set->getData(set->nextSequenceNumber)->submitsRecorded ) {
568  NAMD_die("RequireReduction deleted while reductions outstanding!");
569  }
570 
571  set->requireRegistered--;
572 
573  delSet(setID);
574 }
575 
576 // require the data from a thread
577 void ReductionMgr::require(RequireReductionCharm* handle) {
578  int setID = handle->reductionSetID;
579  ReductionSet *set = reductionSets[setID];
580  int seqNum = handle->sequenceNumber;
581  ReductionSetData *data = set->getData(seqNum);
582  if ( data->submitsRecorded < set->submitsRegistered ) {
583  set->threadIsWaiting = 1;
584  set->waitingForSequenceNumber = seqNum;
585  set->waitingThread = CthSelf();
586 //iout << "seq " << seqNum << " waiting\n" << endi;
587  CthSuspend();
588  }
589  set->threadIsWaiting = 0;
590 
591 //iout << "seq " << seqNum << " consumed\n" << endi;
592  delete handle->currentData;
593  handle->currentData = set->removeData(seqNum);
594  handle->data = handle->currentData->data;
595  handle->sequenceNumber = ++seqNum;
596 }
597 
598 //these will return void for now
600  reducedValue = 0.0;
601  valueLock = CmiCreateLock();
602 }
603 
605  CmiDestroyLock(this->valueLock);
606 }
607 
608 // atomic updates to reducedValue
609 double ReductionValue::operator+=(double rvalue){
610  //reducedValue.fetch_add(rvalue, std::memory_order_relaxed);
611  CmiLock(valueLock);
612  reducedValue += rvalue;
613  CmiUnlock(valueLock);
614  return reducedValue;
615 }
616 
617 
618 double ReductionValue::operator+=(int rvalue){
619  //reducedValue.fetch_add(rvalue, std::memory_order_relaxed);
620  CmiLock(valueLock);
621  reducedValue += rvalue;
622  CmiUnlock(valueLock);
623  return reducedValue;
624 }
625 
626 double ReductionValue::operator+=(unsigned int rvalue){
627  //reducedValue.fetch_add(rvalue, std::memory_order_relaxed);
628  CmiLock(valueLock);
629  reducedValue += rvalue;
630  CmiUnlock(valueLock);
631  return reducedValue;
632 }
633 
635  reducedValue += rvalue;
636 }
637 
638 ReductionValue::operator int(){
639  return (int)reducedValue;
640 }
641 
642 ReductionValue::operator double(){
643  return reducedValue;
644 }
645 
647  //memset(set, 0, sizeof(ReductionValue)*REDUCTION_MAX_RESERVED);
648  for(int i = 0; i < REDUCTION_MAX_RESERVED; i++){
649  this->set[i].reducedValue = 0.0;
650  }
651 
652 }
653 
655  return set[index];
656 }
657 
659  return set[index];
660 }
661 
663  // this memset is going to eff everything up i think
664  //memset(set, 0, sizeof(ReductionValue)*REDUCTION_MAX_RESERVED);
665 #pragma unroll
666  for(int i = 0; i < REDUCTION_MAX_RESERVED; i++){
667  this->set[i].reducedValue = 0.0;
668  }
669 }
670 
672 #pragma unroll
673  for(int i = 0; i < REDUCTION_MAX_RESERVED; i++){
674  CmiLock(this->set[i].valueLock);
675  this->set[i].reducedValue = 0.0;
676  CmiUnlock(this->set[i].valueLock);
677  }
678 }
679 
680 
682 #pragma unroll
683  for(int i = 0; i < REDUCTION_MAX_RESERVED; i++){
684  this->set[i].reducedValue = other->set[i].reducedValue;
685  }
686 }
687 
689 
690 }
691 
692 
694 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
695  CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
696  PatchData *patchData = cpdata.ckLocalBranch();
697  nodeReduction = patchData->reductionBackend;
698  nodeReduction->zero();
699  for (int i = 0; i < REDUCTION_MAX_RESERVED; i++) {
700  my_data[i] = 0;
701  }
702  data = my_data;
703 #else
704  NAMD_bug("SubmitReductionShared is only supported with CUDA/HIP");
705 #endif
706 }
707 
709 #if defined(NAMD_CUDA) || defined(NAMD_HIP)
710  CProxy_PatchData cpdata(CkpvAccess(BOCclass_group).patchData);
711  PatchData *patchData = cpdata.ckLocalBranch();
712  nodeReduction = patchData->reductionBackend;
713  for (int i = 0; i < REDUCTION_MAX_RESERVED; i++) {
714  my_data[i] = 0;
715  }
716  data = my_data;
717 #else
718  NAMD_bug("SubmitReductionShared is only supported with CUDA/HIP");
719 #endif
720 }
721 
722 #include "ReductionMgr.def.h"
723 // nothing should be placed below here
724 
static Node * Object()
Definition: Node.h:86
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
int * addToRemoteSequenceNumber
Definition: ReductionMgr.h:236
friend class RequireReductionCharm
Definition: ReductionMgr.h:248
SimParameters * simParameters
Definition: Node.h:181
ReductionSetData * getData(int seqNum)
Definition: ReductionMgr.C:91
#define DebugM(x, y)
Definition: Debug.h:75
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
NodeReduction * reductionBackend
Definition: PatchData.h:134
double operator+=(double other)
Definition: ReductionMgr.C:609
#define REDUCTION_MAX_CHILDREN
Definition: ReductionMgr.h:190
friend class SubmitReductionShared
Definition: ReductionMgr.h:246
CmiNodeLock valueLock
Definition: ReductionMgr.h:437
void zero_lock()
Definition: ReductionMgr.C:671
static Units next(Units u)
Definition: ParseOptions.C:48
void NAMD_bug(const char *err_msg)
Definition: common.C:195
ReductionValue & item(int index)
Definition: ReductionMgr.C:658
int requireRegistered
Definition: ReductionMgr.h:230
ReductionSetData * removeData(int seqNum)
Definition: ReductionMgr.C:106
int submitsRegistered
Definition: ReductionMgr.h:225
void NAMD_die(const char *err_msg)
Definition: common.C:147
ReductionValue set[REDUCTION_MAX_RESERVED]
Definition: ReductionMgr.h:455
std::vector< std::string > split(const std::string &text, std::string delimiter)
Definition: MoleculeQM.C:74
void remoteSubmit(ReductionSubmitMsg *msg)
Definition: ReductionMgr.C:460
#define simParams
Definition: Output.C:131
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
friend class SubmitReductionCharm
Definition: ReductionMgr.h:245
friend class RequireReductionShared
Definition: ReductionMgr.h:249
ReductionMgr * master
Definition: ReductionMgr.h:388
void remoteUnregister(ReductionRegisterMsg *msg)
Definition: ReductionMgr.C:445
double reducedValue
Definition: ReductionMgr.h:436
double BigReal
Definition: common.h:123
ReductionSetData * dataQueue
Definition: ReductionMgr.h:227
BigReal * data
Definition: ReductionMgr.h:328