SST  14.1.0
StructuralSimulationToolkit
sharedArray.h
1 // Copyright 2009-2024 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-2024, 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_SHAREDARRAY_H
13 #define SST_CORE_SHARED_SHAREDARRAY_H
14 
15 #include "sst/core/serialization/serializable.h"
16 #include "sst/core/shared/sharedObject.h"
17 #include "sst/core/sst_types.h"
18 
19 #include <vector>
20 
21 namespace SST {
22 namespace Shared {
23 
24 /**
25  SharedArray class. The class is templated to allow for an array
26  of any non-pointer type. The type must be serializable.
27  */
28 template <typename T>
29 class SharedArray : public SharedObject
30 {
31  static_assert(!std::is_pointer<T>::value, "Cannot use a pointer type with SharedArray");
32 
33  // Forward declaration. Defined below
34  class Data;
35 
36 public:
37  /**
38  Default constructor for SharedArray.
39  */
40  SharedArray() : SharedObject(), published(false), data(nullptr) {}
41 
42  /**
43  Shared Array Destructor
44  */
46  {
47  // data does not need to be deleted since the
48  // SharedObjectManager owns the pointer
49  }
50 
51  /**
52  Initialize the SharedArray.
53 
54  @param obj_name Name of the object. This name is how the
55  object is uniquely identified across ranks.
56 
57  @param length Length of the array. The length can be 0 if no
58  data is going to be written by the calling element, otherwise,
59  it must be large enough to write the desired data. The final
60  length of the array will be the maximum of the requested
61  lengths. The length of the array can be queried using the
62  size() method.
63 
64  @param init_value value that entries should be initialized to.
65  By default, each array item will be initialized using the
66  default constructor for the class being stored.
67 
68  @param verify_mode Specifies how multiply written data should
69  be verified. FE_VERIFY uses a full/empty bit for each entry
70  and if a value has previously been written, it will make sure
71  the two values match. INIT_VERIFY will simply compare writes
72  against the current value and will error unless the values
73  aren't the same or the existing value is the init_value. When
74  NO_VERIFY is passed, no verification will occur. This is
75  mostly useful when you can guarantee that multiple elements
76  won't write the same value and you want to do in-place
77  modifications as you initialize. VERIFY_UNINITIALIZED is a
78  reserved value and should not be passed.
79 
80  @return returns the number of instances that have intialized
81  themselve before this instance on this MPI rank.
82  */
83  int initialize(const std::string& obj_name, size_t length = 0, T init_value = T(), verify_type v_type = INIT_VERIFY)
84  {
85  if ( data ) {
86  Private::getSimulationOutput().fatal(
87  CALL_INFO, 1, "ERROR: called initialize() of SharedArray %s more than once\n", obj_name.c_str());
88  }
89 
90  if ( v_type == VERIFY_UNINITIALIZED ) {
91  Private::getSimulationOutput().fatal(
92  CALL_INFO, 1,
93  "ERROR: VERIFY_UNINITIALIZED passed into instance of SharedArray %s. "
94  "This is a reserved value and cannot be passed in here. \n",
95  obj_name.c_str());
96  }
97 
98  data = manager.getSharedObjectData<Data>(obj_name);
99  int ret = incShareCount(data);
100  if ( length != 0 ) data->setSize(length, init_value, v_type);
101  return ret;
102  }
103 
104  /*** Typedefs and functions to mimic parts of the vector API ***/
105 
106  typedef typename std::vector<T>::const_iterator const_iterator;
107  typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
108 
109  /**
110  Get the length of the array.
111 
112  @return length of the array
113  */
114  inline size_t size() const { return data->getSize(); }
115 
116  /**
117  Tests if array is empty.
118 
119  @return true if array is empty (size = 0), false otherwise
120  */
121  inline bool empty() const { return data->array.empty(); }
122 
123  /**
124  Get const_iterator to beginning of underlying map
125  */
126  const_iterator begin() const { return data->array.cbegin(); }
127 
128  /**
129  Get const_iterator to end of underlying map
130  */
131  const_iterator end() const { return data->array.cend(); }
132 
133  /**
134  Get const_reverse_iterator to beginning of underlying map
135  */
136  const_reverse_iterator rbegin() const { return data->array.crbegin(); }
137 
138  /**
139  Get const_reverse_iterator to end of underlying map
140  */
141  const_reverse_iterator rend() const { return data->array.crend(); }
142 
143  /**
144  Indicate that the calling element has written all the data it
145  plans to write. Writing to the array through this instance
146  after publish() is called will create an error.
147  */
148  void publish()
149  {
150  if ( published ) return;
151  published = true;
152  incPublishCount(data);
153  }
154 
155  /**
156  Check whether all instances of this SharedArray have called
157  publish(). NOTE: Is is possible that this could return true
158  one round, but false the next if a new instance of the
159  SharedArray was initialized but not published after the last
160  call.
161  */
162  bool isFullyPublished() { return data->isFullyPublished(); }
163 
164  /**
165  Write data to the array. This function is thread-safe, as a
166  mutex is used to ensure only one write at a time.
167 
168  @param index index of the write
169 
170  @param value value to be written
171  */
172  inline void write(int index, const T& value)
173  {
174  if ( published ) {
175  Private::getSimulationOutput().fatal(
176  CALL_INFO, 1, "ERROR: write to SharedArray %s after publish() was called\n", data->getName().c_str());
177  }
178  return data->write(index, value);
179  }
180 
181  /**
182  Read data from the array. This returns a const reference, so
183  is read only.
184 
185  NOTE: This function does not use a mutex, so it is possible to
186  get invalid results if another thread caused a resize of the
187  underlying data structure at the same time as the read.
188  However, after the init() phase of simulation is complete (in
189  setup() and beyond), this is always a safe operation. If
190  reading during init() and you can't guarantee that all elements
191  have already written all data to the SharedArray, use
192  mutex_read() to guarantee thread safety.
193 
194  @param index index to read
195 
196  @return const reference to data at index
197  */
198  inline const T& operator[](int index) const { return data->read(index); }
199 
200  /**
201  Read data from the array. This returns a const reference, so
202  is read only. This version of read is always thread safe (@see
203  operator[]).
204 
205  @param index index to read
206 
207  @return const reference to data at index
208  */
209  inline const T& mutex_read(int index) const { return data->mutex_read(index); }
210 
211  void serialize_order(SST::Core::Serialization::serializer& ser) override
212  {
213  SST::Shared::SharedObject::serialize_order(ser);
214  ser& published;
215  switch ( ser.mode() ) {
216  case SST::Core::Serialization::serializer::SIZER:
217  case SST::Core::Serialization::serializer::PACK:
218  {
219  std::string name = data->getName();
220  ser& name;
221  break;
222  }
223  case SST::Core::Serialization::serializer::UNPACK:
224  {
225  std::string name;
226  ser& name;
227  data = manager.getSharedObjectData<Data>(name);
228  break;
229  }
230  case SST::Core::Serialization::serializer::MAP:
231  // Add your code here
232  break;
233  };
234  }
235  ImplementSerializable(SST::Shared::SharedArray<T>)
236 
237 private:
238  bool published;
239  Data* data;
240 
241  class Data : public SharedObjectData
242  {
243 
244  // Forward declaration. Defined below
245  class ChangeSet;
246 
247  public:
248  std::vector<T> array;
249  std::vector<bool> written;
250  ChangeSet* change_set;
251  T init;
252  verify_type verify;
253 
254  Data() : SharedObjectData(), change_set(nullptr), verify(VERIFY_UNINITIALIZED) {}
255  Data(const std::string& name) : SharedObjectData(name), change_set(nullptr), verify(VERIFY_UNINITIALIZED)
256  {
257  if ( Private::getNumRanks().rank > 1 ) { change_set = new ChangeSet(name); }
258  }
259 
260  ~Data()
261  {
262  if ( change_set ) delete change_set;
263  }
264 
265  /**
266  Set the size of the array. An element can only write up to the
267  current size (reading or writing beyond the size will create
268  undefined behavior). However, an element can put in the size
269  it needs for it's writes and it will end up being the largest
270  size requested. We use a vector underneatch the covers to
271  manage the memory/copying of data.
272  */
273  void setSize(size_t size, const T& init_data, verify_type v_type)
274  {
275  // If the data is uninitialized, then there is nothing to do
276  if ( v_type == VERIFY_UNINITIALIZED ) return;
277  std::lock_guard<std::mutex> lock(mtx);
278  if ( size > array.size() ) {
279  // Need to resize the vector
280  array.resize(size, init_data);
281  if ( v_type == FE_VERIFY ) { written.resize(size); }
282  if ( change_set ) change_set->setSize(size, init_data, v_type);
283  }
284  // init and verify must match across all intances. We can
285  // tell that they have been when verify is not
286  // VERIFY_UNINITIALIZED.
287  if ( verify != VERIFY_UNINITIALIZED ) {
288  if ( init != init_data ) {
289  Private::getSimulationOutput().fatal(
290  CALL_INFO, 1, "ERROR: Two different init_data values passed into SharedArray %s\n",
291  name.c_str());
292  }
293 
294  if ( verify != v_type ) {
295  Private::getSimulationOutput().fatal(
296  CALL_INFO, 1, "ERROR: Two different verify types passed into SharedArray %s\n", name.c_str());
297  }
298  }
299  init = init_data;
300  verify = v_type;
301  }
302 
303  size_t getSize()
304  {
305  std::lock_guard<std::mutex> lock(mtx);
306  return array.size();
307  }
308 
309  void update_write(int index, const T& data)
310  {
311  // Don't need to mutex because this is only ever called
312  // from one thread at a time, with barrier before and
313  // after, or from write(), which does mutex.
314  bool check = false;
315  switch ( verify ) {
316  case FE_VERIFY:
317  check = written[index];
318  break;
319  case INIT_VERIFY:
320  check = array[index] != init;
321  break;
322  default:
323  break;
324  }
325  if ( check && (array[index] != data) ) {
326  Private::getSimulationOutput().fatal(
327  CALL_INFO, 1, "ERROR: wrote two different values to index %d of SharedArray %s\n", index,
328  name.c_str());
329  }
330  array[index] = data;
331  if ( verify == FE_VERIFY ) written[index] = true;
332  }
333 
334  void write(int index, const T& data)
335  {
336  std::lock_guard<std::mutex> lock(mtx);
337  check_lock_for_write("SharedArray");
338  update_write(index, data);
339  if ( verify == FE_VERIFY ) written[index] = true;
340  if ( change_set ) change_set->addChange(index, data);
341  }
342 
343  // Inline the read since it may be called often during run().
344  // This read is not protected from data races in the case where
345  // the array may be resized by another thread. If there is a
346  // danger of the array being resized during init, use the
347  // mutex_read function until after the init phase.
348  inline const T& read(int index) const { return array[index]; }
349 
350  // Mutexed read for use if you are resizing the array as you go
351  inline const T& mutex_read(int index) const
352  {
353  std::lock_guard<std::mutex> lock(mtx);
354  return array[index];
355  }
356 
357  // Functions inherited from SharedObjectData
358  virtual SharedObjectChangeSet* getChangeSet() override { return change_set; }
359  virtual void resetChangeSet() override { change_set->clear(); }
360 
361  void serialize_order(SST::Core::Serialization::serializer& ser) override
362  {
363  SharedObjectData::serialize_order(ser);
364  ser& array;
365  }
366 
367  ImplementSerializable(SST::Shared::SharedArray<T>::Data);
368 
369  private:
370  class ChangeSet : public SharedObjectChangeSet
371  {
372 
373  std::vector<std::pair<int, T>> changes;
374  size_t size;
375  T init;
376  verify_type verify;
377 
378  void serialize_order(SST::Core::Serialization::serializer& ser) override
379  {
380  SharedObjectChangeSet::serialize_order(ser);
381  ser& changes;
382  ser& size;
383  ser& init;
384  ser& verify;
385  }
386 
387  ImplementSerializable(SST::Shared::SharedArray<T>::Data::ChangeSet);
388 
389  public:
390  // For serialization
391  ChangeSet() : SharedObjectChangeSet() {}
392  ChangeSet(const std::string& name) : SharedObjectChangeSet(name), size(0), verify(VERIFY_UNINITIALIZED) {}
393 
394  void addChange(int index, const T& value) { changes.emplace_back(index, value); }
395 
396  void setSize(size_t length, const T& init_data, verify_type v_type)
397  {
398  size = length;
399  init = init_data;
400  verify = v_type;
401  }
402  size_t getSize() { return size; }
403 
404  void applyChanges(SharedObjectDataManager* manager) override
405  {
406  auto data = manager->getSharedObjectData<Data>(getName());
407  data->setSize(size, init, verify);
408  for ( auto x : changes ) {
409  data->update_write(x.first, x.second);
410  }
411  }
412 
413  void clear() override { changes.clear(); }
414  };
415  };
416 };
417 
418 /**
419  SharedArray class. The class is templated to allow for an array
420  of any non-pointer type. The type must be serializable.
421  */
422 template <>
423 class SharedArray<bool> : public SharedObject
424 {
425  // Forward declaration. Defined below
426  class Data;
427 
428 public:
429  /**
430  Default constructor for SharedArray.
431  */
432  SharedArray() : SharedObject(), published(false), data(nullptr) {}
433 
434  /**
435  Shared Array Destructor
436  */
438  {
439  // data does not need to be deleted since the
440  // SharedObjectManager owns the pointer
441  }
442 
443  /**
444  Initialize the SharedArray.
445 
446  @param obj_name Name of the object. This name is how the
447  object is uniquely identified across ranks.
448 
449  @param length Length of the array. The length can be 0 if no
450  data is going to be written by the calling element, otherwise,
451  it must be large enough to write the desired data. The final
452  length of the array will be the maximum of the requested
453  lengths. The length of the array can be queried using the
454  size() method.
455 
456  @param init_value value that entries should be initialized to.
457  By default, each array item will be initialized using the
458  default constructor for the class being stored.
459 
460  @param verify_mode Specifies how multiply written data should
461  be verified. FE_VERIFY uses a full/empty bit for each entry
462  and if a value has previously been written, it will make sure
463  the two values match. INIT_VERIFY will simply compare writes
464  against the current value and will error unless the values
465  aren't the same or the existing value is the init_value. When
466  NO_VERIFY is passed, no verification will occur. This is
467  mostly useful when you can guarantee that multiple elements
468  won't write the same value and you want to do in-place
469  modifications as you initialize. VERIFY_UNINITIALIZED is a
470  reserved value and should not be passed.
471 
472  @return returns the number of instances that have intialized
473  themselve before this instance on this MPI rank.
474  */
476  const std::string& obj_name, size_t length = 0, bool init_value = false, verify_type v_type = INIT_VERIFY)
477  {
478  if ( data ) {
479  Private::getSimulationOutput().fatal(
480  CALL_INFO, 1, "ERROR: called initialize() of SharedArray %s more than once\n", obj_name.c_str());
481  }
482 
483  if ( v_type == VERIFY_UNINITIALIZED ) {
484  Private::getSimulationOutput().fatal(
485  CALL_INFO, 1,
486  "ERROR: VERIFY_UNINITIALIZED passed into instance of SharedArray %s. "
487  "This is a reserved value and cannot be passed in here. \n",
488  obj_name.c_str());
489  }
490  data = manager.getSharedObjectData<Data>(obj_name);
491  int ret = incShareCount(data);
492  if ( length != 0 ) { data->setSize(length, init_value, v_type); }
493 
494  return ret;
495  }
496 
497  /*** Typedefs and functions to mimic parts of the vector API ***/
498 
499  typedef typename std::vector<bool>::const_iterator const_iterator;
500  typedef typename std::vector<bool>::const_reverse_iterator const_reverse_iterator;
501 
502  /**
503  Get the length of the array.
504 
505  @return length of the array
506  */
507  inline size_t size() const { return data->getSize(); }
508 
509  /**
510  Tests if array is empty.
511 
512  @return true if array is empty (size = 0), false otherwise
513  */
514  inline bool empty() const { return data->array.empty(); }
515 
516  /**
517  Get const_iterator to beginning of underlying map
518  */
519  const_iterator begin() const { return data->array.cbegin(); }
520 
521  /**
522  Get const_iterator to end of underlying map
523  */
524  const_iterator end() const { return data->array.cend(); }
525 
526  /**
527  Get const_reverse_iterator to beginning of underlying map
528  */
529  const_reverse_iterator rbegin() const { return data->array.crbegin(); }
530 
531  /**
532  Get const_reverse_iterator to end of underlying map
533  */
534  const_reverse_iterator rend() const { return data->array.crend(); }
535 
536  /**
537  Indicate that the calling element has written all the data it
538  plans to write. Writing to the array through this instance
539  after publish() is called will create an error.
540  */
541  void publish()
542  {
543  if ( published ) return;
544  published = true;
545  incPublishCount(data);
546  }
547 
548  /**
549  Check whether all instances of this SharedArray have called
550  publish(). NOTE: Is is possible that this could return true
551  one round, but false the next if a new instance of the
552  SharedArray was initialized but not published after the last
553  call.
554  */
555  bool isFullyPublished() { return data->isFullyPublished(); }
556 
557  /**
558  Write data to the array. This function is thread-safe, as a
559  mutex is used to ensure only one write at a time.
560 
561  @param index index of the write
562 
563  @param value value to be written
564  */
565  inline void write(int index, bool value)
566  {
567  if ( published ) {
568  Private::getSimulationOutput().fatal(
569  CALL_INFO, 1, "ERROR: write to SharedArray %s after publish() was called\n", data->getName().c_str());
570  }
571  return data->write(index, value);
572  }
573 
574  /**
575  Read data from the array. This returns a const reference, so
576  is read only.
577 
578  NOTE: This function does not use a mutex, so it is possible to
579  get invalid results if another thread caused a resize of the
580  underlying data structure at the same time as the read.
581  However, after the init() phase of simulation is complete (in
582  setup() and beyond), this is always a safe operation. If
583  reading during init() and you can't guarantee that all elements
584  have already written all data to the SharedArray, use
585  mutex_read() to guarantee thread safety.
586 
587  @param index index to read
588 
589  @return const reference to data at index
590  */
591  inline bool operator[](int index) const { return data->read(index); }
592 
593  /**
594  Read data from the array. This returns a const reference, so
595  is read only. This version of read is always thread safe (@see
596  operator[]).
597 
598  @param index index to read
599 
600  @return const reference to data at index
601  */
602  inline bool mutex_read(int index) const { return data->mutex_read(index); }
603 
604  void serialize_order(SST::Core::Serialization::serializer& ser) override
605  {
606  SST::Shared::SharedObject::serialize_order(ser);
607  ser& published;
608  switch ( ser.mode() ) {
609  case SST::Core::Serialization::serializer::SIZER:
610  case SST::Core::Serialization::serializer::PACK:
611  {
612  std::string name = data->getName();
613  ser& name;
614  break;
615  }
616  case SST::Core::Serialization::serializer::UNPACK:
617  {
618  std::string name;
619  ser& name;
620  data = manager.getSharedObjectData<Data>(name);
621  break;
622  }
623  case SST::Core::Serialization::serializer::MAP:
624  // Add your code here
625  break;
626  };
627  }
628  ImplementSerializable(SST::Shared::SharedArray<bool>)
629 
630 private:
631  bool published;
632  Data* data;
633 
634  class Data : public SharedObjectData
635  {
636 
637  // Forward declaration. Defined below
638  class ChangeSet;
639 
640  public:
641  std::vector<bool> array;
642  std::vector<bool> written;
643  ChangeSet* change_set;
644  bool init;
645  verify_type verify;
646 
647  Data() : SharedObjectData(), change_set(nullptr), verify(VERIFY_UNINITIALIZED) {} // For serialization ONLY
648  Data(const std::string& name) : SharedObjectData(name), change_set(nullptr), verify(VERIFY_UNINITIALIZED)
649  {
650  if ( Private::getNumRanks().rank > 1 ) { change_set = new ChangeSet(name); }
651  }
652 
653  ~Data()
654  {
655  if ( change_set ) delete change_set;
656  }
657 
658  /**
659  Set the size of the array. An element can only write up to the
660  current size (reading or writing beyond the size will create
661  undefined behavior). However, an element can put in the size
662  it needs for its writes and it will end up being the largest
663  size requested. We use a vector underneatch the covers to
664  manage the memory/copying of data.
665  */
666  void setSize(size_t size, bool init_data, verify_type v_type)
667  {
668  // If the data is uninitialized, then there is nothing to do
669  if ( v_type == VERIFY_UNINITIALIZED ) return;
670  std::lock_guard<std::mutex> lock(mtx);
671  if ( size > array.size() ) {
672  // Need to resize the vector
673  array.resize(size, init_data);
674  if ( v_type == FE_VERIFY ) { written.resize(size); }
675  if ( change_set ) change_set->setSize(size, init_data, v_type);
676  }
677  // init and verify must match across all intances. We can
678  // tell that they have been when verify is not
679  // VERIFY_UNINITIALIZED.
680  if ( verify != VERIFY_UNINITIALIZED ) {
681  if ( init != init_data ) {
682  Private::getSimulationOutput().fatal(
683  CALL_INFO, 1, "ERROR: Two different init_data values passed into SharedArray %s\n",
684  name.c_str());
685  }
686 
687  if ( verify != v_type ) {
688  Private::getSimulationOutput().fatal(
689  CALL_INFO, 1, "ERROR: Two different verify types passed into SharedArray %s\n", name.c_str());
690  }
691  }
692  init = init_data;
693  verify = v_type;
694  }
695 
696  size_t getSize()
697  {
698  std::lock_guard<std::mutex> lock(mtx);
699  return array.size();
700  }
701 
702  void update_write(int index, bool data)
703  {
704  // Don't need to mutex because this is only ever called
705  // from one thread at a time, with barrier before and
706  // after, or from write(), which does mutex.
707  bool check = false;
708  switch ( verify ) {
709  case FE_VERIFY:
710  check = written[index];
711  break;
712  case INIT_VERIFY:
713  check = array[index] != init;
714  break;
715  default:
716  break;
717  }
718  if ( check && (array[index] != data) ) {
719  Private::getSimulationOutput().fatal(
720  CALL_INFO, 1, "ERROR: wrote two different values to index %d of SharedArray %s\n", index,
721  name.c_str());
722  }
723  array[index] = data;
724  if ( verify == FE_VERIFY ) written[index] = true;
725  }
726 
727  void write(int index, bool data)
728  {
729  std::lock_guard<std::mutex> lock(mtx);
730  check_lock_for_write("SharedArray");
731  update_write(index, data);
732  if ( verify == FE_VERIFY ) written[index] = true;
733  if ( change_set ) change_set->addChange(index, data);
734  }
735 
736  // Inline the read since it may be called often during run().
737  // This read is not protected from data races in the case where
738  // the array may be resized by another thread. If there is a
739  // danger of the array being resized during init, use the
740  // mutex_read function until after the init phase.
741  inline bool read(int index) const { return array[index]; }
742 
743  // Mutexed read for use if you are resizing the array as you go
744  inline bool mutex_read(int index) const
745  {
746  std::lock_guard<std::mutex> lock(mtx);
747  return array[index];
748  }
749 
750  // Functions inherited from SharedObjectData
751  virtual SharedObjectChangeSet* getChangeSet() override { return change_set; }
752  virtual void resetChangeSet() override { change_set->clear(); }
753 
754  void serialize_order(SST::Core::Serialization::serializer& ser) override
755  {
756  SharedObjectData::serialize_order(ser);
757  ser& array;
758  // All other members are not needed past init()
759  }
760 
761  ImplementSerializable(SST::Shared::SharedArray<bool>::Data);
762 
763  private:
764  class ChangeSet : public SharedObjectChangeSet
765  {
766 
767  std::vector<std::pair<int, bool>> changes;
768  size_t size;
769  bool init;
770  verify_type verify;
771 
772  void serialize_order(SST::Core::Serialization::serializer& ser) override
773  {
774  SharedObjectChangeSet::serialize_order(ser);
775  ser& changes;
776  ser& size;
777  ser& init;
778  ser& verify;
779  }
780 
782 
783  public:
784  // For serialization
785  ChangeSet() : SharedObjectChangeSet() {}
786  ChangeSet(const std::string& name) : SharedObjectChangeSet(name), size(0), verify(VERIFY_UNINITIALIZED) {}
787 
788  void addChange(int index, bool value) { changes.emplace_back(index, value); }
789 
790  void setSize(size_t length, bool init_data, verify_type v_type)
791  {
792  size = length;
793  init = init_data;
794  verify = v_type;
795  }
796  size_t getSize() { return size; }
797 
798  void applyChanges(SharedObjectDataManager* manager) override
799  {
800  auto data = manager->getSharedObjectData<Data>(getName());
801  data->setSize(size, init, verify);
802  for ( auto x : changes ) {
803  data->update_write(x.first, x.second);
804  }
805  }
806 
807  void clear() override { changes.clear(); }
808  };
809  };
810 };
811 } // namespace Shared
812 } // namespace SST
813 
814 #endif // SST_CORE_SHARED_SHAREDARRAY_H
size_t size() const
Get the length of the array.
Definition: sharedArray.h:507
virtual SharedObjectChangeSet * getChangeSet() override
Gets the changeset for this data on this rank.
Definition: sharedArray.h:358
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:43
virtual SharedObjectChangeSet * getChangeSet() override
Gets the changeset for this data on this rank.
Definition: sharedArray.h:751
Definition: sharedObject.h:269
const_reverse_iterator rbegin() const
Get const_reverse_iterator to beginning of underlying map.
Definition: sharedArray.h:136
const T & operator[](int index) const
Read data from the array.
Definition: sharedArray.h:198
const_iterator begin() const
Get const_iterator to beginning of underlying map.
Definition: sharedArray.h:519
virtual void resetChangeSet() override
Resets the changeset for this data on this rank.
Definition: sharedArray.h:752
void lock()
Called by the core when writing to shared regions is no longer allowed.
Definition: sharedObject.h:186
bool isFullyPublished()
Checks to see if all instances of this SharedObject have called publish().
Definition: sharedObject.h:109
void publish()
Indicate that the calling element has written all the data it plans to write.
Definition: sharedArray.h:148
size_t size() const
Get the length of the array.
Definition: sharedArray.h:114
SharedArray()
Default constructor for SharedArray.
Definition: sharedArray.h:432
Definition: action.cc:18
const_reverse_iterator rend() const
Get const_reverse_iterator to end of underlying map.
Definition: sharedArray.h:141
bool empty() const
Tests if array is empty.
Definition: sharedArray.h:514
verify_type
Enum of verify types.
Definition: sharedObject.h:276
bool empty() const
Tests if array is empty.
Definition: sharedArray.h:121
SharedArray class.
Definition: sharedArray.h:423
void write(int index, const T &value)
Write data to the array.
Definition: sharedArray.h:172
int initialize(const std::string &obj_name, size_t length=0, bool init_value=false, verify_type v_type=INIT_VERIFY)
Initialize the SharedArray.
Definition: sharedArray.h:475
const_iterator begin() const
Get const_iterator to beginning of underlying map.
Definition: sharedArray.h:126
void write(int index, bool value)
Write data to the array.
Definition: sharedArray.h:565
bool isFullyPublished()
Check whether all instances of this SharedArray have called publish().
Definition: sharedArray.h:162
void setSize(size_t size, bool init_data, verify_type v_type)
Set the size of the array.
Definition: sharedArray.h:666
virtual void resetChangeSet() override
Resets the changeset for this data on this rank.
Definition: sharedArray.h:359
const_reverse_iterator rend() const
Get const_reverse_iterator to end of underlying map.
Definition: sharedArray.h:534
bool mutex_read(int index) const
Read data from the array.
Definition: sharedArray.h:602
SharedArray()
Default constructor for SharedArray.
Definition: sharedArray.h:40
const_reverse_iterator rbegin() const
Get const_reverse_iterator to beginning of underlying map.
Definition: sharedArray.h:529
void publish()
Indicate that the calling element has written all the data it plans to write.
Definition: sharedArray.h:541
const_iterator end() const
Get const_iterator to end of underlying map.
Definition: sharedArray.h:524
SharedArray class.
Definition: sharedArray.h:29
Definition: sharedArray.h:241
~SharedArray()
Shared Array Destructor.
Definition: sharedArray.h:437
~SharedArray()
Shared Array Destructor.
Definition: sharedArray.h:45
int initialize(const std::string &obj_name, size_t length=0, T init_value=T(), verify_type v_type=INIT_VERIFY)
Initialize the SharedArray.
Definition: sharedArray.h:83
const std::string & getName()
Get the name of the SharedObject for this data.
Definition: sharedObject.h:99
virtual void applyChanges(SharedObjectDataManager *UNUSED(manager))=0
Apply the changes to the name shared data.
This is the base class for holding data on changes made to the shared data on each rank...
Definition: sharedObject.h:44
const T & mutex_read(int index) const
Read data from the array.
Definition: sharedArray.h:209
const_iterator end() const
Get const_iterator to end of underlying map.
Definition: sharedArray.h:131
Base class for holding SharedObject data.
Definition: sharedObject.h:87
bool isFullyPublished()
Check whether all instances of this SharedArray have called publish().
Definition: sharedArray.h:555
bool operator[](int index) const
Read data from the array.
Definition: sharedArray.h:591
void setSize(size_t size, const T &init_data, verify_type v_type)
Set the size of the array.
Definition: sharedArray.h:273