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