@@ -131,25 +131,30 @@ class BspArchitecture {
131131 std::vector<unsigned > processorTypes_;
132132
133133 /* *
134- * @brief A p x p matrix of send costs. Diagonal entries should be zero.
134+ * @brief A flattened p x p matrix of send costs.
135+ * Access via index [i * numberOfProcessors_ + j].
135136 */
136- std::vector<std::vector< v_commw_t <Graph_t> >> sendCosts_;
137+ std::vector<v_commw_t <Graph_t>> sendCosts_;
137138
138139 /* *
139140 * @brief The memory constraint type.
140141 */
141142 MEMORY_CONSTRAINT_TYPE memoryConstraintType_ = MEMORY_CONSTRAINT_TYPE::NONE;
142143
144+ std::size_t FlatIndex (const unsigned row, const unsigned col) const {
145+ return static_cast <std::size_t >(row) * numberOfProcessors_ + col;
146+ }
147+
143148 bool AreSendCostsNuma () {
144149 if (numberOfProcessors_ == 1U )
145150 return false ;
146151
147- const v_commw_t <Graph_t> val = sendCosts_.at (0U ). at ( 1U );
152+ const v_commw_t <Graph_t> val = sendCosts_.at (1U );
148153 for (unsigned p1 = 0U ; p1 < numberOfProcessors_; p1++) {
149154 for (unsigned p2 = 0U ; p2 < numberOfProcessors_; p2++) {
150155 if (p1 == p2)
151156 continue ;
152- if (sendCosts_.at (p1). at (p2 ) != val)
157+ if (sendCosts_.at (FlatIndex (p1, p2) ) != val)
153158 return true ;
154159 }
155160 }
@@ -167,12 +172,12 @@ class BspArchitecture {
167172
168173 void SetSendCostDiagonalToZero () {
169174 for (unsigned i = 0U ; i < numberOfProcessors_; i++) {
170- sendCosts_.at (i). at (i ) = 0U ;
175+ sendCosts_.at (FlatIndex (i, i) ) = 0U ;
171176 }
172177 }
173178
174179 void InitializeUniformSendCosts () {
175- sendCosts_ = std::vector<std::vector< v_commw_t <Graph_t>>> (numberOfProcessors_, std::vector< v_commw_t <Graph_t>>( numberOfProcessors_, 1U ) );
180+ sendCosts_. resize (numberOfProcessors_ * numberOfProcessors_, 1U );
176181 SetSendCostDiagonalToZero ();
177182 isNuma_ = false ;
178183 }
@@ -187,15 +192,15 @@ class BspArchitecture {
187192 BspArchitecture ()
188193 : numberOfProcessors_(2U ), numberOfProcessorTypes_(1U ), communicationCosts_(1U ), synchronisationCosts_(2U ),
189194 memoryBound_ (std::vector<v_memw_t <Graph_t>>(numberOfProcessors_, 100U )), isNuma_(false ),
190- processorTypes_(std::vector<unsigned >(numberOfProcessors_, 0U )), sendCosts_(std::vector<std::vector< v_commw_t <Graph_t>>>( numberOfProcessors_, std::vector< v_commw_t <Graph_t>>( numberOfProcessors_, 1U )) ) {
195+ processorTypes_(std::vector<unsigned >(numberOfProcessors_, 0U )), sendCosts_(numberOfProcessors_ * numberOfProcessors_, 1U ) {
191196 SetSendCostDiagonalToZero ();
192197 }
193198
194199 BspArchitecture (const BspArchitecture &other) = default;
195- BspArchitecture (BspArchitecture &&other) = default;
200+ BspArchitecture (BspArchitecture &&other) noexcept = default;
196201 BspArchitecture &operator =(const BspArchitecture &other) = default ;
197- BspArchitecture &operator =(BspArchitecture &&other) = default ;
198- ~BspArchitecture () = default ;
202+ BspArchitecture &operator =(BspArchitecture &&other) noexcept = default ;
203+ virtual ~BspArchitecture () = default ;
199204
200205 /* *
201206 * @brief Constructs a BspArchitecture object with the specified number of processors, communication cost, and
@@ -211,9 +216,7 @@ class BspArchitecture {
211216 : numberOfProcessors_(NumberOfProcessors), numberOfProcessorTypes_(1U ), communicationCosts_(CommunicationCost),
212217 synchronisationCosts_(SynchronisationCost),
213218 memoryBound_(std::vector<v_memw_t <Graph_t>>(NumberOfProcessors, MemoryBound)), isNuma_(false ),
214- processorTypes_(std::vector<unsigned >(NumberOfProcessors, 0U )),
215- sendCosts_(std::vector<std::vector<v_commw_t <Graph_t>>>(
216- numberOfProcessors_, std::vector<v_commw_t <Graph_t>>(numberOfProcessors_, 1U ))) {
219+ processorTypes_(std::vector<unsigned >(NumberOfProcessors, 0U )), sendCosts_(numberOfProcessors_ * numberOfProcessors_, 1U ) {
217220 if (NumberOfProcessors == 0U ) {
218221 throw std::runtime_error (" BspArchitecture: Number of processors must be greater than 0." );
219222 }
@@ -231,7 +234,7 @@ class BspArchitecture {
231234 : numberOfProcessors_(other.numberOfProcessors()), numberOfProcessorTypes_(other.getNumberOfProcessorTypes()),
232235 communicationCosts_(other.communicationCosts()), synchronisationCosts_(other.synchronisationCosts()),
233236 memoryBound_(other.memoryBound()), isNuma_(other.isNumaArchitecture()), processorTypes_(other.processorTypes()),
234- sendCosts_(other.sendCosts ()) {
237+ sendCosts_(other.sendCostsVector ()) {
235238
236239 static_assert (std::is_same_v<v_memw_t <Graph_t>, v_memw_t <Graph_t_other>>,
237240 " BspArchitecture: Graph_t and Graph_t_other have the same memory weight type." );
@@ -255,18 +258,23 @@ class BspArchitecture {
255258 const std::vector<std::vector<v_commw_t <Graph_t>>> &SendCosts)
256259 : numberOfProcessors_(NumberOfProcessors), numberOfProcessorTypes_(1U ), communicationCosts_(CommunicationCost),
257260 synchronisationCosts_(SynchronisationCost), memoryBound_(std::vector<v_memw_t <Graph_t>>(NumberOfProcessors, 100U )),
258- processorTypes_(std::vector<unsigned >(NumberOfProcessors, 0U )), sendCosts_(SendCosts) {
261+ processorTypes_(std::vector<unsigned >(NumberOfProcessors, 0U )) {
259262 if (NumberOfProcessors == 0U ) {
260263 throw std::runtime_error (" BspArchitecture: Number of processors must be greater than 0." );
261264 }
262- if (numberOfProcessors_ != sendCosts_ .size ()) {
265+ if (NumberOfProcessors != SendCosts .size ()) {
263266 throw std::invalid_argument (" sendCosts_ needs to be a processors x processors matrix.\n " );
264267 }
265- if (std::any_of (sendCosts_ .begin (), sendCosts_ .end (),
268+ if (std::any_of (SendCosts .begin (), SendCosts .end (),
266269 [NumberOfProcessors](const auto &thing) { return thing.size () != NumberOfProcessors; })) {
267270 throw std::invalid_argument (" sendCosts_ needs to be a processors x processors matrix.\n " );
268271 }
269272
273+ sendCosts_.reserve (NumberOfProcessors * NumberOfProcessors);
274+ for (const auto &row : SendCosts) {
275+ sendCosts_.insert (sendCosts_.end (), row.begin (), row.end ());
276+ }
277+
270278 SetSendCostDiagonalToZero ();
271279 isNuma_ = AreSendCostsNuma ();
272280 }
@@ -285,18 +293,23 @@ class BspArchitecture {
285293 : numberOfProcessors_(NumberOfProcessors), numberOfProcessorTypes_(1U ), communicationCosts_(CommunicationCost),
286294 synchronisationCosts_(SynchronisationCost),
287295 memoryBound_(std::vector<v_memw_t <Graph_t>>(NumberOfProcessors, MemoryBound)),
288- processorTypes_(std::vector<unsigned >(NumberOfProcessors, 0U )), sendCosts_(SendCosts) {
296+ processorTypes_(std::vector<unsigned >(NumberOfProcessors, 0U )) {
289297 if (NumberOfProcessors == 0U ) {
290298 throw std::runtime_error (" BspArchitecture: Number of processors must be greater than 0." );
291299 }
292- if (numberOfProcessors_ != sendCosts_ .size ()) {
300+ if (NumberOfProcessors != SendCosts .size ()) {
293301 throw std::invalid_argument (" sendCosts_ needs to be a processors x processors matrix.\n " );
294302 }
295- if (std::any_of (sendCosts_ .begin (), sendCosts_ .end (),
303+ if (std::any_of (SendCosts .begin (), SendCosts .end (),
296304 [NumberOfProcessors](const auto &thing) { return thing.size () != NumberOfProcessors; })) {
297305 throw std::invalid_argument (" sendCosts_ needs to be a processors x processors matrix.\n " );
298306 }
299307
308+ sendCosts_.reserve (NumberOfProcessors * NumberOfProcessors);
309+ for (const auto &row : SendCosts) {
310+ sendCosts_.insert (sendCosts_.end (), row.begin (), row.end ());
311+ }
312+
300313 SetSendCostDiagonalToZero ();
301314 isNuma_ = AreSendCostsNuma ();
302315 }
@@ -309,9 +322,9 @@ class BspArchitecture {
309322 for (unsigned i = 0U ; i < numberOfProcessors_; i++) {
310323 for (unsigned j = 0U ; j < numberOfProcessors_; j++) {
311324 if (i == j) {
312- sendCosts_.at (i). at (j ) = 0U ;
325+ sendCosts_.at (FlatIndex (i, j) ) = 0U ;
313326 } else {
314- sendCosts_.at (i). at (j ) = 1U ;
327+ sendCosts_.at (FlatIndex (i, j) ) = 1U ;
315328 }
316329 }
317330 }
@@ -339,7 +352,7 @@ class BspArchitecture {
339352 // Corrected loop to avoid underflow issues with unsigned
340353 for (int pos = static_cast <int >(maxPos); pos >= 0 ; --pos) {
341354 if (((1U << pos) & i) != ((1U << pos) & j)) {
342- sendCosts_.at (i). at (j) = sendCosts_.at (j). at (i ) = intpow (base, static_cast <unsigned >(pos));
355+ sendCosts_.at (FlatIndex (i, j)) = sendCosts_.at (FlatIndex (j, i) ) = intpow (base, static_cast <unsigned >(pos));
343356 break ;
344357 }
345358 }
@@ -351,7 +364,7 @@ class BspArchitecture {
351364 * @brief Returns a view of processor indices from 0 to numberOfProcessors_ - 1.
352365 * @return An integral view of processor indices.
353366 */
354- auto processors () const { return integral_range<unsigned >(numberOfProcessors_); }
367+ [[nodiscard]] auto processors () const { return integral_range<unsigned >(numberOfProcessors_); }
355368
356369 /* *
357370 * @brief Sets the send costs for the BspArchitecture.
@@ -375,7 +388,7 @@ class BspArchitecture {
375388 if (vec.at (i).at (j) != 0U )
376389 throw std::invalid_argument (" Invalid Argument: Diagonal elements should be 0." );
377390 } else {
378- sendCosts_.at (i). at (j ) = vec.at (i).at (j);
391+ sendCosts_.at (FlatIndex (i, j) ) = vec.at (i).at (j);
379392
380393 if (numberOfProcessors_ > 1U && vec.at (i).at (j) != vec.at (0U ).at (1U )) {
381394 isNuma_ = true ;
@@ -398,7 +411,7 @@ class BspArchitecture {
398411 throw std::invalid_argument (" Invalid Argument: Processor index out of bounds." );
399412
400413 if (p1 != p2) {
401- sendCosts_.at (p1). at (p2 ) = cost;
414+ sendCosts_.at (FlatIndex (p1, p2) ) = cost;
402415 isNuma_ = AreSendCostsNuma ();
403416 }
404417 }
@@ -587,10 +600,24 @@ class BspArchitecture {
587600 [[nodiscard]] v_commw_t <Graph_t> synchronisationCosts () const { return synchronisationCosts_; }
588601
589602 /* *
590- * @brief Returns a reference to the send costs matrix.
591- * @return A reference to the send costs matrix.
603+ * @brief Returns the send costs matrix.
604+ * @return The send costs matrix.
605+ */
606+ [[nodiscard]] std::vector<std::vector<v_commw_t <Graph_t>>> sendCostMatrix () const {
607+ std::vector<std::vector<v_commw_t <Graph_t>>> matrix (numberOfProcessors_, std::vector<v_commw_t <Graph_t>>(numberOfProcessors_));
608+ for (unsigned i = 0 ; i < numberOfProcessors_; ++i) {
609+ for (unsigned j = 0 ; j < numberOfProcessors_; ++j) {
610+ matrix[i][j] = sendCosts_[FlatIndex (i, j)];
611+ }
612+ }
613+ return matrix;
614+ }
615+
616+ /* *
617+ * @brief Returns the flattened send costs vector.
618+ * @return The send costs vector.
592619 */
593- [[nodiscard]] const std::vector<std::vector< v_commw_t <Graph_t>>> & sendCostMatrix () const { return sendCosts_; }
620+ [[nodiscard]] const std::vector<v_commw_t <Graph_t>> & sendCostsVector () const { return sendCosts_; }
594621
595622 /* *
596623 * @brief Returns the processor types.
@@ -607,7 +634,7 @@ class BspArchitecture {
607634 * @return The communication costs between the two processors.
608635 */
609636 [[nodiscard]] v_commw_t <Graph_t> communicationCosts (const unsigned p1, const unsigned p2) const {
610- return communicationCosts_ * sendCosts_.at (p1). at (p2 );
637+ return communicationCosts_ * sendCosts_.at (FlatIndex (p1, p2) );
611638 }
612639
613640 /* *
@@ -617,13 +644,13 @@ class BspArchitecture {
617644 * @param p2 The index of the second processor.
618645 * @return The send costs between the two processors.
619646 */
620- [[nodiscard]] v_commw_t <Graph_t> sendCosts (const unsigned p1, const unsigned p2) const { return sendCosts_.at (p1). at (p2 ); }
647+ [[nodiscard]] v_commw_t <Graph_t> sendCosts (const unsigned p1, const unsigned p2) const { return sendCosts_.at (FlatIndex (p1, p2) ); }
621648
622649 /* *
623650 * @brief Returns the send costs matrix.
624651 * @return The send costs matrix.
625652 */
626- [[nodiscard]] const std::vector<std::vector<v_commw_t <Graph_t>>> & sendCosts () const { return sendCosts_ ; }
653+ [[nodiscard]] std::vector<std::vector<v_commw_t <Graph_t>>> sendCosts () const { return sendCostMatrix () ; }
627654
628655 /* *
629656 * @brief Returns the type of a specific processor.
0 commit comments