SST  11.1.0
StructuralSimulationToolkit
sharedRegionImpl.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_SHAREDREGIONIMPL_H
13 #define SST_CORE_CORE_SHAREDREGIONIMPL_H
14 
15 #include "sst/core/output.h"
16 #include "sst/core/serialization/serializable.h"
17 #include "sst/core/sharedRegion.h"
18 #include "sst/core/sst_types.h"
19 #include "sst/core/warnmacros.h"
20 
21 #include <map>
22 #include <mutex>
23 #include <string>
24 #include <vector>
25 
26 namespace SST {
27 
28 class SharedRegionImpl;
29 
31 {
32 public:
33  ChangeSet() {}
34  size_t offset;
35  size_t length;
36  /*const*/ uint8_t* data;
37 
38  ChangeSet(size_t offset, size_t length, /*const*/ uint8_t* data = nullptr) :
39  offset(offset),
40  length(length),
41  data(data)
42  {}
43 
44  void serialize_order(SST::Core::Serialization::serializer& ser) override
45  {
46  ser& offset;
47  // ser & length;
48  // if ( ser.mode() == SST::Core::Serialization::serializer::UNPACK ) {
49  // data = new uint8_t[length];
50  // }
51  // for ( int i = 0; i < length; i++ ) {
52  // ser & data[i];
53  // }
54  ser& SST::Core::Serialization::array(data, length);
55  // ser.binary(data,length);
56  }
57 
58  ImplementSerializable(SST::ChangeSet)
59 };
60 
62 {
63 public:
65  {
66 
67  protected:
68  int rank;
69  std::string key;
70  size_t length;
71  uint8_t initByte;
72 
73  virtual void check_size(RegionInfo* ri)
74  {
75  // Check to see if sizes match.
76 
77  // If the merge info has zero length, then it doesn't know
78  // the size, so just return
79  if ( length == 0 ) return;
80 
81  ri->setSize(length, initByte);
82  }
83 
84  public:
85  RegionMergeInfo() {}
86  RegionMergeInfo(int rank, const std::string& key, size_t length, uint8_t initByte) :
87  rank(rank),
88  key(key),
89  length(length),
90  initByte(initByte)
91  {}
92  virtual ~RegionMergeInfo() {}
93 
94  virtual bool merge(RegionInfo* ri)
95  {
96  check_size(ri);
97  return true;
98  }
99  const std::string& getKey() const { return key; }
100  size_t getLength() const { return length; }
101 
102  void serialize_order(SST::Core::Serialization::serializer& ser) override
103  {
104  ser& rank;
105  ser& key;
106  ser& length;
107  ser& initByte;
108  }
109 
110  ImplementSerializable(SST::RegionInfo::RegionMergeInfo)
111  };
112 
114  {
115  protected:
116  void* data;
117 
118  public:
120  BulkMergeInfo(int rank, const std::string& key, void* data, size_t length, uint8_t initByte) :
121  RegionMergeInfo(rank, key, length, initByte),
122  data(data)
123  {}
124 
125  bool merge(RegionInfo* ri) override
126  {
127  check_size(ri);
128  bool ret = ri->getMerger()->merge((uint8_t*)ri->getMemory(), (const uint8_t*)data, length);
129  free(data);
130  return ret;
131  }
132 
133  void serialize_order(SST::Core::Serialization::serializer& ser) override
134  {
135  RegionInfo::RegionMergeInfo::serialize_order(ser);
136 
137  // if ( ser.mode() == SST::Core::Serialization::serializer::UNPACK ) {
138  // data = malloc(length);
139  // }
140  // for ( int i = 0; i < length; i++ ) {
141  // ser & ((uint8_t*)data)[i];
142  // }
143  ser& SST::Core::Serialization::array(data, length);
144  // ser.binary(data,length);
145  }
146 
147  ImplementSerializable(SST::RegionInfo::BulkMergeInfo)
148  };
149 
151  {
152  protected:
153  // std::vector<SharedRegionMerger::ChangeSet> changeSets;
154  std::vector<ChangeSet> changeSets;
155 
156  public:
159  int rank, const std::string& key, size_t length, uint8_t initByte, std::vector<ChangeSet>& changeSets) :
160  RegionMergeInfo(rank, key, length, initByte),
161  changeSets(changeSets)
162  {}
163  bool merge(RegionInfo* ri) override
164  {
165  check_size(ri);
166  return ri->getMerger()->merge((uint8_t*)ri->getMemory(), ri->getSize(), changeSets);
167  }
168 
169  void serialize_order(SST::Core::Serialization::serializer& ser) override
170  {
171  RegionInfo::RegionMergeInfo::serialize_order(ser);
172  ser& changeSets;
173  }
174 
175  ImplementSerializable(SST::RegionInfo::ChangeSetMergeInfo)
176  };
177 
178 private:
179  std::string myKey;
180  size_t realSize;
181  size_t apparentSize;
182  void* memory;
183 
184  size_t shareCount;
185  size_t publishCount;
186 
187  std::vector<SharedRegionImpl*> sharers;
188 
189  SharedRegionMerger* merger; // If null, no multi-rank merging
190  // std::vector<SharedRegionMerger::ChangeSet> changesets;
191  std::vector<ChangeSet> changesets;
192 
193  bool didBulk;
194  bool initialized;
195  bool ready;
196  uint8_t initByte;
197 
198 public:
199  RegionInfo() :
200  realSize(0),
201  apparentSize(0),
202  memory(nullptr),
203  shareCount(0),
204  publishCount(0),
205  merger(nullptr),
206  didBulk(false),
207  initialized(false),
208  ready(false),
209  initByte(0)
210  {}
211  ~RegionInfo();
212  bool initialize(const std::string& key, size_t size, uint8_t initByte_in, SharedRegionMerger* mergeObj);
213  bool setSize(size_t size, uint8_t initByte_in);
214  bool isInitialized() const { return initialized; }
215  bool isReady() const { return ready; }
216 
217  SharedRegionImpl* addSharer(SharedRegionManager* manager);
218  void removeSharer(SharedRegionImpl* sri);
219 
220  void modifyRegion(size_t offset, size_t length, const void* data);
221  void publish();
222 
223  void updateState(bool finalize);
224 
225  const std::string& getKey() const { return myKey; }
226  void* getMemory()
227  {
228  didBulk = true;
229  return memory;
230  }
231  const void* getConstPtr() const { return memory; }
232  size_t getSize() const { return apparentSize; }
233  size_t getNumSharers() const { return shareCount; }
234 
235  bool shouldMerge() const { return (nullptr != merger); }
236  SharedRegionMerger* getMerger() { return merger; }
237  /** Returns the size of the data to be transferred */
238  RegionMergeInfo* getMergeInfo();
239 
240  void setProtected(bool readOnly);
241 };
242 
244 {
245  bool published;
246  RegionInfo* region;
247 
248 protected:
249  size_t getSize() { return region->getSize(); }
250 
251 public:
252  SharedRegionImpl(SharedRegionManager* manager, size_t id, RegionInfo* region) :
253  SharedRegion(manager, id),
254  published(false),
255  region(region)
256  {}
257 
258  bool isPublished() const { return published; }
259  void setPublished() { published = true; }
260  RegionInfo* getRegion() const { return region; }
261  void notifySetSize()
262  {
263  if ( deferred_pointer != nullptr ) {
264  deferred_pointer->setPointer(getPtr<const void*>());
265  delete deferred_pointer;
266  deferred_pointer = nullptr;
267  }
268  }
269 };
270 
272 {
273 
274  struct CommInfo_t
275  {
276  RegionInfo* region;
277  std::vector<int> tgtRanks;
278  std::vector<char> sendBuffer;
279  };
280 
281  std::map<std::string, RegionInfo> regions;
282  std::mutex mtx;
283 
284 protected:
285  void modifyRegion(SharedRegion* sr, size_t offset, size_t length, const void* data) override;
286  void* getMemory(SharedRegion* sr) override;
287  const void* getConstPtr(const SharedRegion* sr) const override;
288  size_t getSize(const SharedRegion* sr) const override;
289 
290 public:
293 
294  virtual SharedRegion* getLocalSharedRegion(const std::string& key, size_t size, uint8_t initByte = 0) override;
296  const std::string& key, size_t size, SharedRegionMerger* merger = nullptr, uint8_t initByte = 0) override;
297 
298  virtual void publishRegion(SharedRegion*) override;
299  virtual bool isRegionReady(const SharedRegion*) override;
300  virtual void shutdownSharedRegion(SharedRegion*) override;
301 
302  void updateState(bool finalize) override;
303 };
304 
305 } // namespace SST
306 
307 #endif // SST_CORE_CORE_SHAREDREGIONIMPL_H
Definition: sharedRegion.h:133
Definition: sharedRegionImpl.h:271
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:34
virtual SharedRegion * getGlobalSharedRegion(const std::string &key, size_t size, SharedRegionMerger *merger=nullptr, uint8_t initByte=0) override
Create a SharedRegion that will be shared with elements on the all ranks.
Definition: sharedRegion.cc:265
Definition: sharedRegionImpl.h:30
Definition: sharedRegionImpl.h:243
Utility class to define how to merge multiple pieces of shared memory regions Useful in the multi-MPI...
Definition: sharedRegion.h:35
RegionMergeInfo * getMergeInfo()
Returns the size of the data to be transferred.
Definition: sharedRegion.cc:230
Definition: serializable.h:118
virtual SharedRegion * getLocalSharedRegion(const std::string &key, size_t size, uint8_t initByte=0) override
Create a SharedRegion that will only be shared with elements on the current rank. ...
Definition: sharedRegion.cc:254
Definition: sharedRegionImpl.h:61
virtual bool merge(uint8_t *target, const uint8_t *newData, size_t size)
Merge the data from &#39;newData&#39; into &#39;target&#39;.
Definition: sharedRegionImpl.h:150
Definition: sharedRegionImpl.h:64
Definition: sharedRegion.h:63
Definition: sharedRegionImpl.h:113