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"
26namespace SST::Shared {
35 static_assert(!std::is_pointer_v<T>,
"Cannot use a pointer type with SharedArray");
91 int initialize(
const std::string& obj_name,
size_t length = 0, T init_value = T(),
verify_type v_type = INIT_VERIFY)
94 Private::getSimulationOutput().fatal(
95 CALL_INFO, 1,
"ERROR: called initialize() of SharedArray %s more than once\n", obj_name.c_str());
98 if ( v_type == VERIFY_UNINITIALIZED ) {
99 Private::getSimulationOutput().fatal(CALL_INFO, 1,
100 "ERROR: VERIFY_UNINITIALIZED passed into instance of SharedArray %s. "
101 "This is a reserved value and cannot be passed in here. \n",
105 data = manager.getSharedObjectData<
Data>(obj_name);
106 int ret = incShareCount(data);
107 if ( length != 0 ) data->setSize(length, init_value, v_type);
113 using const_iterator =
typename std::vector<T>::const_iterator;
114 using const_reverse_iterator =
typename std::vector<T>::const_reverse_iterator;
121 inline size_t size()
const {
return data->getSize(); }
128 inline bool empty()
const {
return data->array.empty(); }
133 const_iterator
begin()
const {
return data->array.cbegin(); }
138 const_iterator
end()
const {
return data->array.cend(); }
143 const_reverse_iterator
rbegin()
const {
return data->array.crbegin(); }
148 const_reverse_iterator
rend()
const {
return data->array.crend(); }
157 if ( published )
return;
159 incPublishCount(data);
179 inline void write(
int index,
const T& value)
182 Private::getSimulationOutput().fatal(
183 CALL_INFO, 1,
"ERROR: write to SharedArray %s after publish() was called\n", data->getName().c_str());
185 return data->write(index, value);
205 inline const T&
operator[](
int index)
const {
return data->read(index); }
216 inline const T&
mutex_read(
int index)
const {
return data->mutex_read(index); }
218 void serialize_order(
serializer& ser)
override
220 SharedObject::serialize_order(ser);
222 const auto mode = ser.mode();
223 initialized = data !=
nullptr;
225 if ( mode == serializer::MAP )
228 SST_SER(published, SerOption::map_read_only);
229 SST_SER(initialized, SerOption::map_read_only);
232 case serializer::SIZER:
233 case serializer::PACK:
235 if ( !initialized )
return;
236 std::string name = data->
getName();
240 case serializer::UNPACK:
242 if ( !initialized )
return;
245 data = manager.getSharedObjectData<Data>(name);
248 case serializer::MAP:
249 if ( initialized ) SST_SER_NAME(data->array,
"data");
250 ser.mapper().map_hierarchy_end();
258 bool published =
false;
259 Data* data =
nullptr;
260 bool initialized =
false;
269 std::vector<T> array;
270 std::vector<bool> written;
271 ChangeSet* change_set;
278 verify(VERIFY_UNINITIALIZED)
280 explicit Data(
const std::string& name) :
283 verify(VERIFY_UNINITIALIZED)
285 if ( Private::getNumRanks().rank > 1 ) {
286 change_set =
new ChangeSet(name);
292 if ( change_set )
delete change_set;
306 if ( v_type == VERIFY_UNINITIALIZED )
return;
307 std::lock_guard<std::mutex>
lock(mtx);
308 if (
size > array.size() ) {
310 array.resize(
size, init_data);
311 if ( v_type == FE_VERIFY ) {
312 written.resize(
size);
314 if ( change_set ) change_set->setSize(
size, init_data, v_type);
319 if ( verify != VERIFY_UNINITIALIZED ) {
320 if ( init != init_data ) {
321 Private::getSimulationOutput().fatal(CALL_INFO, 1,
322 "ERROR: Two different init_data values passed into SharedArray %s\n", name.c_str());
325 if ( verify != v_type ) {
326 Private::getSimulationOutput().fatal(
327 CALL_INFO, 1,
"ERROR: Two different verify types passed into SharedArray %s\n", name.c_str());
336 std::lock_guard<std::mutex>
lock(mtx);
340 void update_write(
int index,
const T& data)
348 check = written[index];
351 check = array[index] != init;
356 if ( check && (array[index] != data) ) {
357 Private::getSimulationOutput().fatal(CALL_INFO, 1,
358 "ERROR: wrote two different values to index %d of SharedArray %s\n", index, name.c_str());
361 if ( verify == FE_VERIFY ) written[index] =
true;
364 void write(
int index,
const T& data)
366 std::lock_guard<std::mutex>
lock(mtx);
367 check_lock_for_write(
"SharedArray");
368 update_write(index, data);
369 if ( verify == FE_VERIFY ) written[index] =
true;
370 if ( change_set ) change_set->addChange(index, data);
378 inline const T& read(
int index)
const {
return array[index]; }
381 inline const T& mutex_read(
int index)
const
383 std::lock_guard<std::mutex>
lock(mtx);
391 void serialize_order(
serializer& ser)
override
393 SharedObjectData::serialize_order(ser);
403 std::vector<std::pair<int, T>> changes;
408 void serialize_order(
serializer& ser)
override
410 SharedObjectChangeSet::serialize_order(ser);
417 ImplementSerializable(SharedArray<T>::Data::ChangeSet);
422 SharedObjectChangeSet()
424 explicit ChangeSet(
const std::string& name) :
425 SharedObjectChangeSet(name),
427 verify(VERIFY_UNINITIALIZED)
430 void addChange(
int index,
const T& value) { changes.emplace_back(index, value); }
432 void setSize(
size_t length,
const T& init_data,
verify_type v_type)
438 size_t getSize() {
return size; }
440 void applyChanges(SharedObjectDataManager* manager)
override
442 auto data = manager->getSharedObjectData<Data>(
getName());
443 data->setSize(size, init, verify);
444 for (
auto x : changes ) {
445 data->update_write(x.first, x.second);
449 void clear()
override { changes.clear(); }
516 const std::string& obj_name,
size_t length = 0,
bool init_value =
false,
verify_type v_type = INIT_VERIFY)
519 Private::getSimulationOutput().fatal(
520 CALL_INFO, 1,
"ERROR: called initialize() of SharedArray %s more than once\n", obj_name.c_str());
523 if ( v_type == VERIFY_UNINITIALIZED ) {
524 Private::getSimulationOutput().fatal(CALL_INFO, 1,
525 "ERROR: VERIFY_UNINITIALIZED passed into instance of SharedArray %s. "
526 "This is a reserved value and cannot be passed in here. \n",
529 data = manager.getSharedObjectData<
Data>(obj_name);
530 int ret = incShareCount(data);
532 data->setSize(length, init_value, v_type);
540 using const_iterator =
typename std::vector<bool>::const_iterator;
541 using const_reverse_iterator =
typename std::vector<bool>::const_reverse_iterator;
548 inline size_t size()
const {
return data->getSize(); }
555 inline bool empty()
const {
return data->array.empty(); }
560 const_iterator
begin()
const {
return data->array.cbegin(); }
565 const_iterator
end()
const {
return data->array.cend(); }
570 const_reverse_iterator
rbegin()
const {
return data->array.crbegin(); }
575 const_reverse_iterator
rend()
const {
return data->array.crend(); }
584 if ( published )
return;
586 incPublishCount(data);
606 inline void write(
int index,
bool value)
609 Private::getSimulationOutput().fatal(
610 CALL_INFO, 1,
"ERROR: write to SharedArray %s after publish() was called\n", data->getName().c_str());
612 return data->write(index, value);
632 inline bool operator[](
int index)
const {
return data->read(index); }
643 inline bool mutex_read(
int index)
const {
return data->mutex_read(index); }
645 void serialize_order(
serializer& ser)
override
647 SharedObject::serialize_order(ser);
649 const auto mode = ser.mode();
650 initialized = data !=
nullptr;
652 if ( mode == serializer::MAP )
655 SST_SER(published, SerOption::map_read_only);
656 SST_SER(initialized, SerOption::map_read_only);
659 case serializer::SIZER:
660 case serializer::PACK:
662 if ( !initialized )
return;
663 std::string name = data->getName();
667 case serializer::UNPACK:
669 if ( !initialized )
return;
672 data = manager.getSharedObjectData<Data>(name);
675 case serializer::MAP:
676 if ( initialized ) SST_SER_NAME(data->array,
"data");
677 ser.mapper().map_hierarchy_end();
685 bool published =
false;
686 Data* data =
nullptr;
687 bool initialized =
false;
696 std::vector<bool> array;
697 std::vector<bool> written;
698 ChangeSet* change_set;
705 verify(VERIFY_UNINITIALIZED)
707 explicit Data(
const std::string& name) :
710 verify(VERIFY_UNINITIALIZED)
712 if ( Private::getNumRanks().rank > 1 ) {
713 change_set =
new ChangeSet(name);
719 if ( change_set )
delete change_set;
733 if ( v_type == VERIFY_UNINITIALIZED )
return;
734 std::lock_guard<std::mutex>
lock(mtx);
735 if (
size > array.size() ) {
737 array.resize(
size, init_data);
738 if ( v_type == FE_VERIFY ) {
739 written.resize(
size);
741 if ( change_set ) change_set->setSize(
size, init_data, v_type);
746 if ( verify != VERIFY_UNINITIALIZED ) {
747 if ( init != init_data ) {
748 Private::getSimulationOutput().fatal(CALL_INFO, 1,
749 "ERROR: Two different init_data values passed into SharedArray %s\n", name.c_str());
752 if ( verify != v_type ) {
753 Private::getSimulationOutput().fatal(
754 CALL_INFO, 1,
"ERROR: Two different verify types passed into SharedArray %s\n", name.c_str());
763 std::lock_guard<std::mutex>
lock(mtx);
767 void update_write(
int index,
bool data)
775 check = written[index];
778 check = array[index] != init;
783 if ( check && (array[index] != data) ) {
784 Private::getSimulationOutput().fatal(CALL_INFO, 1,
785 "ERROR: wrote two different values to index %d of SharedArray %s\n", index, name.c_str());
788 if ( verify == FE_VERIFY ) written[index] =
true;
791 void write(
int index,
bool data)
793 std::lock_guard<std::mutex>
lock(mtx);
794 check_lock_for_write(
"SharedArray");
795 update_write(index, data);
796 if ( verify == FE_VERIFY ) written[index] =
true;
797 if ( change_set ) change_set->addChange(index, data);
805 inline bool read(
int index)
const {
return array[index]; }
808 inline bool mutex_read(
int index)
const
810 std::lock_guard<std::mutex>
lock(mtx);
818 void serialize_order(
serializer& ser)
override
820 SharedObjectData::serialize_order(ser);
831 std::vector<std::pair<int, bool>> changes;
836 void serialize_order(
serializer& ser)
override
838 SharedObjectChangeSet::serialize_order(ser);
845 ImplementSerializable(SharedArray<bool>::Data::ChangeSet);
850 SharedObjectChangeSet()
852 explicit ChangeSet(
const std::string& name) :
853 SharedObjectChangeSet(name),
855 verify(VERIFY_UNINITIALIZED)
858 void addChange(
int index,
bool value) { changes.emplace_back(index, value); }
860 void setSize(
size_t length,
bool init_data,
verify_type v_type)
866 size_t getSize() {
return size; }
868 void applyChanges(SharedObjectDataManager* manager)
override
870 auto data = manager->getSharedObjectData<Data>(
getName());
871 data->setSize(size, init, verify);
872 for (
auto x : changes ) {
873 data->update_write(x.first, x.second);
877 void clear()
override { changes.clear(); }
Class used to map containers.
Definition objectMap.h:1420
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:43
Definition sharedArray.h:263
virtual SharedObjectChangeSet * getChangeSet() override
Gets the changeset for this data on this rank.
Definition sharedArray.h:388
virtual void resetChangeSet() override
Resets the changeset for this data on this rank.
Definition sharedArray.h:389
void setSize(size_t size, const T &init_data, verify_type v_type)
Set the size of the array.
Definition sharedArray.h:303
Definition sharedArray.h:690
void setSize(size_t size, bool init_data, verify_type v_type)
Set the size of the array.
Definition sharedArray.h:730
virtual void resetChangeSet() override
Resets the changeset for this data on this rank.
Definition sharedArray.h:816
virtual SharedObjectChangeSet * getChangeSet() override
Gets the changeset for this data on this rank.
Definition sharedArray.h:815
SharedArray()
Default constructor for SharedArray.
Definition sharedArray.h:468
size_t size() const
Get the length of the array.
Definition sharedArray.h:548
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:515
const_iterator begin() const
Get const_iterator to beginning of underlying map.
Definition sharedArray.h:560
bool empty() const
Tests if array is empty.
Definition sharedArray.h:555
bool isFullyPublished()
Check whether all instances of this SharedArray have called publish().
Definition sharedArray.h:596
void write(int index, bool value)
Write data to the array.
Definition sharedArray.h:606
bool mutex_read(int index) const
Read data from the array.
Definition sharedArray.h:643
const_reverse_iterator rend() const
Get const_reverse_iterator to end of underlying map.
Definition sharedArray.h:575
~SharedArray()
Shared Array Destructor.
Definition sharedArray.h:477
void publish()
Indicate that the calling element has written all the data it plans to write.
Definition sharedArray.h:582
bool operator[](int index) const
Read data from the array.
Definition sharedArray.h:632
const_iterator end() const
Get const_iterator to end of underlying map.
Definition sharedArray.h:565
const_reverse_iterator rbegin() const
Get const_reverse_iterator to beginning of underlying map.
Definition sharedArray.h:570
size_t size() const
Get the length of the array.
Definition sharedArray.h:121
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:91
const T & mutex_read(int index) const
Read data from the array.
Definition sharedArray.h:216
const_iterator begin() const
Get const_iterator to beginning of underlying map.
Definition sharedArray.h:133
const_iterator end() const
Get const_iterator to end of underlying map.
Definition sharedArray.h:138
bool empty() const
Tests if array is empty.
Definition sharedArray.h:128
SharedArray()
Default constructor for SharedArray.
Definition sharedArray.h:44
~SharedArray()
Shared Array Destructor.
Definition sharedArray.h:53
const_reverse_iterator rend() const
Get const_reverse_iterator to end of underlying map.
Definition sharedArray.h:148
const T & operator[](int index) const
Read data from the array.
Definition sharedArray.h:205
void publish()
Indicate that the calling element has written all the data it plans to write.
Definition sharedArray.h:155
void write(int index, const T &value)
Write data to the array.
Definition sharedArray.h:179
bool isFullyPublished()
Check whether all instances of this SharedArray have called publish().
Definition sharedArray.h:169
const_reverse_iterator rbegin() const
Get const_reverse_iterator to beginning of underlying map.
Definition sharedArray.h:143
This is the base class for holding data on changes made to the shared data on each rank.
Definition sharedObject.h:52
const std::string & getName()
Get the name of the shared data the changeset should be applied to.
Definition sharedObject.h:81
virtual void clear()=0
Clears the data.
const std::string & getName()
Get the name of the SharedObject for this data.
Definition sharedObject.h:108
SharedObjectData(const std::string &name)
Constructor for SharedObjectData.
Definition sharedObject.h:202
void lock()
Called by the core when writing to shared regions is no longer allowed.
Definition sharedObject.h:195
verify_type
Enum of verify types.
Definition sharedObject.h:286