SST  11.1.0
StructuralSimulationToolkit
sharedRegion.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_SHAREDREGION_H
13 #define SST_CORE_SHAREDREGION_H
14 
15 #include "sst/core/sst_types.h"
16 #include "sst/core/warnmacros.h"
17 
18 #include <string>
19 #include <vector>
20 
21 #if !SST_BUILDING_CORE
22 #warning \
23  "SharedRegion and its accompanying classes have been deprecated and will be removed in SST 12. Please use the new SharedObject classes found in sst/core/shared."
24 #endif
25 
26 namespace SST {
27 
28 class SharedRegion;
29 class ChangeSet;
30 
31 /**
32  * Utility class to define how to merge multiple pieces of shared memory regions
33  * Useful in the multi-MPI-rank, "Global Shared" model
34  */
36 {
37 public:
38  virtual ~SharedRegionMerger() {}
39 
40  /**
41  * Merge the data from 'newData' into 'target'
42  * @return True on success, False on failure
43  */
44  virtual bool merge(uint8_t* target, const uint8_t* newData, size_t size);
45  virtual bool merge(uint8_t* target, size_t size, const std::vector<ChangeSet>& changeSets);
46 };
47 
49 {
50  uint8_t defVal;
51 
52 public:
53  SharedRegionInitializedMerger(uint8_t defaultValue) { defVal = defaultValue; }
54 
55  bool merge(uint8_t* target, const uint8_t* newData, size_t size) override;
56 
57  bool merge(uint8_t* target, size_t size, const std::vector<ChangeSet>& changeSets) override
58  {
59  return SharedRegionMerger::merge(target, size, changeSets);
60  }
61 };
62 
64 {
65 protected:
66  friend class SharedRegion;
67 
68  virtual void modifyRegion(SharedRegion* sr, size_t offset, size_t length, const void* data) = 0;
69  virtual void* getMemory(SharedRegion* sr) = 0;
70  virtual const void* getConstPtr(const SharedRegion* sr) const = 0;
71  virtual size_t getSize(const SharedRegion* sr) const = 0;
72 
73 public:
74  /**
75  Create a SharedRegion that will only be shared with elements on
76  the current rank. This type of SharedRegion is intended to
77  have at least one element on each rank initialize the region.
78 
79  @param key Name of the SharedRegion. All elements om the rank
80  using this name will get the same underlying data.
81 
82  @param size Size of the SharedRegion. Elements can specify 0
83  size if they don't know the size of the region. At least one
84  element will need to specify the size and all elements that
85  specify a size must pass in the same size. There are many
86  calls in SharedRegion that can't be called until the size is
87  known.
88 
89  @param initByte Value to initialize all bytes in the region to
90 
91  @return SharedRegion object to be used by the calling element
92  to access the shared region.
93  */
94  virtual SharedRegion* getLocalSharedRegion(const std::string& key, size_t size, uint8_t initByte = 0) = 0;
95 
96  /**
97  Create a SharedRegion that will be shared with elements on the
98  all ranks. The SharedRegion data will be merged across ranks
99  before each round of calls to init().
100 
101  @param key Name of the SharedRegion. All elements using this
102  name will get the same underlying data.
103 
104  @param size Size of the SharedRegion. Elements can specify 0
105  size if they don't know the size of the region. At least one
106  element will need to specify the size and all elements that
107  specify a size must pass in the same size. There are many
108  calls in SharedRegion that can't be called until the size is
109  known.
110 
111  @param merger Merger to use when combining data across ranks
112 
113  @param initByte Value to initialize all bytes in the region to
114 
115  @return SharedRegion object to be used by the calling element
116  to access the shared region.
117  */
119  const std::string& key, size_t size, SharedRegionMerger* merger = nullptr, uint8_t initByte = 0) = 0;
120 
121  // The following functions will become protected in SST 12. Need
122  // to look for instances of these used in the core, they will be
123  // bracketed with DISABLE_WARN_DEPRECATED_DECLARATION.
124  virtual void publishRegion(SharedRegion*) = 0;
125 
126  virtual bool isRegionReady(const SharedRegion*) = 0;
127 
128  virtual void shutdownSharedRegion(SharedRegion*) = 0;
129 
130  virtual void updateState(bool finalize) = 0;
131 };
132 
134 {
135 private:
136  SharedRegionManager* manager;
137  size_t id;
138 
139 protected:
141  {
142  public:
143  virtual ~DeferredPointerBase() {}
144  virtual void setPointer(const void* p) = 0;
145  };
146 
147  template <typename T>
149  {
150  T& ptr;
151 
152  public:
153  DeferredPointer(T& ptr) : DeferredPointerBase(), ptr(ptr) {}
154 
155  void setPointer(const void* p) { ptr = static_cast<const T>(p); }
156  };
157 
158  DeferredPointerBase* deferred_pointer;
159 
160  SharedRegion(SharedRegionManager* manager, size_t id) : manager(manager), id(id), deferred_pointer(nullptr) {}
161 
162 public:
163  virtual ~SharedRegion() {}
164 
165  void shutdown()
166  {
167  DISABLE_WARN_DEPRECATED_DECLARATION;
168  manager->shutdownSharedRegion(this);
169  REENABLE_WARNING;
170  }
171 
172  /**
173  * @return The ID of this instance. (Number in range 0->N)
174  */
175  size_t getLocalShareID() const { return id; }
176 
177  /**
178  * @return The size of the shared memory region, may return 0 if
179  * this copy of the region doesn't know the final size yet.
180  */
181  size_t getSize() const { return manager->getSize(this); }
182 
183  /**
184  * Call to denote that you are done making any changes to this region
185  */
186  void publish()
187  {
188  DISABLE_WARN_DEPRECATED_DECLARATION;
189  manager->publishRegion(this);
190  REENABLE_WARNING;
191  }
192 
193  /**
194  * Check to see if the region is ready (all elements requesting
195  * the region have called publish()).
196  *
197  * @return True if the region is ready to use (all sharers have
198  * called publish()).
199  */
200  bool isReady() const
201  {
202  DISABLE_WARN_DEPRECATED_DECLARATION;
203  return manager->isRegionReady(this);
204  REENABLE_WARNING;
205  }
206 
207  /**
208  * Before the region has published, apply a modification. (Copy
209  * this data in). This function cannot be called if the size is
210  * still set to 0.
211  */
212  void modifyRegion(size_t offset, size_t length, const void* data)
213  {
214  manager->modifyRegion(this, offset, length, data);
215  }
216 
217  /**
218  * Before the region has published, apply a modification. (Copy
219  * this data in). This function cannot be called if the size is
220  * still set to 0.
221  */
222  template <typename T>
223  void modifyArray(size_t offset, const T& data)
224  {
225  manager->modifyRegion(this, offset * sizeof(T), sizeof(T), &data);
226  }
227 
228  /**
229  * @return a void* pointer to the shared memory region This
230  * pointer is only valid to write to before a call to publish().
231  * This function cannot be called if the size is still set to
232  * 0, as there is no backing memory yet.
233  */
234  void* getRawPtr() { return manager->getMemory(this); }
235 
236  /**
237  * Get a pointer to the const shared data
238  *
239  * @return a const pointer to the shared memory region. This
240  * function cannot be called if the size is still set to
241  * 0, as there is no backing memory yet.
242  */
243  template <typename T>
244  T getPtr() const
245  {
246  return static_cast<T>(manager->getConstPtr(this));
247  }
248 
249  /**
250  * Used to get a pointer to the const shared data when the element
251  * doesn't yet know the size. This will defer setting the pointer
252  * until the size of the region is known (and therefor the memory
253  * has been allocated). This allows an element to initialize the
254  * region and get the pointer without having to make the call to
255  * getPtr() later. This is particularly helpful if the
256  * SharedRegion is created in an object that doesn't get called
257  * during init() or setup().
258  *
259  * @ptr Pointer that should be set once the size is known. User
260  * can tell pointer is valid when getSize() returns a value != 0.
261  */
262  template <typename T>
263  void getPtrDeferred(T& ptr)
264  {
265  if ( getSize() != 0 ) {
266  // Size is already set, just set the pointer
267  ptr = getPtr<T>();
268  return;
269  }
270  if ( deferred_pointer != nullptr ) return;
271  deferred_pointer = new DeferredPointer<T>(ptr);
272  }
273 };
274 
275 } // namespace SST
276 
277 #endif // SST_CORE_SHAREDREGION_H
void modifyRegion(size_t offset, size_t length, const void *data)
Before the region has published, apply a modification.
Definition: sharedRegion.h:212
Definition: sharedRegion.h:133
bool merge(uint8_t *target, const uint8_t *newData, size_t size) override
Merge the data from &#39;newData&#39; into &#39;target&#39;.
Definition: sharedRegion.cc:75
bool isReady() const
Check to see if the region is ready (all elements requesting the region have called publish())...
Definition: sharedRegion.h:200
Definition: sharedRegion.h:140
void getPtrDeferred(T &ptr)
Used to get a pointer to the const shared data when the element doesn&#39;t yet know the size...
Definition: sharedRegion.h:263
void * getRawPtr()
Definition: sharedRegion.h:234
Utility class to define how to merge multiple pieces of shared memory regions Useful in the multi-MPI...
Definition: sharedRegion.h:35
void publish()
Call to denote that you are done making any changes to this region.
Definition: sharedRegion.h:186
virtual SharedRegion * getLocalSharedRegion(const std::string &key, size_t size, uint8_t initByte=0)=0
Create a SharedRegion that will only be shared with elements on the current rank. ...
size_t getLocalShareID() const
Definition: sharedRegion.h:175
void modifyArray(size_t offset, const T &data)
Before the region has published, apply a modification.
Definition: sharedRegion.h:223
T getPtr() const
Get a pointer to the const shared data.
Definition: sharedRegion.h:244
virtual bool merge(uint8_t *target, const uint8_t *newData, size_t size)
Merge the data from &#39;newData&#39; into &#39;target&#39;.
virtual SharedRegion * getGlobalSharedRegion(const std::string &key, size_t size, SharedRegionMerger *merger=nullptr, uint8_t initByte=0)=0
Create a SharedRegion that will be shared with elements on the all ranks.
Definition: sharedRegion.h:48
size_t getSize() const
Definition: sharedRegion.h:181
Definition: sharedRegion.h:148
Definition: sharedRegion.h:63