32#include "DistStructInfo.h"
41#include "BEllPacktructInfo.h"
42#include "SendRecvOp.h"
44using namespace Arccore;
45using namespace Arccore::MessagePassing;
47namespace Alien::SimpleCSRInternal
49void DistStructInfo::compute(Integer nproc, ConstArrayView<Integer> offset, Integer my_rank,
50 IMessagePassingMng* parallel_mng,
const BaseBEllPackStructInfo& profile,
51 ITraceMng* trace ALIEN_UNUSED_PARAM)
54 std::stringstream file(
"dd");
56 ofstream fout(file.str().c_str());
58 std::vector<Integer> count(nproc);
59 count.assign(nproc, 0);
60 const Integer nrow = profile.getNRow();
61 ConstArrayView<Integer> row_offset = profile.getRowOffset();
63 m_cols.copy(profile.getCols());
65 Integer local_offset = offset[my_rank];
67 std::vector<std::map<Integer, Integer>> lids(nproc);
68 std::vector<std::set<Integer>> gids(nproc);
69 m_local_row_size.resize(nrow);
70 for (Integer irow = 0; irow < nrow; ++irow) {
71 Integer lrow_size = 0;
72 for (Integer icol = row_offset[irow]; icol < row_offset[irow + 1]; ++icol) {
73 Integer col_uid = m_cols[icol];
74 Integer ip = domainId(nproc, offset, col_uid);
79 m_cols[icol] = col_uid - local_offset;
92 gids[ip].insert(col_uid);
96 m_local_row_size[irow] = lrow_size;
97 if (lrow_size < row_offset[irow + 1] - row_offset[irow])
101 for (Integer ip = 0; ip < nproc; ++ip) {
103 auto& lids_ip = lids[ip];
104 for (Integer uid : gids[ip]) {
105 lids_ip.insert(std::make_pair(uid, lid));
110 m_interface_rows.resize(m_interface_nrow);
111 std::vector<Integer> col_offset(nproc + 1);
112 col_offset[0] = nrow;
113 for (Integer ip = 1; ip < nproc + 1; ++ip) {
115 col_offset[ip] = col_offset[ip - 1] + gids[ip - 1].size();
117 std::size_t ghost_size = col_offset[nproc] - col_offset[0];
118 m_recv_info.m_rank_ids.resize(ghost_size);
119 m_recv_info.m_ids.resize(ghost_size);
121 Integer ghost_icount = 0;
122 std::set<Integer> ghost_set;
123 for (Integer irow = 0; irow < nrow; ++irow) {
124 if (m_local_row_size[irow] < row_offset[irow + 1] - row_offset[irow]) {
125 m_interface_rows[icount] = irow;
126 m_interface_row_set.insert(irow);
128 for (Integer icol = row_offset[irow] + m_local_row_size[irow];
129 icol < row_offset[irow + 1]; ++icol) {
131 Integer col_uid = m_cols[icol];
132 Integer ip = domainId(nproc, offset, col_uid);
133 m_cols[icol] = lids[ip][col_uid] + col_offset[ip];
134 auto const& iter = ghost_set.insert(col_uid);
136 m_recv_info.m_rank_ids[ghost_icount] = ip;
137 m_recv_info.m_ids[ghost_icount] = m_cols[icol];
150 Integer nb_neighbour = 0;
151 Integer first_upper_neighb = 0;
152 for (Integer ip = 0; ip < nproc; ++ip)
155 if (gids[ip].size() > 0) {
158 ++first_upper_neighb;
161 m_recv_info.m_num_neighbours = nb_neighbour;
162 m_recv_info.m_first_upper_neighb = first_upper_neighb;
163 m_recv_info.m_ranks.resize(nb_neighbour);
164 m_recv_info.m_ids_offset.resize(nb_neighbour + 1);
166 m_recv_info.m_ids_offset[0] = nrow;
167 for (Integer ip = 0; ip < nproc; ++ip)
169 if (gids[ip].size() > 0) {
170 m_recv_info.m_ranks[nb_neighbour] = ip;
173 m_recv_info.m_ids_offset[nb_neighbour + 1] =
174 m_recv_info.m_ids_offset[nb_neighbour] + gids[ip].size();
177 m_ghost_nrow = m_recv_info.m_ids_offset[nb_neighbour] - nrow;
178 m_recv_info.m_uids.resize(m_ghost_nrow);
179 m_first_upper_ghost_index = m_recv_info.m_ids_offset[first_upper_neighb];
187 std::vector<std::vector<Integer>> send_ids(nproc);
189 Integer send_count = 0;
190 std::vector<Integer> buffer;
191 for (Integer ip = 0; ip < nproc; ++ip) {
194 for (Integer ip2 = 0; ip2 < nproc; ++ip2) {
195 if (ip2 != my_rank) {
198 Integer nids = gids[ip2].size();
200 Arccore::MessagePassing::mpSend(
201 parallel_mng, ConstArrayView<Integer>(1, &nids), ip2);
206 std::map<Integer, Integer>::iterator iter = lids[ip2].begin();
207 while (iter != lids[ip2].end()) {
209 buffer[(*iter).second] = (*iter).first;
210 m_recv_info.m_uids[offset + (*iter).second] = (*iter).first;
214 Arccore::MessagePassing::mpSend(
215 parallel_mng, ConstArrayView<Integer>(nids, &buffer[0]), ip2);
223 Arccore::MessagePassing::mpReceive(parallel_mng, ArrayView<Integer>(1, &nids), ip);
228 send_ids[ip].resize(nids);
229 Arccore::MessagePassing::mpReceive(
230 parallel_mng, ArrayView<Integer>(nids, &send_ids[ip][0]), ip);
234 m_send_info.m_num_neighbours = nb_neighbour;
235 m_send_info.m_ranks.resize(nb_neighbour);
236 m_send_info.m_ids.resize(send_count);
237 m_send_info.m_ids_offset.resize(nb_neighbour + 1);
238 first_upper_neighb = 0;
241 for (Integer ip = 0; ip < nproc; ++ip) {
242 if (send_ids[ip].size() > 0) {
243 m_send_info.m_ranks[nb_neighbour] = ip;
244 m_send_info.m_ids_offset[nb_neighbour] = icount;
247 ++first_upper_neighb;
248 std::size_t nids = send_ids[ip].size();
249 Integer* ids = &send_ids[ip][0];
250 for (
auto i = 0; i < nids; ++i) {
251 m_send_info.m_ids[icount] = ids[i] - local_offset;
257 m_send_info.m_ids_offset[nb_neighbour] = icount;
258 m_send_info.m_first_upper_neighb = first_upper_neighb;
263void DistStructInfo::compute(Integer nproc, ConstArrayView<Integer> offset, Integer my_rank,
264 IMessagePassingMng* parallel_mng,
const BaseBEllPackStructInfo& profile,
265 const VBlock* block_sizes,
const MatrixDistribution& dist,
266 ITraceMng* trace ALIEN_UNUSED_PARAM)
269 std::vector<Integer> count(nproc);
270 count.assign(nproc, 0);
271 std::vector<Integer> block_count(nproc);
272 block_count.assign(nproc, 0);
274 Integer nrow = profile.getNRow();
275 ConstArrayView<Integer> row_offset = profile.getRowOffset();
276 m_cols.copy(profile.getCols());
278 VBlockImpl blocks(*block_sizes, dist);
280 Integer block_nrow = 0;
281 for (Integer i = 0; i < nrow; ++i) {
282 block_nrow += blocks.sizeFromLocalIndex(i);
285 Integer local_offset = offset[my_rank];
287 std::vector<std::map<Integer, Integer>> lids(nproc);
288 std::vector<std::set<Integer>> gids(nproc);
289 m_local_row_size.resize(nrow);
290 for (Integer irow = 0; irow < nrow; ++irow) {
291 Integer lrow_size = 0;
293 for (Integer icol = row_offset[irow]; icol < row_offset[irow + 1]; ++icol) {
294 Integer col_uid = m_cols[icol];
295 Integer ip = domainId(nproc, offset, col_uid);
300 m_cols[icol] = col_uid - local_offset;
314 auto value = gids[ip].insert(col_uid);
316 block_count[ip] += block_sizes->size(col_uid);
320 m_local_row_size[irow] = lrow_size;
321 if (lrow_size < row_offset[irow + 1] - row_offset[irow])
326 for (
int ip = 0; ip < nproc; ++ip) {
328 auto& lids_ip = lids[ip];
329 for (
int uid : gids[ip]) {
330 lids_ip.insert(std::make_pair(uid, lid));
337 std::map<Integer, Integer> ghost_sizes;
340 m_interface_rows.resize(m_interface_nrow);
341 std::vector<Integer> col_offset(nproc + 1);
342 col_offset[0] = nrow;
343 for (Integer ip = 1; ip < nproc + 1; ++ip)
345 col_offset[ip] = col_offset[ip - 1] + gids[ip - 1].size();
346 std::size_t ghostsize = col_offset[nproc] - col_offset[0];
347 m_recv_info.m_rank_ids.resize(ghostsize);
348 m_recv_info.m_ids.resize(ghostsize);
350 int ghost_icount = 0;
351 std::set<int> ghost_set;
352 for (Integer irow = 0; irow < nrow; ++irow) {
353 if (m_local_row_size[irow] < row_offset[irow + 1] - row_offset[irow]) {
354 m_interface_rows[icount] = irow;
355 m_interface_row_set.insert(irow);
358 for (Integer icol = row_offset[irow] + m_local_row_size[irow];
359 icol < row_offset[irow + 1]; ++icol) {
361 Integer col_uid = m_cols[icol];
362 Integer ip = domainId(nproc, offset, col_uid);
363 m_cols[icol] = lids[ip][col_uid] + col_offset[ip];
364 auto const& iter = ghost_set.insert(col_uid);
366 m_recv_info.m_rank_ids[ghost_icount] = ip;
367 m_recv_info.m_ids[ghost_icount] = m_cols[icol];
373 ghost_sizes[m_cols[icol]] = block_sizes->size(col_uid);
379 ConstArrayView<Integer> local_sizes = blocks.sizeOfLocalIndex();
380 ConstArrayView<Integer> local_offsets = blocks.offsetOfLocalIndex();
383 (local_offsets.size() == local_sizes.size() + 1), (
"sizes are different"));
385 const Integer size = local_sizes.size();
386 const Integer ghost_size = ghost_sizes.size();
388 m_block_sizes.resize(size + ghost_size);
389 m_block_offsets.resize(size + ghost_size);
391 for (Integer i = 0; i < size; ++i) {
392 m_block_sizes[i] = local_sizes[i];
393 m_block_offsets[i] = local_offsets[i];
396 for (std::map<Integer, Integer>::const_iterator it = ghost_sizes.begin();
397 it != ghost_sizes.end(); ++it) {
398 const Integer lid = it->first;
399 m_block_sizes[lid] = it->second;
400 m_block_offsets[lid] = m_block_offsets[lid - 1] + m_block_sizes[lid - 1];
415 Integer nb_neighbour = 0;
419 int first_upper_neighb = 0;
420 for (
int ip = 0; ip < nproc; ++ip)
421 if (gids[ip].size() > 0) {
424 ++first_upper_neighb;
426 m_recv_info.m_num_neighbours = nb_neighbour;
427 m_recv_info.m_first_upper_neighb = first_upper_neighb;
428 m_recv_info.m_ranks.resize(nb_neighbour);
429 m_recv_info.m_ids_offset.resize(nb_neighbour + 1);
430 m_recv_info.m_block_ids_offset.resize(nb_neighbour + 1);
432 m_recv_info.m_ids_offset[0] = nrow;
433 m_recv_info.m_block_ids_offset[0] = block_nrow;
434 for (Integer ip = 0; ip < nproc; ++ip)
436 if (gids[ip].size() > 0) {
437 m_recv_info.m_ranks[nb_neighbour] = ip;
440 m_recv_info.m_ids_offset[nb_neighbour + 1] =
441 m_recv_info.m_ids_offset[nb_neighbour] + gids[ip].size();
442 m_recv_info.m_block_ids_offset[nb_neighbour + 1] =
443 m_recv_info.m_block_ids_offset[nb_neighbour] + block_count[ip];
446 m_ghost_nrow = m_recv_info.m_ids_offset[nb_neighbour] - nrow;
447 m_recv_info.m_uids.resize(m_ghost_nrow);
448 m_first_upper_ghost_index = m_recv_info.m_ids_offset[first_upper_neighb];
457 std::vector<std::vector<Integer>> send_ids(nproc);
459 Integer send_count = 0;
460 std::vector<Integer> buffer;
461 for (Integer ip = 0; ip < nproc; ++ip) {
464 for (Integer ip2 = 0; ip2 < nproc; ++ip2) {
465 if (ip2 != my_rank) {
468 Integer nids = gids[ip2].size();
470 Arccore::MessagePassing::mpSend(
471 parallel_mng, ConstArrayView<Integer>(1, &nids), ip2);
476 std::map<Integer, Integer>::iterator iter = lids[ip2].begin();
477 while (iter != lids[ip2].end()) {
479 buffer[(*iter).second] = (*iter).first;
480 m_recv_info.m_uids[offset + (*iter).second] = (*iter).first;
484 Arccore::MessagePassing::mpSend(
485 parallel_mng, ConstArrayView<Integer>(nids, &buffer[0]), ip2);
493 Arccore::MessagePassing::mpReceive(parallel_mng, ArrayView<Integer>(1, &nids), ip);
498 send_ids[ip].resize(nids);
499 Arccore::MessagePassing::mpReceive(
500 parallel_mng, ArrayView<Integer>(nids, &send_ids[ip][0]), ip);
504 m_send_info.m_num_neighbours = nb_neighbour;
505 m_send_info.m_ranks.resize(nb_neighbour);
506 m_send_info.m_ids.resize(send_count);
507 m_send_info.m_ids_offset.resize(nb_neighbour + 1);
508 m_send_info.m_block_ids_offset.resize(nb_neighbour + 1);
509 Integer icount = 0, block_icount = 0;
511 for (Integer ip = 0; ip < nproc; ++ip) {
512 if (send_ids[ip].size() > 0) {
513 m_send_info.m_ranks[nb_neighbour] = ip;
514 m_send_info.m_ids_offset[nb_neighbour] = icount;
515 m_send_info.m_block_ids_offset[nb_neighbour] = block_icount;
518 ++first_upper_neighb;
519 Integer nids = send_ids[ip].size();
520 Integer* ids = &send_ids[ip][0];
521 for (Integer i = 0; i < nids; ++i) {
522 m_send_info.m_ids[icount] = ids[i] - local_offset;
524 block_icount += m_block_sizes[ids[i] - local_offset];
528 m_send_info.m_ids_offset[nb_neighbour] = icount;
529 m_send_info.m_block_ids_offset[nb_neighbour] = block_icount;
536 m_local_row_size.copy(src.m_local_row_size);
537 m_ghost_nrow = src.m_ghost_nrow;
538 m_interface_nrow = src.m_interface_nrow;
540 m_interface_rows.copy(src.m_interface_rows);
541 m_interface_row_set = src.m_interface_row_set;
542 m_cols.copy(src.m_cols);
544 m_block_sizes.copy(src.m_block_sizes);
545 m_block_offsets.copy(src.m_block_offsets);
547 m_recv_info.copy(src.m_recv_info);
548 m_send_info.copy(src.m_send_info);