NAMD
BroadcastObject.h
Go to the documentation of this file.
1 
7 /*
8  Coordinates broadcast of a data type from a Controller/Seq
9  to all other Controller/Sequencer type objects (they must
10  run in a thread!)
11 */
12 
13 #ifndef _BCASTOBJ_H
14 #define _BCASTOBJ_H
15 
16 #include "BroadcastMgr.h"
17 #include "BroadcastClient.h"
18 #include "LdbCoordinator.h"
19 #include "Node.h"
20 #include "SimParameters.h"
21 #include "common.h"
22 
23 #include <map>
24 #include <any>
25 
26 
27 /*
28  * @brief Broadcast object for intra-node GPU-resident broadcasts
29  *
30  * There will exist one of these in each logical node to facilitate shared memory
31  * broadcasts between PEs within that logic node
32  *
33  * The data object stores the actual data associated with a given ID, and the current
34  * objects stores the retrieval count for a given ID,tag pair. Once the retrieval count
35  * has been reached, the entry for that ID in data is cleared
36  */
38 public:
39  CmiNodeLock lock;
40  std::map<int, std::any> data;
41  std::map<int, std::map<int, int>> current;
42 };
43 
44 template <class T> class SimpleBroadcastObject : public BroadcastClient {
45 
46  public:
47 
48  const LDObjHandle *ldObjPtr;
49 
50  bool useShared = false;
51  int id = -1;
53 
54  /*
55  * @brief Creates a new SimpleBroadcastObject with given id
56  *
57  * NodeBroadcast is used by the shared memory backend and the same pointer should be given to all
58  * objects on all Pes.
59  *
60  * Even if we are using the shared memory backend, some of the broadcast objects must still use
61  * the charm++ backend since they are used for barriers, like scriptBarrier. The shared memory backend must
62  * be explicitly enabled using the useSharedIfPossible parameter
63  *
64  */
65  SimpleBroadcastObject(int id_in, const LDObjHandle *h = 0,
66  NodeBroadcast* nodeBroadcastIn = 0, const bool useSharedIfPossible = false)
67  : BroadcastClient(id_in), ldObjPtr(h), nodeBroadcast(nodeBroadcastIn), id(id_in) {
68  if ( sizeof(T) > BCASTMSGSIZE ) {
69  NAMD_bug("SimpleBroadcastObject instantiated on class larger than BCASTMSGSIZE");
70  }
71 
72  if (nodeBroadcast != 0) {
74 
75  if (useShared) {
76  // Add a map for this broadcast object if needed
77  CmiLock(nodeBroadcast->lock);
78  if (nodeBroadcast->data.find(id) == nodeBroadcast->data.end()) {
79  nodeBroadcast->data[id] = new std::map<int, T>();
80  }
81  CmiUnlock(nodeBroadcast->lock);
82  }
83  }
84  }
86 
87  /*
88  * @brief Attempts to retrieve a previously published value for a given tag and id
89  *
90  * This function has slightly different behavior between the shared memory and charm++ backends. The Charm++
91  * backend will suspend and wait if it attempts to retrieve an unpublished tag, while the shared memory
92  * backend will throw an error. The shared memory backend also should be given the expected number of
93  * retrievals so the data can be removed
94  *
95  */
96  T get(int tag, const int expected = -1) {
97  T tmp;
98  if (useShared) {
99  CmiLock(nodeBroadcast->lock);
100  if (nodeBroadcast->data.find(id) == nodeBroadcast->data.end()) {
101  NAMD_bug("SimpleBroadcastObject: Did not find id");
102  }
103  std::map<int, T>* data = std::any_cast<std::map<int, T>*>(nodeBroadcast->data[id]);
104  if (data->find(tag) == data->end()) {
105  NAMD_bug("SimpleBroadcastObject: Did not find tag");
106  }
107  tmp = (*data)[tag];
108  nodeBroadcast->current[id][tag]++;
109  if (nodeBroadcast->current[id][tag] == expected) {
110  data->erase(tag);
111  nodeBroadcast->current[id].erase(tag);
112  }
113  CmiUnlock(nodeBroadcast->lock);
114  } else {
116  while ( BroadcastMgr::Object()->getbuf(*this, tag, (void*)(&tmp)) < 0 ) {
117  suspendFor(tag);
118  }
120  }
121  return tmp;
122  }
123  int getSize() {
124  return BroadcastMgr::Object()->boidSize();
125  }
126  int getBcastSize() {
128  }
131  }
132  void publish(int tag,const T &t ) {
133  if (useShared) {
134  CmiLock(nodeBroadcast->lock);
135  std::map<int, T>* data = std::any_cast<std::map<int, T>*>(nodeBroadcast->data[id]);
136  data->insert({tag, t});
137  nodeBroadcast->current[id][tag] = 0;
138  CmiUnlock(nodeBroadcast->lock);
139  } else {
140  BroadcastMgr::Object()->send(*this, tag, (void*)(&t), sizeof(T));
141  }
142  }
143 };
144 
145 #endif
static Node * Object()
Definition: Node.h:86
SimParameters * simParameters
Definition: Node.h:181
void startWork(const LDObjHandle &handle)
void pauseWork(const LDObjHandle &handle)
int boidBroadcastSize()
Definition: BroadcastMgr.C:28
const LDObjHandle * ldObjPtr
void send(BroadcastClient &b, int tag, void *buf, size_t)
Definition: BroadcastMgr.C:69
void NAMD_bug(const char *err_msg)
Definition: common.C:195
std::map< int, std::any > data
NodeBroadcast * nodeBroadcast
int boidTaggedMsgSize()
Definition: BroadcastMgr.C:38
static LdbCoordinator * Object()
SimpleBroadcastObject(int id_in, const LDObjHandle *h=0, NodeBroadcast *nodeBroadcastIn=0, const bool useSharedIfPossible=false)
void publish(int tag, const T &t)
Bool GPUresidentSingleProcessMode
void suspendFor(int tag)
static BroadcastMgr * Object()
Definition: BroadcastMgr.h:95
#define BCASTMSGSIZE
Definition: BroadcastMgr.h:22
CmiNodeLock lock
std::map< int, std::map< int, int > > current