12#ifndef SST_CORE_SHARED_SHAREDARRAY_H
13#define SST_CORE_SHARED_SHAREDARRAY_H
15#include "sst/core/serialization/serializable.h"
16#include "sst/core/shared/sharedObject.h"
17#include "sst/core/sst_types.h"
24namespace SST::Shared {
33 static_assert(!std::is_pointer_v<T>,
"Cannot use a pointer type with SharedArray");
89 int initialize(
const std::string& obj_name,
size_t length = 0, T init_value = T(),
verify_type v_type = INIT_VERIFY)
92 Private::getSimulationOutput().fatal(
93 CALL_INFO, 1,
"ERROR: called initialize() of SharedArray %s more than once\n", obj_name.c_str());
96 if ( v_type == VERIFY_UNINITIALIZED ) {
97 Private::getSimulationOutput().fatal(CALL_INFO, 1,
98 "ERROR: VERIFY_UNINITIALIZED passed into instance of SharedArray %s. "
99 "This is a reserved value and cannot be passed in here. \n",
103 data = manager.getSharedObjectData<
Data>(obj_name);
104 int ret = incShareCount(data);
105 if ( length != 0 ) data->setSize(length, init_value, v_type);
111 using const_iterator =
typename std::vector<T>::const_iterator;
112 using const_reverse_iterator =
typename std::vector<T>::const_reverse_iterator;
119 inline size_t size()
const {
return data->getSize(); }
126 inline bool empty()
const {
return data->array.empty(); }
131 const_iterator
begin()
const {
return data->array.cbegin(); }
136 const_iterator
end()
const {
return data->array.cend(); }
141 const_reverse_iterator
rbegin()
const {
return data->array.crbegin(); }
146 const_reverse_iterator
rend()
const {
return data->array.crend(); }
155 if ( published )
return;
157 incPublishCount(data);
177 inline void write(
int index,
const T& value)
180 Private::getSimulationOutput().fatal(
181 CALL_INFO, 1,
"ERROR: write to SharedArray %s after publish() was called\n", data->getName().c_str());
183 return data->write(index, value);
203 inline const T&
operator[](
int index)
const {
return data->read(index); }
214 inline const T&
mutex_read(
int index)
const {
return data->mutex_read(index); }
218 SST::Shared::SharedObject::serialize_order(ser);
220 switch ( ser.mode() ) {
221 case SST::Core::Serialization::serializer::SIZER:
222 case SST::Core::Serialization::serializer::PACK:
224 std::string name = data->
getName();
228 case SST::Core::Serialization::serializer::UNPACK:
232 data = manager.getSharedObjectData<Data>(name);
235 case SST::Core::Serialization::serializer::MAP:
240 ImplementSerializable(SST::Shared::SharedArray<T>)
253 std::vector<T> array;
254 std::vector<bool> written;
255 ChangeSet* change_set;
262 verify(VERIFY_UNINITIALIZED)
264 explicit Data(
const std::string& name) :
267 verify(VERIFY_UNINITIALIZED)
269 if ( Private::getNumRanks().rank > 1 ) {
270 change_set =
new ChangeSet(name);
276 if ( change_set )
delete change_set;
290 if ( v_type == VERIFY_UNINITIALIZED )
return;
291 std::lock_guard<std::mutex>
lock(mtx);
292 if (
size > array.size() ) {
294 array.resize(
size, init_data);
295 if ( v_type == FE_VERIFY ) {
296 written.resize(
size);
298 if ( change_set ) change_set->setSize(
size, init_data, v_type);
303 if ( verify != VERIFY_UNINITIALIZED ) {
304 if ( init != init_data ) {
305 Private::getSimulationOutput().fatal(CALL_INFO, 1,
306 "ERROR: Two different init_data values passed into SharedArray %s\n", name.c_str());
309 if ( verify != v_type ) {
310 Private::getSimulationOutput().fatal(
311 CALL_INFO, 1,
"ERROR: Two different verify types passed into SharedArray %s\n", name.c_str());
320 std::lock_guard<std::mutex>
lock(mtx);
324 void update_write(
int index,
const T& data)
332 check = written[index];
335 check = array[index] != init;
340 if ( check && (array[index] != data) ) {
341 Private::getSimulationOutput().fatal(CALL_INFO, 1,
342 "ERROR: wrote two different values to index %d of SharedArray %s\n", index, name.c_str());
345 if ( verify == FE_VERIFY ) written[index] =
true;
348 void write(
int index,
const T& data)
350 std::lock_guard<std::mutex>
lock(mtx);
351 check_lock_for_write(
"SharedArray");
352 update_write(index, data);
353 if ( verify == FE_VERIFY ) written[index] =
true;
354 if ( change_set ) change_set->addChange(index, data);
362 inline const T& read(
int index)
const {
return array[index]; }
365 inline const T& mutex_read(
int index)
const
367 std::lock_guard<std::mutex>
lock(mtx);
377 SharedObjectData::serialize_order(ser);
387 std::vector<std::pair<int, T>> changes;
394 SharedObjectChangeSet::serialize_order(ser);
401 ImplementSerializable(SST::Shared::SharedArray<T>::Data::ChangeSet);
406 SharedObjectChangeSet()
408 explicit ChangeSet(
const std::string& name) :
409 SharedObjectChangeSet(name),
411 verify(VERIFY_UNINITIALIZED)
414 void addChange(
int index,
const T& value) { changes.emplace_back(index, value); }
416 void setSize(
size_t length,
const T& init_data,
verify_type v_type)
422 size_t getSize() {
return size; }
424 void applyChanges(SharedObjectDataManager* manager)
override
426 auto data = manager->getSharedObjectData<Data>(
getName());
427 data->setSize(size, init, verify);
428 for (
auto x : changes ) {
429 data->update_write(x.first, x.second);
433 void clear()
override { changes.clear(); }
500 const std::string& obj_name,
size_t length = 0,
bool init_value =
false,
verify_type v_type = INIT_VERIFY)
503 Private::getSimulationOutput().fatal(
504 CALL_INFO, 1,
"ERROR: called initialize() of SharedArray %s more than once\n", obj_name.c_str());
507 if ( v_type == VERIFY_UNINITIALIZED ) {
508 Private::getSimulationOutput().fatal(CALL_INFO, 1,
509 "ERROR: VERIFY_UNINITIALIZED passed into instance of SharedArray %s. "
510 "This is a reserved value and cannot be passed in here. \n",
513 data = manager.getSharedObjectData<
Data>(obj_name);
514 int ret = incShareCount(data);
516 data->setSize(length, init_value, v_type);
524 using const_iterator =
typename std::vector<bool>::const_iterator;
525 using const_reverse_iterator =
typename std::vector<bool>::const_reverse_iterator;
532 inline size_t size()
const {
return data->getSize(); }
539 inline bool empty()
const {
return data->array.empty(); }
544 const_iterator
begin()
const {
return data->array.cbegin(); }
549 const_iterator
end()
const {
return data->array.cend(); }
554 const_reverse_iterator
rbegin()
const {
return data->array.crbegin(); }
559 const_reverse_iterator
rend()
const {
return data->array.crend(); }
568 if ( published )
return;
570 incPublishCount(data);
590 inline void write(
int index,
bool value)
593 Private::getSimulationOutput().fatal(
594 CALL_INFO, 1,
"ERROR: write to SharedArray %s after publish() was called\n", data->getName().c_str());
596 return data->write(index, value);
616 inline bool operator[](
int index)
const {
return data->read(index); }
627 inline bool mutex_read(
int index)
const {
return data->mutex_read(index); }
631 SST::Shared::SharedObject::serialize_order(ser);
633 switch ( ser.mode() ) {
634 case SST::Core::Serialization::serializer::SIZER:
635 case SST::Core::Serialization::serializer::PACK:
637 std::string name = data->getName();
641 case SST::Core::Serialization::serializer::UNPACK:
645 data = manager.getSharedObjectData<Data>(name);
648 case SST::Core::Serialization::serializer::MAP:
653 ImplementSerializable(SST::Shared::SharedArray<bool>)
666 std::vector<bool> array;
667 std::vector<bool> written;
668 ChangeSet* change_set;
675 verify(VERIFY_UNINITIALIZED)
677 explicit Data(
const std::string& name) :
680 verify(VERIFY_UNINITIALIZED)
682 if ( Private::getNumRanks().rank > 1 ) {
683 change_set =
new ChangeSet(name);
689 if ( change_set )
delete change_set;
703 if ( v_type == VERIFY_UNINITIALIZED )
return;
704 std::lock_guard<std::mutex>
lock(mtx);
705 if (
size > array.size() ) {
707 array.resize(
size, init_data);
708 if ( v_type == FE_VERIFY ) {
709 written.resize(
size);
711 if ( change_set ) change_set->setSize(
size, init_data, v_type);
716 if ( verify != VERIFY_UNINITIALIZED ) {
717 if ( init != init_data ) {
718 Private::getSimulationOutput().fatal(CALL_INFO, 1,
719 "ERROR: Two different init_data values passed into SharedArray %s\n", name.c_str());
722 if ( verify != v_type ) {
723 Private::getSimulationOutput().fatal(
724 CALL_INFO, 1,
"ERROR: Two different verify types passed into SharedArray %s\n", name.c_str());
733 std::lock_guard<std::mutex>
lock(mtx);
737 void update_write(
int index,
bool data)
745 check = written[index];
748 check = array[index] != init;
753 if ( check && (array[index] != data) ) {
754 Private::getSimulationOutput().fatal(CALL_INFO, 1,
755 "ERROR: wrote two different values to index %d of SharedArray %s\n", index, name.c_str());
758 if ( verify == FE_VERIFY ) written[index] =
true;
761 void write(
int index,
bool data)
763 std::lock_guard<std::mutex>
lock(mtx);
764 check_lock_for_write(
"SharedArray");
765 update_write(index, data);
766 if ( verify == FE_VERIFY ) written[index] =
true;
767 if ( change_set ) change_set->addChange(index, data);
775 inline bool read(
int index)
const {
return array[index]; }
778 inline bool mutex_read(
int index)
const
780 std::lock_guard<std::mutex>
lock(mtx);
790 SharedObjectData::serialize_order(ser);
801 std::vector<std::pair<int, bool>> changes;
808 SharedObjectChangeSet::serialize_order(ser);
815 ImplementSerializable(SST::Shared::SharedArray<bool>::Data::ChangeSet);
820 SharedObjectChangeSet()
822 explicit ChangeSet(
const std::string& name) :
823 SharedObjectChangeSet(name),
825 verify(VERIFY_UNINITIALIZED)
828 void addChange(
int index,
bool value) { changes.emplace_back(index, value); }
830 void setSize(
size_t length,
bool init_data,
verify_type v_type)
836 size_t getSize() {
return size; }
838 void applyChanges(SharedObjectDataManager* manager)
override
840 auto data = manager->getSharedObjectData<Data>(
getName());
841 data->setSize(size, init, verify);
842 for (
auto x : changes ) {
843 data->update_write(x.first, x.second);
847 void clear()
override { changes.clear(); }
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:45
Definition sharedArray.h:247
virtual SharedObjectChangeSet * getChangeSet() override
Gets the changeset for this data on this rank.
Definition sharedArray.h:372
virtual void resetChangeSet() override
Resets the changeset for this data on this rank.
Definition sharedArray.h:373
void setSize(size_t size, const T &init_data, verify_type v_type)
Set the size of the array.
Definition sharedArray.h:287
Definition sharedArray.h:660
void setSize(size_t size, bool init_data, verify_type v_type)
Set the size of the array.
Definition sharedArray.h:700
virtual void resetChangeSet() override
Resets the changeset for this data on this rank.
Definition sharedArray.h:786
virtual SharedObjectChangeSet * getChangeSet() override
Gets the changeset for this data on this rank.
Definition sharedArray.h:785
SharedArray()
Default constructor for SharedArray.
Definition sharedArray.h:452
size_t size() const
Get the length of the array.
Definition sharedArray.h:532
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:499
const_iterator begin() const
Get const_iterator to beginning of underlying map.
Definition sharedArray.h:544
bool empty() const
Tests if array is empty.
Definition sharedArray.h:539
bool isFullyPublished()
Check whether all instances of this SharedArray have called publish().
Definition sharedArray.h:580
void write(int index, bool value)
Write data to the array.
Definition sharedArray.h:590
bool mutex_read(int index) const
Read data from the array.
Definition sharedArray.h:627
const_reverse_iterator rend() const
Get const_reverse_iterator to end of underlying map.
Definition sharedArray.h:559
~SharedArray()
Shared Array Destructor.
Definition sharedArray.h:461
void publish()
Indicate that the calling element has written all the data it plans to write.
Definition sharedArray.h:566
bool operator[](int index) const
Read data from the array.
Definition sharedArray.h:616
const_iterator end() const
Get const_iterator to end of underlying map.
Definition sharedArray.h:549
const_reverse_iterator rbegin() const
Get const_reverse_iterator to beginning of underlying map.
Definition sharedArray.h:554
size_t size() const
Get the length of the array.
Definition sharedArray.h:119
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:89
const T & mutex_read(int index) const
Read data from the array.
Definition sharedArray.h:214
const_iterator begin() const
Get const_iterator to beginning of underlying map.
Definition sharedArray.h:131
const_iterator end() const
Get const_iterator to end of underlying map.
Definition sharedArray.h:136
bool empty() const
Tests if array is empty.
Definition sharedArray.h:126
SharedArray()
Default constructor for SharedArray.
Definition sharedArray.h:42
~SharedArray()
Shared Array Destructor.
Definition sharedArray.h:51
const_reverse_iterator rend() const
Get const_reverse_iterator to end of underlying map.
Definition sharedArray.h:146
const T & operator[](int index) const
Read data from the array.
Definition sharedArray.h:203
void publish()
Indicate that the calling element has written all the data it plans to write.
Definition sharedArray.h:153
void write(int index, const T &value)
Write data to the array.
Definition sharedArray.h:177
bool isFullyPublished()
Check whether all instances of this SharedArray have called publish().
Definition sharedArray.h:167
const_reverse_iterator rbegin() const
Get const_reverse_iterator to beginning of underlying map.
Definition sharedArray.h:141
This is the base class for holding data on changes made to the shared data on each rank.
Definition sharedObject.h:46
const std::string & getName()
Get the name of the shared data the changeset should be applied to.
Definition sharedObject.h:75
const std::string & getName()
Get the name of the SharedObject for this data.
Definition sharedObject.h:102
SharedObjectData(const std::string &name)
Constructor for SharedObjectData.
Definition sharedObject.h:196
void lock()
Called by the core when writing to shared regions is no longer allowed.
Definition sharedObject.h:189
verify_type
Enum of verify types.
Definition sharedObject.h:281