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