57, m_block_ghost_size(-1)
59, m_block_matrix_size(0)
62, m_col_ordering(eUndef)
75template <
typename ValueT>
81template <
typename ValueT>
82void StreamVBlockMatrixBuilderT<ValueT>::finalize()
84 bool has_error =
false;
85 for (
auto iter = m_inserters.begin(); iter != m_inserters.end(); ++iter) {
86 Filler& filler = **iter;
87 if (!filler.isEnd()) {
89 m_trace->warning() <<
"Inserter #" << filler.getId() <<
" not at final index";
94 throw FatalErrorException(A_FUNCINFO,
"All inserters are not at final index");
96 m_matrix_impl->updateTimestamp();
97 m_matrix.impl()->unlock();
100template <
typename ValueT>
101void StreamVBlockMatrixBuilderT<ValueT>::end()
107template <
typename ValueT>
109StreamVBlockMatrixBuilderT<ValueT>::getNewInserter()
111 Inserter* inserter =
new Inserter(
this, m_inserters.size());
112 m_inserters.add(inserter);
118template <
typename ValueT>
120StreamVBlockMatrixBuilderT<ValueT>::getInserter(Integer
id)
122 if ((
id < 0) || (
id >= (Integer)m_inserters.size()))
123 throw FatalErrorException(A_FUNCINFO,
"Bad Inserter id");
124 return *m_inserters[id];
129template <
typename ValueT>
130void StreamVBlockMatrixBuilderT<ValueT>::allocate()
137template <
typename ValueT>
138void StreamVBlockMatrixBuilderT<ValueT>::_freeInserters()
140 for (
auto iter = m_inserters.begin(); iter != m_inserters.end(); ++iter)
142 m_inserters.resize(0);
147template <
typename ValueT>
148void StreamVBlockMatrixBuilderT<ValueT>::init()
150 if (m_state == eInit)
159 const VBlock* vblock = m_matrix.impl()->vblock();
162 throw FatalErrorException(
163 A_FUNCINFO,
"Space is not variable block size - Can't use block builder");
166 m_parallel_mng = dist.parallelMng();
168 m_matrix.impl()->lock();
169 m_matrix_impl = &m_matrix.impl()->template get<BackEnd::tag::simplecsr>(
true);
170 m_matrix_impl->free();
172 m_local_size = dist.localRowSize();
173 m_global_size = dist.globalRowSize();
174 m_local_offset = dist.rowOffset();
175 m_col_ordering = eUndef;
182template <
typename ValueT>
183void StreamVBlockMatrixBuilderT<ValueT>::start()
185 m_matrix_impl->free();
191template <
typename ValueT>
192void StreamVBlockMatrixBuilderT<ValueT>::fillZero()
194 m_matrix_impl->internal()->getValues().fill(0.);
199template <
typename ValueT>
201StreamVBlockMatrixBuilderT<ValueT>::vblock()
const
203 return m_matrix.impl()->vblock();
208template <
typename ValueT>
209void StreamVBlockMatrixBuilderT<ValueT>::computeProfile()
227 typedef std::map<Integer, Integer> RowCols;
229 UniqueArray<RowCols> row_cols;
230 UniqueArray<RowCols> block_row_cols;
232 if (m_parallel_mng == NULL) {
237 m_myrank = m_parallel_mng->commRank();
238 m_nproc = m_parallel_mng->commSize();
241 const VBlock* block_sizes = this->vblock();
244 m_block_ghost_size = 0;
245 m_offset.resize(m_nproc + 1);
246 Arccore::MessagePassing::mpAllGather(m_parallel_mng,
247 ConstArrayView<Integer>(1, &m_local_offset), m_offset.subView(0, m_nproc));
248 m_offset[m_nproc] = m_global_size;
254 IsLocal(
const ConstArrayView<Integer> offset,
const Integer myrank)
258 bool operator()(Arccore::Integer col)
const
260 return (col >= m_offset[m_myrank]) && (col < m_offset[m_myrank + 1]);
264 const ConstArrayView<Integer> m_offset;
265 const Integer m_myrank;
266 } isLocal(m_offset, m_myrank);
269 profile.init(m_local_size);
271 m_row_size.resize(m_local_size);
272 m_ghost_row_size.resize(m_local_size);
274 m_ghost_row_size.fill(0);
275 row_cols.resize(m_local_size);
276 block_row_cols.resize(m_local_size);
277 for (Integer row = 0; row < m_local_size; ++row) {
278 row_cols[row][m_local_offset + row] = 0;
279 block_row_cols[row][m_local_offset + row] = 0;
283 m_block_row_size.resize(m_local_size);
284 m_block_ghost_row_size.resize(m_local_size);
285 m_block_row_size.fill(0);
286 m_block_ghost_row_size.fill(0);
287 for (Integer row = 0; row < m_local_size; ++row) {
288 const Integer
id = m_local_offset + row;
289 const Integer block_size = block_sizes->size(
id);
290 m_block_row_size[row] += block_size * block_size;
293 UniqueArray<UniqueArray<Integer>> m_block_data_index(m_inserters.size());
297 for (
auto iter = m_inserters.begin(); iter != m_inserters.end(); ++iter) {
298 BaseInserter* ins = *iter;
299 ins->m_data_index.resize(ins->count());
300 m_block_data_index[nb_ins].resize(ins->count());
302 ins->m_block_size_row.add(0);
303 ins->m_block_size_col.add(0);
305 m_trace->info() <<
"Inserter id=" << ins->getId() <<
" count=" << ins->count();
306 for (Integer i = 0; i < ins->count(); ++i) {
307 const Integer row = ins->m_row_index[i] - m_local_offset;
308 const Integer col = ins->m_col_index[i];
309 if (row == m_local_size) {
312 ins->m_data_index[i] = -1;
313 m_block_data_index[nb_ins][i] = -1;
318 std::pair<RowCols::iterator, bool> finder = row_cols[row].insert(col);
319 std::pair<RowCols::iterator, bool> block_finder = block_row_cols[row].insert(col);
321 std::pair<RowCols::iterator, bool> finder =
322 row_cols[row].insert(std::pair<Integer, Integer>(col, 0));
324 RowCols::iterator inner_iter = finder.first;
325 RowCols::iterator block_iter = block_finder.first;
327 const Integer k = m_row_size[row];
328 const Integer gk = m_ghost_row_size[row];
329 const Integer block_k = m_block_row_size[row];
330 const Integer block_gk = m_block_ghost_row_size[row];
332 VALUE_OF(inner_iter) = k - gk;
333 VALUE_OF(block_iter) = block_k - block_gk;
334 ins->m_data_index[i] = k - gk;
335 m_block_data_index[nb_ins][i] = block_k - block_gk;
339 VALUE_OF(inner_iter) = gk;
340 VALUE_OF(block_iter) = block_gk;
341 ins->m_data_index[i] = gk;
342 m_block_data_index[nb_ins][i] = block_gk;
343 ++m_ghost_row_size[row];
344 m_block_ghost_row_size[row] += block_sizes->size(ins->m_row_index[i]) * block_sizes->size(ins->m_col_index[i]);
347 m_block_row_size[row] += block_sizes->size(ins->m_row_index[i]) * block_sizes->size(ins->m_col_index[i]);
350 ins->m_data_index[i] = VALUE_OF(inner_iter);
351 m_block_data_index[nb_ins][i] = VALUE_OF(block_iter);
358 ArrayView<Integer> m_row_offsets =
359 m_matrix_impl->internal()->getCSRProfile().getRowOffset();
360 ArrayView<Integer> m_block_row_offsets =
361 m_matrix_impl->internal()->getCSRProfile().getBlockRowOffset();
363 m_block_matrix_size = 0;
364 for (Integer row = 0; row < m_local_size; ++row) {
365 m_row_offsets[row] = m_matrix_size;
366 m_matrix_size += m_row_size[row];
367 m_block_row_offsets[row] = m_block_matrix_size;
368 m_block_matrix_size += m_block_row_size[row];
370 m_row_offsets[m_local_size] = m_matrix_size;
371 m_block_row_offsets[m_local_size] = m_block_matrix_size;
374 ArrayView<Integer> m_cols = profile.getCols();
378 for (Integer row = 0; row < m_local_size; ++row) {
379 const Integer ghost_offset = m_row_size[row] - m_ghost_row_size[row];
380 for (RowCols::iterator iter = row_cols[row].begin(); iter != row_cols[row].end();
382 const Integer col_uid = KEY_OF(iter);
384 if (!isLocal(col_uid))
385 iter.value() += ghost_offset;
386 m_cols[offset + VALUE_OF(iter)] = col_uid;
389 offset += m_row_size[row];
394 ArrayView<Integer> m_block_cols = profile.getBlockCols();
396 Integer previous_block_size = 0, index = 0;
397 for (Integer irow = 0; irow < m_local_size; ++irow) {
398 for (Integer j = m_row_offsets[irow]; j < m_row_offsets[irow + 1]; ++j) {
399 const Integer col = m_cols[j];
401 m_block_cols[index] = 0;
404 m_block_cols[index] = m_block_cols[index - 1] + previous_block_size;
406 previous_block_size =
407 block_sizes->size(col) * block_sizes->size(irow + m_local_offset);
412 m_matrix_impl->allocate();
413 m_matrix_impl->internal()->getValues().fill(0.);
416 for (
auto iter = m_inserters.begin(); iter != m_inserters.end(); ++iter) {
417 BaseInserter* ins = *iter;
418 for (Integer i = 0; i < ins->count(); ++i) {
419 const Integer row = ins->m_row_index[i] - m_local_offset;
420 if (row == m_local_size) {
422 ins->m_data_index[i] = m_block_matrix_size;
425 const Integer col = ins->m_col_index[i];
426 const Integer ghost_offset =
427 (isLocal(col) ? 0 : m_block_row_size[row] - m_block_ghost_row_size[row]);
428 ins->m_data_index[i] =
429 m_block_data_index[nb_ins][i] + m_block_row_offsets[row] + ghost_offset;
433 ins->setMatrixValues(m_matrix_impl->internal()->getDataPtr());
434 ins->m_col_index.dispose();
435 ins->m_row_index.dispose();
439 m_matrix_impl->parallelStart(m_offset, m_parallel_mng);
441 m_matrix_impl->sequentialStart();
442 m_col_ordering = eOwnAndGhost;
445 m_row_size.resize(0);
446 m_ghost_row_size.resize(0);
447 m_block_row_size.resize(0);
448 m_block_ghost_row_size.resize(0);