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