Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
BaseDirectMatrixBuilder.cc
1
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7
8
9#include "BaseDirectMatrixBuilder.h"
10
11#include <iomanip>
12#include <limits>
13#include <set>
14
15#include <alien/utils/Precomp.h>
16
17#include <algorithm>
19#include <alien/kernels/simple_csr/CSRStructInfo.h>
20#include <alien/kernels/simple_csr/SimpleCSRMatrix.h>
21#include <sstream>
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Alien
27{
28
29using namespace Arccore;
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34#ifdef USE_VMAP
35#undef KEY_OF
36#undef VALUE_OF
37#define KEY_OF(i) (i).key()
38#define VALUE_OF(i) (i).value()
39#else /* USE_VMAP */
40#undef KEY_OF
41#undef VALUE_OF
42#define KEY_OF(i) (i)->first
43#define VALUE_OF(i) (i)->second
44#endif /* USE_VMAP */
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49namespace Common
50{
51
52 /*---------------------------------------------------------------------------*/
53 /*---------------------------------------------------------------------------*/
54
55 DirectMatrixBuilder::DirectMatrixBuilder(IMatrix& matrix,
56 const DirectMatrixOptions::ResetFlag reset_flag,
57 const DirectMatrixOptions::SymmetricFlag symmetric_flag)
58 : m_matrix(matrix)
59 , m_matrix_impl(nullptr)
60 , m_row_starts()
61 , m_cols()
62 , m_values()
63 , m_row_sizes()
64 , m_reset_flag(reset_flag)
65 , m_allocated(false)
66 , m_finalized(false)
67 , m_symmetric_profile(symmetric_flag == DirectMatrixOptions::eSymmetric)
68 , m_nproc(0)
69 , m_parallel_mng(nullptr)
70 , m_trace(nullptr)
71 {
72 m_matrix.impl()->lock();
73 m_matrix_impl = &m_matrix.impl()->get<BackEnd::tag::simplecsr>(true);
74
75 const MatrixDistribution& dist = m_matrix_impl->distribution();
76
77 m_parallel_mng = dist.parallelMng();
78
79 if (!m_parallel_mng) {
80 m_nproc = 1;
81 }
82 else {
83 m_nproc = m_parallel_mng->commSize();
84 }
85
86 m_local_size = dist.localRowSize();
87 m_global_size = dist.globalRowSize();
88 m_local_offset = dist.rowOffset();
89
90 m_col_global_size = m_matrix_impl->colSpace().size();
91
92 const bool never_allocated = (m_matrix_impl->getCSRProfile().getNRow() == 0);
93 if (m_reset_flag == DirectMatrixOptions::eResetAllocation or never_allocated) {
94 m_reset_flag = DirectMatrixOptions::eResetAllocation;
95 m_row_sizes.resize(m_local_size, 0);
96 }
97 else {
98 m_row_sizes.resize(m_local_size);
99 SimpleCSRInternal::CSRStructInfo& profile =
100 m_matrix_impl->internal()->getCSRProfile();
101 ConstArrayView<Integer> row_starts = profile.getRowOffset();
102 for (Integer i = 0; i < m_local_size; ++i) {
103 const Integer row_capacity = row_starts[i + 1] - row_starts[i];
104 m_row_sizes[i] = row_capacity;
105 }
106 }
107 }
108
109 /*---------------------------------------------------------------------------*/
110
111 DirectMatrixBuilder::~DirectMatrixBuilder()
112 {
113 if (!m_finalized) {
114 finalize();
115 }
116 }
117
118 /*---------------------------------------------------------------------------*/
119
120 void DirectMatrixBuilder::reserve(
121 Integer n, const DirectMatrixOptions::ReserveFlag flag)
122 {
123 ALIEN_ASSERT((!m_allocated), ("Cannot reserve already allocated matrix"));
124 m_reset_flag = DirectMatrixOptions::eResetAllocation;
125
126 if (flag == DirectMatrixOptions::eResetReservation) {
127 m_row_sizes.fill(n);
128 }
129 else {
130 ALIEN_ASSERT((flag == DirectMatrixOptions::eExtendReservation),
131 ("Unexpected reservation flag"));
132 for (Integer i = 0, is = m_row_sizes.size(); i < is; ++i)
133 m_row_sizes[i] += n;
134 }
135 }
136
137 /*---------------------------------------------------------------------------*/
138
139 void DirectMatrixBuilder::reserve(
140 const ConstArrayView<Integer> indices, Integer n, const ReserveFlag flag)
141 {
142 ALIEN_ASSERT((!m_allocated), ("Cannot reserve already allocated matrix"));
143 m_reset_flag = DirectMatrixOptions::eResetAllocation;
144
145 if (flag == DirectMatrixOptions::eResetReservation) {
146 for (Integer i = 0; i < indices.size(); ++i)
147 m_row_sizes[indices[i] - m_local_offset] = n;
148 }
149 else {
150 ALIEN_ASSERT((flag == DirectMatrixOptions::eExtendReservation),
151 ("Unexpected reservation flag"));
152 for (Integer i = 0; i < indices.size(); ++i)
153 m_row_sizes[indices[i] - m_local_offset] += n;
154 }
155 }
156
157 /*---------------------------------------------------------------------------*/
158
159 void DirectMatrixBuilder::allocate()
160 {
161 _startTimer();
162 ALIEN_ASSERT((!m_allocated), ("Cannot allocate already allocated matrix"));
163
164 if (m_reset_flag == DirectMatrixOptions::eResetAllocation) {
165 computeProfile(m_row_sizes);
166 }
167 SimpleCSRInternal::CSRStructInfo& profile = m_matrix_impl->internal()->getCSRProfile();
168
169 profile.setSymmetric(m_symmetric_profile);
170
171 m_row_starts = profile.getRowOffset();
172 m_cols = profile.getCols();
173 m_values = m_matrix_impl->internal()->getValues();
174
175 if (m_reset_flag == DirectMatrixOptions::eResetAllocation or m_reset_flag == DirectMatrixOptions::eResetProfile or profile.getColOrdering() != SimpleCSRInternal::CSRStructInfo::eFull) {
176 profile.getColOrdering() = SimpleCSRInternal::CSRStructInfo::eUndef;
177 m_row_sizes.fill(0);
178 }
179 else {
180 if (m_matrix_impl->isParallel()) {
181 // NEED TO SORT COLS BECAUSE OF DichotomyScan
182 if (m_reset_flag == DirectMatrixOptions::eResetValues) {
183 for (Integer i = 0; i < m_local_size; ++i) {
184 const Integer row_capacity = m_row_starts[i + 1] - m_row_starts[i];
185 m_row_sizes[i] = row_capacity;
186 auto view = ArrayView<Integer>(row_capacity, m_cols.data() + m_row_starts[i]);
187 std::sort(view.begin(), view.end());
188 }
189 }
190 else {
191 std::set<std::pair<Integer, Real>> entries;
192 for (Integer i = 0; i < m_local_size; ++i) {
193 const Integer row_capacity = m_row_starts[i + 1] - m_row_starts[i];
194 m_row_sizes[i] = row_capacity;
195 entries.clear();
196 for (Integer k = m_row_starts[i]; k < m_row_starts[i + 1]; ++k) {
197 entries.insert(std::make_pair(m_cols[k], m_values[k]));
198 }
199 Integer k = 0;
200 for (auto e = entries.begin(); e != entries.end(); ++e, ++k) {
201 m_cols[k] = e->first;
202 m_values[k] = e->second;
203 }
204 }
205 }
206 }
207 else {
208 for (Integer i = 0; i < m_local_size; ++i) {
209 const Integer row_capacity = m_row_starts[i + 1] - m_row_starts[i];
210 m_row_sizes[i] = row_capacity;
211 }
212 }
213 }
214
215 if (m_reset_flag != DirectMatrixOptions::eNoReset)
216 m_values.fill(0.);
217
218 m_allocated = true;
219 _stopTimer();
220 }
221
222 /*---------------------------------------------------------------------------*/
223
224 void DirectMatrixBuilder::addData(
225 const Integer iIndex, const Integer jIndex, const Real value)
226 {
227 _startTimer();
228 ALIEN_ASSERT((m_allocated), ("Not allocated matrix"));
229
230 // skip dead zone
231 if (iIndex == -1 or jIndex == -1)
232 return;
233 const Integer local_row = iIndex - m_local_offset;
234#ifdef CHECKPROFILE_ON_FILLING
235 if (local_row < 0 or local_row >= m_local_size)
236 throw FatalErrorException("Cannot add data on undefined row");
237#endif /* CHECKPROFILE_ON_FILLING */
238 if (jIndex < -1 or jIndex >= m_col_global_size)
239 throw FatalErrorException("column index undefined");
240 const Integer row_start = m_row_starts[local_row];
241 Integer& row_size = m_row_sizes[local_row];
242 Integer row_capacity = m_row_starts[local_row + 1] - row_start;
243 Integer hint_pos; // hint insertion position not used
244 Real* found_value = intrusive_vmap_insert(jIndex, hint_pos, row_size, row_capacity,
245 m_cols.unguardedBasePointer() + row_start,
246 m_values.unguardedBasePointer() + row_start);
247 if (found_value)
248 *found_value += value;
249 else // Manage extra data storage
250 m_extras[local_row][jIndex] += value;
251 _stopTimer();
252 }
253
254 /*---------------------------------------------------------------------------*/
255
256 void DirectMatrixBuilder::addData(const Integer iIndex, const Real factor,
257 ConstArrayView<Integer> jIndexes, ConstArrayView<Real> jValues)
258 {
259 _startTimer();
260 ALIEN_ASSERT((m_allocated), ("Not allocated matrix"));
261 ALIEN_ASSERT((jIndexes.size() == jValues.size()),
262 ("Inconsistent sizes: %d vs %d", jIndexes.size(), jValues.size()));
263
264 if (iIndex == -1)
265 return; // skip dead zone
266 const Integer local_row = iIndex - m_local_offset;
267#ifdef CHECKPROFILE_ON_FILLING
268 if (local_row < 0 or local_row >= m_local_size)
269 throw FatalErrorException("Cannot add data on undefined row");
270#endif /* CHECKPROFILE_ON_FILLING */
271 const Integer row_start = m_row_starts[local_row];
272 Integer& row_size = m_row_sizes[local_row];
273 Integer row_capacity = m_row_starts[local_row + 1] - row_start;
274 ColValueData* local_extras = nullptr;
275
276 for (Integer i = 0, n = jIndexes.size(); i < n; ++i) {
277 const Integer jIndex = jIndexes[i];
278 if (jIndex == -1)
279 continue; // skip dead zone
280 if (jIndex < -1 or jIndex >= m_col_global_size)
281 throw FatalErrorException("column index undefined");
282 Integer hint_pos; // hint insertion position not used
283 Real* found_value = intrusive_vmap_insert(jIndex, hint_pos, row_size, row_capacity,
284 m_cols.unguardedBasePointer() + row_start,
285 m_values.unguardedBasePointer() + row_start);
286 if (found_value)
287 *found_value += factor * jValues[i];
288 else // Manage extra data storage
289 {
290 if (local_extras == nullptr)
291 local_extras = &m_extras[local_row];
292 (*local_extras)[jIndex] += factor * jValues[i];
293 }
294 }
295 _stopTimer();
296 }
297
298 /*---------------------------------------------------------------------------*/
299
300 void DirectMatrixBuilder::setData(
301 const Integer iIndex, const Integer jIndex, const Real value)
302 {
303 _startTimer();
304 ALIEN_ASSERT((m_allocated), ("Not allocated matrix"));
305
306 // skip dead zone
307 if (iIndex == -1 or jIndex == -1)
308 return;
309 const Integer local_row = iIndex - m_local_offset;
310#ifdef CHECKPROFILE_ON_FILLING
311 if (local_row < 0 or local_row >= m_local_size)
312 throw FatalErrorException("Cannot add data on undefined row");
313#endif /* CHECKPROFILE_ON_FILLING */
314 if (jIndex < -1 or jIndex >= m_col_global_size)
315 throw FatalErrorException("column index undefined");
316 const Integer row_start = m_row_starts[local_row];
317 Integer& row_size = m_row_sizes[local_row];
318 Integer row_capacity = m_row_starts[local_row + 1] - row_start;
319 Integer hint_pos; // hint insertion position not used
320 Real* found_value = intrusive_vmap_insert(jIndex, hint_pos, row_size, row_capacity,
321 m_cols.unguardedBasePointer() + row_start,
322 m_values.unguardedBasePointer() + row_start);
323 if (found_value)
324 *found_value = value;
325 else // Manage extra data storage
326 m_extras[local_row][jIndex] = value;
327 _stopTimer();
328 }
329
330 /*---------------------------------------------------------------------------*/
331
332 void DirectMatrixBuilder::setData(const Integer iIndex, const Real factor,
333 ConstArrayView<Integer> jIndexes, ConstArrayView<Real> jValues)
334 {
335 _startTimer();
336 ALIEN_ASSERT((m_allocated), ("Not allocated matrix"));
337 ALIEN_ASSERT((jIndexes.size() == jValues.size()),
338 ("Inconsistent sizes: %d vs %d", jIndexes.size(), jValues.size()));
339
340 if (iIndex == -1)
341 return; // skip dead zone
342 const Integer local_row = iIndex - m_local_offset;
343#ifdef CHECKPROFILE_ON_FILLING
344 if (local_row < 0 or local_row >= m_local_size)
345 throw FatalErrorException("Cannot add data on undefined row");
346#endif /* CHECKPROFILE_ON_FILLING */
347 const Integer row_start = m_row_starts[local_row];
348 Integer& row_size = m_row_sizes[local_row];
349 Integer row_capacity = m_row_starts[local_row + 1] - row_start;
350 ColValueData* local_extras = nullptr;
351
352 for (Integer i = 0, n = jIndexes.size(); i < n; ++i) {
353 const Integer jIndex = jIndexes[i];
354 if (jIndex == -1)
355 continue; // skip dead zone
356 if (jIndex < -1 or jIndex >= m_col_global_size)
357 throw FatalErrorException("column index undefined");
358 Integer hint_pos; // hint insertion position not used
359 Real* found_value = intrusive_vmap_insert(jIndex, hint_pos, row_size, row_capacity,
360 m_cols.unguardedBasePointer() + row_start,
361 m_values.unguardedBasePointer() + row_start);
362 if (found_value)
363 *found_value = factor * jValues[i];
364 else // Manage extra data storage
365 {
366 if (local_extras == nullptr)
367 local_extras = &m_extras[local_row];
368 (*local_extras)[jIndex] = factor * jValues[i];
369 }
370 }
371 _stopTimer();
372 }
373
374 /*---------------------------------------------------------------------------*/
375
376 void DirectMatrixBuilder::finalize()
377 {
378 if (m_finalized)
379 return;
380 squeeze();
381 m_matrix.impl()->unlock();
382 m_finalized = true;
383 }
384
385 /*---------------------------------------------------------------------------*/
386
388 {
389 public:
390 class Finder
391 {
392 public:
393 Finder(ConstArrayView<Integer> indexes, const Integer offset)
394 {
395 for (Integer i = 0, is = indexes.size(); i < is; ++i)
396 m_index_set.insert(indexes[i] - offset);
397 }
398 bool operator()(const Integer index) const
399 {
400 return m_index_set.find(index) != m_index_set.end();
401 }
402
403 private:
404 std::set<Integer> m_index_set;
405 };
406
407 public:
408 IndexEnumerator(ConstArrayView<Integer> indexes, const Integer offset)
409 : m_i(0)
410 , m_offset(offset)
411 , m_indexes(indexes)
412 {}
413 [[nodiscard]] bool end() const { return m_i >= m_indexes.size(); }
414 void operator++() { ++m_i; }
415 Integer operator*() const { return m_indexes[m_i] - m_offset; }
416 [[nodiscard]] Integer size() const { return m_indexes.size(); }
417 [[nodiscard]] Finder finder() const { return Finder(m_indexes, m_offset); }
418
419 private:
420 Integer m_i;
421 const Integer m_offset;
422 const ConstArrayView<Integer> m_indexes;
423 std::set<Integer> m_index_set;
424 };
425
426 /*---------------------------------------------------------------------------*/
427
429 {
430 public:
431 class Finder
432 {
433 public:
434 explicit Finder(const Integer size)
435 : m_size(size)
436 {}
437 bool operator()(const Integer index) const { return index >= 0 and index < m_size; }
438
439 private:
440 const Integer m_size;
441 };
442
443 public:
444 explicit FullEnumerator(const Integer size)
445 : m_i(0)
446 , m_size(size)
447 {}
448 [[nodiscard]] bool end() const { return m_i >= m_size; }
449 void operator++() { ++m_i; }
450 Integer operator*() const { return m_i; }
451 [[nodiscard]] Integer size() const { return m_size; }
452 [[nodiscard]] Finder finder() const { return Finder(m_size); }
453
454 private:
455 Integer m_i;
456 const Integer m_size;
457 };
458
459 /*---------------------------------------------------------------------------*/
460
461 String DirectMatrixBuilder::stats() const
462 {
463 std::ostringstream oss;
464 _stats(oss, FullEnumerator(m_local_size));
465 return String(oss.str());
466 }
467
468 /*---------------------------------------------------------------------------*/
469
470 String DirectMatrixBuilder::stats(ConstArrayView<Integer> ids) const
471 {
472 std::ostringstream oss;
473 _stats(oss, IndexEnumerator(ids, m_local_offset));
474 return String(oss.str());
475 }
476
477 /*---------------------------------------------------------------------------*/
478
479 void DirectMatrixBuilder::squeeze()
480 {
481 bool need_squeeze = false;
482
483 Integer total_size = 0, total_capacity = 0;
484 for (Integer i = 0; i < m_local_size; ++i) {
485 const Integer row_size = m_row_sizes[i];
486 const Integer row_capacity = m_row_starts[i + 1] - m_row_starts[i];
487 total_size += row_size;
488 total_capacity += row_capacity;
489 need_squeeze |= (row_size != row_capacity);
490 }
491 need_squeeze |= (!m_extras.empty());
492 for (auto i = m_extras.begin(); i != m_extras.end(); ++i)
493 total_size += i->second.size();
494
495 // Parallel reduction of the decision
496 if (m_parallel_mng)
497 need_squeeze = Arccore::MessagePassing::mpAllReduce(
498 m_parallel_mng, Arccore::MessagePassing::ReduceMax, need_squeeze);
499
500 // Premature return if no need of squeeze
501 if (!need_squeeze)
502 return;
503
504 UniqueArray<Integer> row_starts(m_local_size + 1);
505 UniqueArray<Integer> cols(total_size);
506 UniqueArray<Real> values(total_size);
507
508 Integer offset = 0;
509 for (Integer i = 0; i < m_local_size; ++i) {
510 auto ifinder = m_extras.find(i);
511 if (ifinder == m_extras.end()) { // Algo sans fusion avec les extras
512 const Integer row_start_orig = m_row_starts[i];
513 const Integer row_start = row_starts[i] = offset;
514 const Integer row_size = m_row_sizes[i];
515 for (Integer j = 0; j < row_size; ++j) {
516 cols[row_start + j] = m_cols[row_start_orig + j];
517 values[row_start + j] = m_values[row_start_orig + j];
518 }
519 offset += row_size;
520 }
521 else { // Algo avec fusion des extras
522 const ColValueData& extra_col_value_data = ifinder->second;
523 const Integer row_start_orig = m_row_starts[i];
524 const Integer row_start = row_starts[i] = offset;
525 const Integer row_size = m_row_sizes[i];
526
527 Integer pos = row_start, j = 0;
528 ColValueData::const_iterator extra_j_iter = extra_col_value_data.begin();
529
530 while (true) {
531 if (j == row_size) { // Copie la partie restante des extras
532 while (extra_j_iter != extra_col_value_data.end()) {
533 cols[pos] = KEY_OF(extra_j_iter);
534 values[pos] = VALUE_OF(extra_j_iter);
535 ++pos;
536 ++extra_j_iter;
537 }
538 break;
539 }
540 if (extra_j_iter == extra_col_value_data.end()) { // Copie la partie restante des originaux
541 while (j < row_size) {
542 cols[pos] = m_cols[row_start_orig + j];
543 values[pos] = m_values[row_start_orig + j];
544 ++pos;
545 ++j;
546 }
547 break;
548 }
549
550 // Copie en fusionnant les deux listes
551 if (m_cols[row_start_orig + j] < KEY_OF(extra_j_iter)) {
552 cols[pos] = m_cols[row_start_orig + j];
553 values[pos] = m_values[row_start_orig + j];
554 ++pos;
555 ++j;
556 }
557 else {
558 cols[pos] = KEY_OF(extra_j_iter);
559 values[pos] = VALUE_OF(extra_j_iter);
560 ++pos;
561 ++extra_j_iter;
562 }
563 }
564 offset += row_size + extra_col_value_data.size();
565 }
566 }
567 row_starts[m_local_size] = offset;
568 ALIEN_ASSERT((offset == total_size), ("Inconsistent total size"));
569
570 updateProfile(row_starts, cols, values);
571 }
572
573 /*---------------------------------------------------------------------------*/
574
575 void DirectMatrixBuilder::computeProfile(const ConstArrayView<Integer> sizes)
576 {
577 UniqueArray<Integer> m_offset;
578 m_offset.resize(m_nproc + 1);
579 if (m_parallel_mng) {
580 Arccore::MessagePassing::mpAllGather(m_parallel_mng,
581 ConstArrayView<Integer>(1, &m_local_offset), m_offset.subView(0, m_nproc));
582 }
583 m_offset[m_nproc] = m_global_size;
584
585 SimpleCSRInternal::CSRStructInfo& profile = m_matrix_impl->internal()->getCSRProfile();
586 profile.init(m_local_size);
587
588 m_row_starts = profile.getRowOffset();
589
590 Integer offset = 0;
591 for (Integer i = 0; i < m_local_size; ++i) {
592 m_row_starts[i] = offset;
593 offset += sizes[i];
594 }
595 m_row_starts[m_local_size] = offset;
596
597 profile.allocate();
598 profile.setTimestamp(m_matrix_impl->timestamp() + 1);
599
600 m_cols = profile.getCols();
601 profile.getColOrdering() = SimpleCSRInternal::CSRStructInfo::eUndef;
602
603 m_matrix_impl->allocate();
604 m_values = m_matrix_impl->internal()->getValues();
605
606#ifndef NDEBUG
607 m_values.fill(0.);
608 m_cols.fill(-1);
609#endif /* NDEBUG */
610 }
611
612 /*---------------------------------------------------------------------------*/
613
614 void DirectMatrixBuilder::updateProfile(UniqueArray<Integer>& row_starts,
615 UniqueArray<Integer>& cols, UniqueArray<Real>& values)
616 {
617 SimpleCSRInternal::CSRStructInfo& profile = m_matrix_impl->internal()->getCSRProfile();
618 profile.getRowOffset().copy(row_starts);
619 m_row_starts = profile.getRowOffset();
620 profile.getCols() = cols;
621 m_cols = profile.getCols();
622 profile.getColOrdering() = SimpleCSRInternal::CSRStructInfo::eFull;
623
624 UniqueArray<Integer> offset;
625 offset.resize(m_nproc + 1);
626 if (m_parallel_mng) {
627 Arccore::MessagePassing::mpAllGather(m_parallel_mng,
628 ConstArrayView<Integer>(1, &m_local_offset), offset.subView(0, m_nproc));
629 }
630 offset[m_nproc] = m_global_size;
631
632 m_matrix_impl->allocate();
633 m_matrix_impl->internal()->getValues() = values; // copy values dans Matrix.getValues()
634
635 if (m_nproc > 1) {
636 m_matrix_impl->parallelStart(offset, m_parallel_mng, true);
637 }
638 else
639 m_matrix_impl->sequentialStart();
640 m_values = m_matrix_impl->internal()->getValues();
641 }
642
643 /*---------------------------------------------------------------------------*/
644
645 template <typename Enumerator>
646 void DirectMatrixBuilder::_stats(std::ostream& o, const Enumerator& e) const
647 {
648 bool need_squeeze = false;
649 Integer total_used_data = 0;
650 Integer min_used_data = (m_local_size > 0) ? std::numeric_limits<Integer>::max() : 0,
651 max_used_data = 0;
652 Integer total_reserved_data = 0;
653 Integer min_reserved_data =
654 (m_local_size > 0) ? std::numeric_limits<Integer>::max() : 0,
655 max_reserved_data = 0;
656 for (Enumerator ie = e; !ie.end(); ++ie) {
657 const Integer i = *ie;
658 const Integer data_capacity = m_row_starts[i + 1] - m_row_starts[i];
659 max_reserved_data = std::max(max_reserved_data, data_capacity);
660 min_reserved_data = std::min(min_reserved_data, data_capacity);
661 total_reserved_data += data_capacity;
662 const Integer data_size = m_row_sizes[i];
663 min_used_data = std::min(min_used_data, data_size);
664 max_used_data = std::max(max_used_data, data_size);
665 total_used_data += data_size;
666 need_squeeze |= (data_capacity != data_size);
667 }
668 min_used_data = std::min(min_used_data, max_used_data);
669 min_reserved_data = std::min(min_reserved_data, max_reserved_data);
670
671 Integer total_extra_data = 0;
672 Integer min_extra_data =
673 (!m_extras.empty()) ? std::numeric_limits<Integer>::max() : 0,
674 max_extra_data = 0;
675 Integer extra_count = 0;
676 typename Enumerator::Finder finder = e.finder();
677 for (ExtraRows::const_iterator j = m_extras.begin(); j != m_extras.end(); ++j) {
678 if (finder(j->first)) {
679 ++extra_count;
680 const Integer data_size = j->second.size();
681 min_extra_data = std::min(min_extra_data, data_size);
682 max_extra_data = std::max(max_extra_data, data_size);
683 total_extra_data += data_size;
684 }
685 }
686 min_extra_data = std::min(min_extra_data, max_extra_data);
687 need_squeeze |= (extra_count > 0);
688 // Parallel reduction of the decision : uniquement pour affichage
689 need_squeeze = Arccore::MessagePassing::mpAllReduce(
690 m_parallel_mng, Arccore::MessagePassing::ReduceMax, need_squeeze);
691
692 const Integer size = e.size();
693 o << "Total used data = " << total_used_data << " on " << size
694 << " rows\n"
695 << "Min / Mean / Max used data = " << min_used_data << std::setprecision(2)
696 << " / " << ((size) ? (double(total_used_data) / size) : 0) << " / "
697 << max_used_data << "\n"
698 << "Total extra data = " << total_extra_data << " on " << extra_count
699 << " rows\n"
700 << "Min / Mean / Max extra data = " << min_extra_data << std::setprecision(2)
701 << " / " << ((extra_count) ? (double(total_extra_data) / extra_count) : 0) << " / "
702 << max_extra_data << "\n"
703 << "Total reserved data = " << total_reserved_data
704 << std::setprecision(3) << " ("
705 << ((total_used_data) ? (100 * double(total_reserved_data) / total_used_data) : 0)
706 << "% of used data)\n"
707 << "Min / Mean / Max reserved data = " << min_reserved_data << std::setprecision(2)
708 << " / " << ((size) ? (double(total_reserved_data) / size) : 0) << " / "
709 << max_reserved_data << "\n"
710 << "Need squeeze optimization = " << std::boolalpha << need_squeeze << "\n";
711 }
712
713 /*---------------------------------------------------------------------------*/
714 /*---------------------------------------------------------------------------*/
715
716} // namespace Common
717
718/*---------------------------------------------------------------------------*/
719/*---------------------------------------------------------------------------*/
720
721} // namespace Alien
722
723/*---------------------------------------------------------------------------*/
724/*---------------------------------------------------------------------------*/
MultiMatrixImpl.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17