SST  11.0.0
StructuralSimulationToolkit
sharedObject.h
1 // Copyright 2009-2021 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2021, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_CORE_SHARED_SHAREDOBJECT_H
13 #define SST_CORE_CORE_SHARED_SHAREDOBJECT_H
14 
15 #include "sst/core/sst_types.h"
16 
17 #include "sst/core/simulation.h"
18 #include "sst/core/serialization/serializable.h"
19 
20 #include <string>
21 
22 namespace SST {
23 
24 class Simulation_impl;
25 
26 namespace Shared {
27 
28 // NOTE: The classes in this header file are not part of the public
29 // API and can change at any time
30 
31 
32 class SharedObjectDataManager;
33 
34 /**
35  This is the base class for holding data on changes made to the
36  shared data on each rank. This data will be serialized and shared
37  with all ranks in the simulation.
38  */
40 
41 public:
43  SharedObjectChangeSet(const std::string& name) :
44  name(name)
45  {}
46 
47  /**
48  Apply the changes to the name shared data.
49 
50  @param manager The SharedObjectDataManager for the rank. This
51  is used to get the named shared data.
52  */
53  virtual void applyChanges(SharedObjectDataManager* UNUSED(manager)) = 0;
54 
55  /**
56  Clears the data. Used after transfering data to other ranks to
57  prepare for the next round of init. Child classes should call
58  this version of clear() in there implementations.
59  */
60  virtual void clear() = 0;
61 
62  /**
63  Get the name of the shared data the changeset should be applied
64  to
65 
66  @return name of shared data to apply changes to
67  */
68  const std::string& getName() { return name; }
69 
70 
71 protected:
72  void serialize_order(SST::Core::Serialization::serializer& ser) override {
73  ser & name;
74  }
75 
76  ImplementVirtualSerializable(SharedObjectChangeSet);
77 
78 
79 private:
80  std::string name;
81 };
82 
83 /**
84  Base class for holding SharedObject data. The base class is needed
85  so that we can have an API to manage unknown types of objects.
86 */
88 
89  friend class SharedObjectDataManager;
90  friend class SharedObject;
91 
92 public:
93 
94  /**
95  Get the name of the SharedObject for this data
96 
97  @return name of data
98  */
99  const std::string& getName() { return name; }
100 
101  /**
102  Checks to see if all instances of this SharedObject have called
103  publish(). This is forced to true before the setup() phase of
104  simulation, as no more writes are allowed.
105 
106  @return true if all instances have called publish(), false
107  otherwise.
108  */
109  bool isFullyPublished() { return fully_published; }
110 
111  /**
112  Get the number of sharers for this data
113 
114  @return number of sharers
115  */
116  virtual int getShareCount() { return share_count; }
117 
118  /**
119  Get the number of instances that have called publish() on their
120  instance of the shared object
121 
122  @return number of instances that have called publish()
123  */
124  virtual int getPublishCount() { return publish_count; }
125 
126 protected:
127 
128  std::string name;
129  int share_count;
130  int publish_count;
131  bool fully_published;
132  bool locked;
133 
134  // Mutex for locking across threads
135  mutable std::mutex mtx;
136 
137  // Check to see if object data is locked. If so, fatal
138  inline void check_lock_for_write(const std::string& obj) {
139  if ( locked ) {
141  CALL_INFO_LONG,1,"ERROR: attempt to write to %s %s after init phase\n",obj.c_str(),name.c_str());
142  }
143  }
144 
145  /* Manage counts */
146 
147  /**
148  Increment the count of sharers. This should only be called
149  once per instance.
150  */
151  virtual int incShareCount() {
152  std::lock_guard<std::mutex> lock(mtx);
153  int ret = share_count;
154  share_count++;
155  return ret;
156  }
157  /**
158  Increment the count of instances that have called publish.
159  This should only be called once per instance.
160  */
161  virtual void incPublishCount() {
162  std::lock_guard<std::mutex> lock(mtx);
163  publish_count++;
164  }
165 
166 
167  /* For merging across ranks */
168 
169  /**
170  Gets the changeset for this data on this rank. This is called
171  by the core when exchanging and merging data
172  */
173  virtual SharedObjectChangeSet* getChangeSet() = 0;
174 
175  /**
176  Resets the changeset for this data on this rank. This is called
177  by the core when exchanging and merging data
178  */
179  virtual void resetChangeSet() = 0;
180 
181  /**
182  Called by the core when writing to shared regions is no longer
183  allowed
184  */
185  void lock() { locked = true; }
186 
187 
188  /**
189  Constructor for SharedObjectData
190 
191  @param name name of the SharedObject
192  */
193  SharedObjectData(const std::string& name) :
194  name(name),
195  share_count(0),
196  publish_count(0),
197  fully_published(false),
198  locked(false)
199  {}
200 
201  /**
202  Destructor for SharedObjectData
203  */
204  virtual ~SharedObjectData() {}
205 };
206 
207 
209 
210  std::map<std::string, SharedObjectData*> shared_data;
211 
212  // Mutex for locking across threads
213  static std::mutex mtx;
214  static std::mutex update_mtx;
215 
216  bool locked;
217 
218 public:
219 
221  locked(false) {}
222 
224  for ( auto x : shared_data ) {
225  delete x.second;
226  }
227  }
228 
229  template <typename T>
230  T* getSharedObjectData(const std::string name)
231  {
232  // Need to lock since we may be initializing the
233  // SharedData object.
234  std::lock_guard<std::mutex> lock(mtx);
235  if ( locked ) {
237  CALL_INFO,1,"Attempting to initialize SharedObject %s after the init() phase\n",name.c_str());
238  }
239  auto obj = shared_data.find(name);
240  if ( obj == shared_data.end() ) {
241  // Does not yet exist, create it
242  auto ret = new T(name);
243  shared_data[name] = ret;
244  return ret;
245  }
246 
247  // If it exists, make sure the types match
248  auto obj_cast = dynamic_cast<T*>(obj->second);
249 
250  if ( obj_cast == nullptr ) {
252  CALL_INFO,1,"ERROR: Shared object %s requested with two different types\n",name.c_str());
253  }
254 
255  return obj_cast;
256  }
257 
258  void updateState(bool finalize);
259 
260 };
261 
262 
264 
265 
266 public:
267 
268  /**
269  Enum of verify types.
270  */
271  enum verify_type { VERIFY_UNINITIALIZED, FE_VERIFY, INIT_VERIFY, NO_VERIFY };
272 
273 
274 
275  SharedObject() {}
276  virtual ~SharedObject() {}
277 
278 protected:
279  friend class SST::Simulation_impl;
280  static SharedObjectDataManager manager;
281 
282 
283  void incPublishCount(SharedObjectData* data) {
284  data->incPublishCount();
285  }
286 
287  int incShareCount(SharedObjectData* data) {
288  return data->incShareCount();
289  }
290 
291 
292 };
293 
294 } // namespace Shared
295 } // namespace SST
296 
297 #endif
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
Definition: sharedObject.h:263
virtual SharedObjectChangeSet * getChangeSet()=0
Gets the changeset for this data on this rank.
virtual int getShareCount()
Get the number of sharers for this data.
Definition: sharedObject.h:116
void lock()
Called by the core when writing to shared regions is no longer allowed.
Definition: sharedObject.h:185
bool isFullyPublished()
Checks to see if all instances of this SharedObject have called publish().
Definition: sharedObject.h:109
const std::string & getName()
Get the name of the shared data the changeset should be applied to.
Definition: sharedObject.h:68
SharedObjectData(const std::string &name)
Constructor for SharedObjectData.
Definition: sharedObject.h:193
verify_type
Enum of verify types.
Definition: sharedObject.h:271
Definition: serializable.h:109
virtual void incPublishCount()
Increment the count of instances that have called publish.
Definition: sharedObject.h:161
void fatal(uint32_t line, const char *file, const char *func, int exit_code, const char *format,...) const
Output the fatal message with formatting as specified by the format parameter.
Definition: output.cc:155
Definition: sharedObject.h:208
Main control class for a SST Simulation.
Definition: simulation_impl.h:72
virtual int getPublishCount()
Get the number of instances that have called publish() on their instance of the shared object...
Definition: sharedObject.h:124
virtual int incShareCount()
Increment the count of sharers.
Definition: sharedObject.h:151
const std::string & getName()
Get the name of the SharedObject for this data.
Definition: sharedObject.h:99
virtual void clear()=0
Clears the data.
virtual void applyChanges(SharedObjectDataManager *UNUSED(manager))=0
Apply the changes to the name shared data.
static Output & getSimulationOutput()
Return the base simulation Output class instance.
Definition: simulation.cc:70
virtual void resetChangeSet()=0
Resets the changeset for this data on this rank.
This is the base class for holding data on changes made to the shared data on each rank...
Definition: sharedObject.h:39
Base class for holding SharedObject data.
Definition: sharedObject.h:87
virtual ~SharedObjectData()
Destructor for SharedObjectData.
Definition: sharedObject.h:204