14#include "CSRStructInfo.h"
15#include "DistStructInfo.h"
16#include "SendRecvOp.h"
18using namespace Arccore;
19using namespace Arccore::MessagePassing;
21namespace Alien::SimpleCSRInternal
24void DistStructInfo::compute(Integer nproc, ConstArrayView<Integer> offset, Integer my_rank,
25 IMessagePassingMng* parallel_mng,
const CSRStructInfo& profile,
26 ITraceMng* trace ALIEN_UNUSED_PARAM)
29 std::stringstream file(
"dd");
31 ofstream fout(file.str().c_str());
33 std::vector<Integer> count(nproc);
34 count.assign(nproc, 0);
35 const Integer nrow = profile.getNRow();
36 ConstArrayView<Integer> row_offset = profile.getRowOffset();
38 m_cols.copy(profile.getCols());
40 Integer local_offset = offset[my_rank];
42 std::vector<std::map<Integer, Integer>> lids(nproc);
43 std::vector<std::set<Integer>> gids(nproc);
44 m_local_row_size.resize(nrow);
45 for (Integer irow = 0; irow < nrow; ++irow) {
46 Integer lrow_size = 0;
47 for (Integer icol = row_offset[irow]; icol < row_offset[irow + 1]; ++icol) {
48 Integer col_uid = m_cols[icol];
49 Integer ip = domainId(nproc, offset, col_uid);
54 m_cols[icol] = col_uid - local_offset;
67 gids[ip].insert(col_uid);
71 m_local_row_size[irow] = lrow_size;
72 if (lrow_size < row_offset[irow + 1] - row_offset[irow])
76 for (Integer ip = 0; ip < nproc; ++ip) {
78 auto& lids_ip = lids[ip];
79 for (Integer uid : gids[ip]) {
80 lids_ip.insert(std::make_pair(uid, lid));
85 m_interface_rows.resize(m_interface_nrow);
86 std::vector<Integer> col_offset(nproc + 1);
88 for (Integer ip = 1; ip < nproc + 1; ++ip) {
90 col_offset[ip] = col_offset[ip - 1] + gids[ip - 1].size();
92 std::size_t ghost_size = col_offset[nproc] - col_offset[0];
93 m_recv_info.m_rank_ids.resize(ghost_size);
94 m_recv_info.m_ids.resize(ghost_size);
96 Integer ghost_icount = 0;
97 std::set<Integer> ghost_set;
98 for (Integer irow = 0; irow < nrow; ++irow) {
99 if (m_local_row_size[irow] < row_offset[irow + 1] - row_offset[irow]) {
100 m_interface_rows[icount] = irow;
101 m_interface_row_set.insert(irow);
103 for (Integer icol = row_offset[irow] + m_local_row_size[irow];
104 icol < row_offset[irow + 1]; ++icol) {
106 Integer col_uid = m_cols[icol];
107 Integer ip = domainId(nproc, offset, col_uid);
108 m_cols[icol] = lids[ip][col_uid] + col_offset[ip];
109 auto const& iter = ghost_set.insert(col_uid);
111 m_recv_info.m_rank_ids[ghost_icount] = ip;
112 m_recv_info.m_ids[ghost_icount] = m_cols[icol];
125 Integer nb_neighbour = 0;
126 Integer first_upper_neighb = 0;
127 for (Integer ip = 0; ip < nproc; ++ip)
130 if (gids[ip].size() > 0) {
133 ++first_upper_neighb;
136 m_recv_info.m_num_neighbours = nb_neighbour;
137 m_recv_info.m_first_upper_neighb = first_upper_neighb;
138 m_recv_info.m_ranks.resize(nb_neighbour);
139 m_recv_info.m_ids_offset.resize(nb_neighbour + 1);
141 m_recv_info.m_ids_offset[0] = nrow;
142 for (Integer ip = 0; ip < nproc; ++ip)
144 if (gids[ip].size() > 0) {
145 m_recv_info.m_ranks[nb_neighbour] = ip;
148 m_recv_info.m_ids_offset[nb_neighbour + 1] =
149 m_recv_info.m_ids_offset[nb_neighbour] + gids[ip].size();
152 m_ghost_nrow = m_recv_info.m_ids_offset[nb_neighbour] - nrow;
153 m_recv_info.m_uids.resize(m_ghost_nrow);
154 m_first_upper_ghost_index = m_recv_info.m_ids_offset[first_upper_neighb];
162 std::vector<std::vector<Integer>> send_ids(nproc);
164 Integer send_count = 0;
165 std::vector<Integer> buffer;
166 for (Integer ip = 0; ip < nproc; ++ip) {
169 for (Integer ip2 = 0; ip2 < nproc; ++ip2) {
170 if (ip2 != my_rank) {
173 Integer nids = gids[ip2].size();
175 Arccore::MessagePassing::mpSend(
176 parallel_mng, ConstArrayView<Integer>(1, &nids), ip2);
181 std::map<Integer, Integer>::iterator iter = lids[ip2].begin();
182 while (iter != lids[ip2].end()) {
184 buffer[(*iter).second] = (*iter).first;
185 m_recv_info.m_uids[offset + (*iter).second] = (*iter).first;
189 Arccore::MessagePassing::mpSend(
190 parallel_mng, ConstArrayView<Integer>(nids, &buffer[0]), ip2);
198 Arccore::MessagePassing::mpReceive(parallel_mng, ArrayView<Integer>(1, &nids), ip);
203 send_ids[ip].resize(nids);
204 Arccore::MessagePassing::mpReceive(
205 parallel_mng, ArrayView<Integer>(nids, &send_ids[ip][0]), ip);
209 m_send_info.m_num_neighbours = nb_neighbour;
210 m_send_info.m_ranks.resize(nb_neighbour);
211 m_send_info.m_ids.resize(send_count);
212 m_send_info.m_ids_offset.resize(nb_neighbour + 1);
213 first_upper_neighb = 0;
216 for (Integer ip = 0; ip < nproc; ++ip) {
217 if (send_ids[ip].size() > 0) {
218 m_send_info.m_ranks[nb_neighbour] = ip;
219 m_send_info.m_ids_offset[nb_neighbour] = icount;
222 ++first_upper_neighb;
223 std::size_t nids = send_ids[ip].size();
224 Integer* ids = &send_ids[ip][0];
225 for (
auto i = 0; i < nids; ++i) {
226 m_send_info.m_ids[icount] = ids[i] - local_offset;
232 m_send_info.m_ids_offset[nb_neighbour] = icount;
233 m_send_info.m_first_upper_neighb = first_upper_neighb;
238void DistStructInfo::compute(Integer nproc, ConstArrayView<Integer> offset, Integer my_rank,
239 IMessagePassingMng* parallel_mng,
const CSRStructInfo& profile,
240 const VBlock* block_sizes,
const MatrixDistribution& dist,
241 ITraceMng* trace ALIEN_UNUSED_PARAM)
244 std::vector<Integer> count(nproc);
245 count.assign(nproc, 0);
246 std::vector<Integer> block_count(nproc);
247 block_count.assign(nproc, 0);
249 Integer nrow = profile.getNRow();
250 ConstArrayView<Integer> row_offset = profile.getRowOffset();
251 m_cols.copy(profile.getCols());
253 VBlockImpl blocks(*block_sizes, dist);
255 Integer block_nrow = 0;
256 for (Integer i = 0; i < nrow; ++i) {
257 block_nrow += blocks.sizeFromLocalIndex(i);
260 Integer local_offset = offset[my_rank];
262 std::vector<std::map<Integer, Integer>> lids(nproc);
263 std::vector<std::set<Integer>> gids(nproc);
264 m_local_row_size.resize(nrow);
265 for (Integer irow = 0; irow < nrow; ++irow) {
266 Integer lrow_size = 0;
268 for (Integer icol = row_offset[irow]; icol < row_offset[irow + 1]; ++icol) {
269 Integer col_uid = m_cols[icol];
270 Integer ip = domainId(nproc, offset, col_uid);
275 m_cols[icol] = col_uid - local_offset;
289 auto value = gids[ip].insert(col_uid);
291 block_count[ip] += block_sizes->size(col_uid);
295 m_local_row_size[irow] = lrow_size;
296 if (lrow_size < row_offset[irow + 1] - row_offset[irow])
301 for (
int ip = 0; ip < nproc; ++ip) {
303 auto& lids_ip = lids[ip];
304 for (
int uid : gids[ip]) {
305 lids_ip.insert(std::make_pair(uid, lid));
312 std::map<Integer, Integer> ghost_sizes;
315 m_interface_rows.resize(m_interface_nrow);
316 std::vector<Integer> col_offset(nproc + 1);
317 col_offset[0] = nrow;
318 for (Integer ip = 1; ip < nproc + 1; ++ip)
320 col_offset[ip] = col_offset[ip - 1] + gids[ip - 1].size();
321 std::size_t ghostsize = col_offset[nproc] - col_offset[0];
322 m_recv_info.m_rank_ids.resize(ghostsize);
323 m_recv_info.m_ids.resize(ghostsize);
325 int ghost_icount = 0;
326 std::set<int> ghost_set;
327 for (Integer irow = 0; irow < nrow; ++irow) {
328 if (m_local_row_size[irow] < row_offset[irow + 1] - row_offset[irow]) {
329 m_interface_rows[icount] = irow;
330 m_interface_row_set.insert(irow);
333 for (Integer icol = row_offset[irow] + m_local_row_size[irow];
334 icol < row_offset[irow + 1]; ++icol) {
336 Integer col_uid = m_cols[icol];
337 Integer ip = domainId(nproc, offset, col_uid);
338 m_cols[icol] = lids[ip][col_uid] + col_offset[ip];
339 auto const& iter = ghost_set.insert(col_uid);
341 m_recv_info.m_rank_ids[ghost_icount] = ip;
342 m_recv_info.m_ids[ghost_icount] = m_cols[icol];
348 ghost_sizes[m_cols[icol]] = block_sizes->size(col_uid);
354 ConstArrayView<Integer> local_sizes = blocks.sizeOfLocalIndex();
355 ConstArrayView<Integer> local_offsets = blocks.offsetOfLocalIndex();
358 (local_offsets.size() == local_sizes.size() + 1), (
"sizes are different"));
360 const Integer size = local_sizes.size();
361 const Integer ghost_size = ghost_sizes.size();
362 const Integer total_size = size + ghost_size;
364 m_block_sizes.resize(total_size);
365 m_block_offsets.resize(total_size + 1);
367 for (Integer i = 0; i < size; ++i) {
368 m_block_sizes[i] = local_sizes[i];
369 m_block_offsets[i] = local_offsets[i];
372 for (std::map<Integer, Integer>::const_iterator it = ghost_sizes.begin();
373 it != ghost_sizes.end(); ++it) {
374 const Integer lid = it->first;
375 m_block_sizes[lid] = it->second;
376 m_block_offsets[lid] = m_block_offsets[lid - 1] + m_block_sizes[lid - 1];
378 m_block_offsets[total_size] = m_block_offsets[total_size - 1] + m_block_sizes[total_size - 1];
392 Integer nb_neighbour = 0;
396 int first_upper_neighb = 0;
397 for (
int ip = 0; ip < nproc; ++ip)
398 if (gids[ip].size() > 0) {
401 ++first_upper_neighb;
403 m_recv_info.m_num_neighbours = nb_neighbour;
404 m_recv_info.m_first_upper_neighb = first_upper_neighb;
405 m_recv_info.m_ranks.resize(nb_neighbour);
406 m_recv_info.m_ids_offset.resize(nb_neighbour + 1);
407 m_recv_info.m_block_ids_offset.resize(nb_neighbour + 1);
409 m_recv_info.m_ids_offset[0] = nrow;
410 m_recv_info.m_block_ids_offset[0] = block_nrow;
411 for (Integer ip = 0; ip < nproc; ++ip)
413 if (gids[ip].size() > 0) {
414 m_recv_info.m_ranks[nb_neighbour] = ip;
417 m_recv_info.m_ids_offset[nb_neighbour + 1] =
418 m_recv_info.m_ids_offset[nb_neighbour] + gids[ip].size();
419 m_recv_info.m_block_ids_offset[nb_neighbour + 1] =
420 m_recv_info.m_block_ids_offset[nb_neighbour] + block_count[ip];
423 m_ghost_nrow = m_recv_info.m_ids_offset[nb_neighbour] - nrow;
424 m_recv_info.m_uids.resize(m_ghost_nrow);
425 m_first_upper_ghost_index = m_recv_info.m_ids_offset[first_upper_neighb];
434 std::vector<std::vector<Integer>> send_ids(nproc);
436 Integer send_count = 0;
437 std::vector<Integer> buffer;
438 for (Integer ip = 0; ip < nproc; ++ip) {
441 for (Integer ip2 = 0; ip2 < nproc; ++ip2) {
442 if (ip2 != my_rank) {
445 Integer nids = gids[ip2].size();
447 Arccore::MessagePassing::mpSend(
448 parallel_mng, ConstArrayView<Integer>(1, &nids), ip2);
453 std::map<Integer, Integer>::iterator iter = lids[ip2].begin();
454 while (iter != lids[ip2].end()) {
456 buffer[(*iter).second] = (*iter).first;
457 m_recv_info.m_uids[offset + (*iter).second] = (*iter).first;
461 Arccore::MessagePassing::mpSend(
462 parallel_mng, ConstArrayView<Integer>(nids, &buffer[0]), ip2);
470 Arccore::MessagePassing::mpReceive(parallel_mng, ArrayView<Integer>(1, &nids), ip);
475 send_ids[ip].resize(nids);
476 Arccore::MessagePassing::mpReceive(
477 parallel_mng, ArrayView<Integer>(nids, &send_ids[ip][0]), ip);
481 m_send_info.m_num_neighbours = nb_neighbour;
482 m_send_info.m_ranks.resize(nb_neighbour);
483 m_send_info.m_ids.resize(send_count);
484 m_send_info.m_ids_offset.resize(nb_neighbour + 1);
485 m_send_info.m_block_ids_offset.resize(nb_neighbour + 1);
486 Integer icount = 0, block_icount = 0;
488 for (Integer ip = 0; ip < nproc; ++ip) {
489 if (send_ids[ip].size() > 0) {
490 m_send_info.m_ranks[nb_neighbour] = ip;
491 m_send_info.m_ids_offset[nb_neighbour] = icount;
492 m_send_info.m_block_ids_offset[nb_neighbour] = block_icount;
495 ++first_upper_neighb;
496 Integer nids = send_ids[ip].size();
497 Integer* ids = &send_ids[ip][0];
498 for (Integer i = 0; i < nids; ++i) {
499 m_send_info.m_ids[icount] = ids[i] - local_offset;
501 block_icount += m_block_sizes[ids[i] - local_offset];
505 m_send_info.m_ids_offset[nb_neighbour] = icount;
506 m_send_info.m_block_ids_offset[nb_neighbour] = block_icount;
511void DistStructInfo::computeBlock2DSizesAndOffsets(Integer
const* kcol,
513 Integer
const* bcol)
const
515 auto nrows = m_local_row_size.size();
516 m_block2d_sizes.resize(nrows + m_ghost_nrow);
517 m_block2d_offsets.resize(nrows + m_ghost_nrow + 1);
518 for (
int irow = 0; irow < nrows; ++irow) {
519 auto blk_size = m_block_sizes[irow];
520 m_block2d_sizes[irow] = blk_size * blk_size;
521 m_block2d_offsets[irow] = bcol[dcol[irow]];
524 Integer offset = bcol[kcol[nrows]];
525 for (
int irow = nrows; irow < nrows + m_ghost_nrow; ++irow) {
526 auto blk_size = m_block_sizes[irow];
527 m_block2d_sizes[irow] = blk_size * blk_size;
528 m_block2d_offsets[irow] = offset;
529 offset += blk_size * blk_size;
531 m_block2d_offsets[nrows + m_ghost_nrow] = offset;
534 m_send_info.m_block2d_ids_offset.resize(m_send_info.m_num_neighbours + 1);
536 for (Integer ineighb = 0; ineighb < m_send_info.m_num_neighbours; ++ineighb) {
537 m_send_info.m_block2d_ids_offset[ineighb] = offset;
538 for (Integer k = m_send_info.m_ids_offset[ineighb]; k < m_send_info.m_ids_offset[ineighb + 1]; ++k) {
539 auto blk_size = m_block_sizes[m_send_info.m_ids[k]];
540 offset += blk_size * blk_size;
543 m_send_info.m_block2d_ids_offset[m_send_info.m_num_neighbours] = offset;
547 m_recv_info.m_block2d_ids_offset.resize(m_recv_info.m_num_neighbours + 1);
549 for (Integer ineighb = 0; ineighb < m_recv_info.m_num_neighbours; ++ineighb) {
550 m_recv_info.m_block2d_ids_offset[ineighb] = offset;
551 for (Integer k = m_recv_info.m_ids_offset[ineighb]; k < m_recv_info.m_ids_offset[ineighb + 1]; ++k) {
552 auto blk_size = m_block_sizes[k];
553 offset += blk_size * blk_size;
556 m_recv_info.m_block2d_ids_offset[m_recv_info.m_num_neighbours] = offset;
562 m_local_row_size.copy(src.m_local_row_size);
563 m_ghost_nrow = src.m_ghost_nrow;
564 m_interface_nrow = src.m_interface_nrow;
565 m_first_upper_ghost_index = src.m_first_upper_ghost_index;
567 m_interface_rows.copy(src.m_interface_rows);
568 m_interface_row_set = src.m_interface_row_set;
569 m_cols.copy(src.m_cols);
571 m_upper_diag_offset.copy(src.m_upper_diag_offset);
572 m_block_sizes.copy(src.m_block_sizes);
573 m_block_offsets.copy(src.m_block_offsets);
575 m_recv_info.copy(src.m_recv_info);
576 m_send_info.copy(src.m_send_info);