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