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