Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
simple_csr/DistStructInfo.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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#include <map>
8#include <set>
9#include <sstream>
10
13
14#include "CSRStructInfo.h"
15#include "DistStructInfo.h"
16#include "SendRecvOp.h"
17
18using namespace Arccore;
19using namespace Arccore::MessagePassing;
20
21namespace Alien::SimpleCSRInternal
22{
23
24void DistStructInfo::compute(Integer nproc, ConstArrayView<Integer> offset, Integer my_rank,
25 IMessagePassingMng* parallel_mng, const CSRStructInfo& profile,
26 ITraceMng* trace ALIEN_UNUSED_PARAM)
27{
28#ifdef DEBUG
29 std::stringstream file("dd");
30 file << my_rank;
31 ofstream fout(file.str().c_str());
32#endif
33 std::vector<Integer> count(nproc);
34 count.assign(nproc, 0);
35 const Integer nrow = profile.getNRow();
36 ConstArrayView<Integer> row_offset = profile.getRowOffset();
37 // ArrayView<Integer> cols = profile->getCols();
38 m_cols.copy(profile.getCols());
39
40 Integer local_offset = offset[my_rank];
41
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);
50 // TODO: deal with ip == -1
51 // fout<<"col("<<col_uid<<","<<ip<<");";
52 if (ip == my_rank) {
53 // turn col global id to local id
54 m_cols[icol] = col_uid - local_offset;
55 ++lrow_size;
56 }
57 else {
58 /*
59 std::map<Integer, Integer>::iterator iter = lids[ip].find(col_uid);
60 if (iter == lids[ip].end()) {
61 // compute local id of ghost id
62 Integer col_lid = count[ip];
63 lids[ip].insert(std::pair<Integer, Integer>(col_uid, col_lid));
64 // cols[icol] = col_lid;
65 ++count[ip];
66 }*/
67 gids[ip].insert(col_uid);
68 }
69 }
70 // fout<<endl;
71 m_local_row_size[irow] = lrow_size;
72 if (lrow_size < row_offset[irow + 1] - row_offset[irow])
73 ++m_interface_nrow;
74 }
75 // COMPUTE GHOST LOCAL ID PER NEIGH DOMAIN
76 for (Integer ip = 0; ip < nproc; ++ip) {
77 Integer lid = 0;
78 auto& lids_ip = lids[ip];
79 for (Integer uid : gids[ip]) {
80 lids_ip.insert(std::make_pair(uid, lid));
81 ++lid;
82 }
83 }
84 {
85 m_interface_rows.resize(m_interface_nrow);
86 std::vector<Integer> col_offset(nproc + 1);
87 col_offset[0] = nrow;
88 for (Integer ip = 1; ip < nproc + 1; ++ip) {
89 // col_offset[ip] = col_offset[ip - 1] + count[ip - 1];
90 col_offset[ip] = col_offset[ip - 1] + gids[ip - 1].size();
91 }
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);
95 Integer icount = 0;
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);
102 ++icount;
103 for (Integer icol = row_offset[irow] + m_local_row_size[irow];
104 icol < row_offset[irow + 1]; ++icol) {
105 // compute local id of ghost col id
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);
110 if (iter.second) {
111 m_recv_info.m_rank_ids[ghost_icount] = ip;
112 m_recv_info.m_ids[ghost_icount] = m_cols[icol];
113 ++ghost_icount;
114 }
115 }
116 }
117 }
118 }
120 //
121 // compute mailing list for mat mult communication operation
122 //
123 // INFO to recv from neighbour processors
124 //
125 Integer nb_neighbour = 0;
126 Integer first_upper_neighb = 0;
127 for (Integer ip = 0; ip < nproc; ++ip)
128 // if (count[ip] > 0)
129 // ++nb_neighbour;
130 if (gids[ip].size() > 0) {
131 ++nb_neighbour;
132 if (ip < my_rank)
133 ++first_upper_neighb;
134 }
135
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);
140 nb_neighbour = 0;
141 m_recv_info.m_ids_offset[0] = nrow;
142 for (Integer ip = 0; ip < nproc; ++ip)
143 // if (count[ip] > 0) {
144 if (gids[ip].size() > 0) {
145 m_recv_info.m_ranks[nb_neighbour] = ip;
146 // m_recv_info.m_ids_offset[nb_neighbour + 1] =
147 // m_recv_info.m_ids_offset[nb_neighbour] + count[ip];
148 m_recv_info.m_ids_offset[nb_neighbour + 1] =
149 m_recv_info.m_ids_offset[nb_neighbour] + gids[ip].size();
150 ++nb_neighbour;
151 }
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];
155 // m_recv_info->printInfo(trace->info().file());
156
158 //
159 // compute mailing list for mat mult communication operation
160 //
161 // INFO to send to neighbour processor
162 std::vector<std::vector<Integer>> send_ids(nproc);
163 nb_neighbour = 0;
164 Integer send_count = 0;
165 std::vector<Integer> buffer;
166 for (Integer ip = 0; ip < nproc; ++ip) {
167 if (ip == my_rank) {
168 Integer offset = 0;
169 for (Integer ip2 = 0; ip2 < nproc; ++ip2) {
170 if (ip2 != my_rank) {
171 // Integer nids = lids[ip2].size();
172 // Integer nids = count[ip2];
173 Integer nids = gids[ip2].size();
174 // trace->info()<<"SEND to "<<ip2<<" nids="<<nids;
175 Arccore::MessagePassing::mpSend(
176 parallel_mng, ConstArrayView<Integer>(1, &nids), ip2);
177 if (nids > 0) {
178 buffer.clear();
179 buffer.resize(nids);
180 // buffer.reserve(nids);
181 std::map<Integer, Integer>::iterator iter = lids[ip2].begin();
182 while (iter != lids[ip2].end()) {
183 // buffer.push_back((*iter).first);
184 buffer[(*iter).second] = (*iter).first;
185 m_recv_info.m_uids[offset + (*iter).second] = (*iter).first;
186 ++iter;
187 }
188
189 Arccore::MessagePassing::mpSend(
190 parallel_mng, ConstArrayView<Integer>(nids, &buffer[0]), ip2);
191 offset += nids;
192 }
193 }
194 }
195 }
196 else {
197 Integer nids = 0;
198 Arccore::MessagePassing::mpReceive(parallel_mng, ArrayView<Integer>(1, &nids), ip);
199 // trace->info()<<"RECV from "<<ip<<" nids="<<nids;
200 if (nids > 0) {
201 ++nb_neighbour;
202 send_count += nids;
203 send_ids[ip].resize(nids);
204 Arccore::MessagePassing::mpReceive(
205 parallel_mng, ArrayView<Integer>(nids, &send_ids[ip][0]), ip);
206 }
207 }
208 }
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;
214 Integer icount = 0;
215 nb_neighbour = 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;
220 ++nb_neighbour;
221 if (ip < my_rank)
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;
227 // fout<<"SEND : "<<ids[i]<<" "<<ids[i] - local_offset<<endl;
228 ++icount;
229 }
230 }
231 }
232 m_send_info.m_ids_offset[nb_neighbour] = icount;
233 m_send_info.m_first_upper_neighb = first_upper_neighb;
234
235 // m_send_info->printInfo(trace->info().file());
236}
237
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)
242{
243 // alien_info([&] {cout() << "DistStructInfo::compute VBlock";}) ;
244 std::vector<Integer> count(nproc);
245 count.assign(nproc, 0);
246 std::vector<Integer> block_count(nproc);
247 block_count.assign(nproc, 0);
248
249 Integer nrow = profile.getNRow();
250 ConstArrayView<Integer> row_offset = profile.getRowOffset();
251 m_cols.copy(profile.getCols());
252
253 VBlockImpl blocks(*block_sizes, dist);
254
255 Integer block_nrow = 0;
256 for (Integer i = 0; i < nrow; ++i) {
257 block_nrow += blocks.sizeFromLocalIndex(i);
258 }
259
260 Integer local_offset = offset[my_rank];
261
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;
267 // fout<<"ROW("<<irow<<")";
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);
271 // TODO: Deal with ip == -1
272 // fout<<"col("<<col_uid<<","<<ip<<");";
273 if (ip == my_rank) {
274 // turn col global id to local id
275 m_cols[icol] = col_uid - local_offset;
276 ++lrow_size;
277 }
278 else {
279 /*
280 std::map<Integer, Integer>::iterator iter = lids[ip].find(col_uid);
281 if (iter == lids[ip].end()) {
282 // compute local id of ghost id
283 Integer col_lid = count[ip];
284 lids[ip].insert(std::pair<Integer, Integer>(col_uid, col_lid));
285 // cols[icol] = col_lid;
286 ++count[ip];
287 block_count[ip] += block_sizes->size(col_uid);
288 }*/
289 auto value = gids[ip].insert(col_uid);
290 if (value.second)
291 block_count[ip] += block_sizes->size(col_uid);
292 }
293 }
294 // fout<<endl;
295 m_local_row_size[irow] = lrow_size;
296 if (lrow_size < row_offset[irow + 1] - row_offset[irow])
297 ++m_interface_nrow;
298 }
299
300 // COMPUTE GHOST LOCAL ID PER NEIGH DOMAIN
301 for (int ip = 0; ip < nproc; ++ip) {
302 int lid = 0;
303 auto& lids_ip = lids[ip];
304 for (int uid : gids[ip]) {
305 lids_ip.insert(std::make_pair(uid, lid));
306 ++lid;
307 }
308 }
309
310 {
311 // Il faut une map ordonn?e
312 std::map<Integer, Integer> ghost_sizes;
313
314 // Integer icount = 0;
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)
319 // col_offset[ip] = col_offset[ip - 1] + count[ip - 1];
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);
324 int icount = 0;
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);
331 ++icount;
332 // fout<<my_rank<<" Interface row : "<<irow << std::endl;
333 for (Integer icol = row_offset[irow] + m_local_row_size[irow];
334 icol < row_offset[irow + 1]; ++icol) {
335 // compute local id of ghost col id
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);
340 if (iter.second) {
341 m_recv_info.m_rank_ids[ghost_icount] = ip;
342 m_recv_info.m_ids[ghost_icount] = m_cols[icol];
343 ++ghost_icount;
344 }
345 // fout<<"COL["<<icol<<","<<col_uid<<"]="<<m_cols[icol]<<"
346 // "<<col_offset[ip]<<endl; trace->info()
347 // <<"COL["<<icol<<","<<col_uid<<"]="<<m_cols[icol]<<" "<<col_offset[ip];
348 ghost_sizes[m_cols[icol]] = block_sizes->size(col_uid);
349 // block_sizes.setGhostLocalId(col_uid,m_cols[icol]);
350 }
351 }
352 }
353
354 ConstArrayView<Integer> local_sizes = blocks.sizeOfLocalIndex();
355 ConstArrayView<Integer> local_offsets = blocks.offsetOfLocalIndex();
356
357 ALIEN_ASSERT(
358 (local_offsets.size() == local_sizes.size() + 1), ("sizes are different"));
359
360 const Integer size = local_sizes.size();
361 const Integer ghost_size = ghost_sizes.size();
362 const Integer total_size = size + ghost_size;
363
364 m_block_sizes.resize(total_size);
365 m_block_offsets.resize(total_size + 1);
366
367 for (Integer i = 0; i < size; ++i) {
368 m_block_sizes[i] = local_sizes[i];
369 m_block_offsets[i] = local_offsets[i];
370 }
371
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];
377 }
378 m_block_offsets[total_size] = m_block_offsets[total_size - 1] + m_block_sizes[total_size - 1];
379 }
380
381 // for(Integer i = 0; i < m_block_sizes.size(); ++i) {
382 // trace->info() << "block_sizes[" << i << "] = " << m_block_sizes[i];
383 // trace->info() << "block_offsets[" << i << "] = " << m_block_offsets[i];
384 // }
385
387 //
388 // compute mailing list for mat mult communication operation
389 //
390 // INFO to recv from neighbour processors
391 //
392 Integer nb_neighbour = 0;
393 // for (Integer ip = 0; ip < nproc; ++ip)
394 // if (count[ip] > 0)
395 // ++nb_neighbour;
396 int first_upper_neighb = 0;
397 for (int ip = 0; ip < nproc; ++ip)
398 if (gids[ip].size() > 0) {
399 ++nb_neighbour;
400 if (ip < my_rank)
401 ++first_upper_neighb;
402 }
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);
408 nb_neighbour = 0;
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)
412 // if (count[ip] > 0) {
413 if (gids[ip].size() > 0) {
414 m_recv_info.m_ranks[nb_neighbour] = ip;
415 // m_recv_info.m_ids_offset[nb_neighbour + 1] =
416 // m_recv_info.m_ids_offset[nb_neighbour] + count[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];
421 ++nb_neighbour;
422 }
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];
426
427 // m_recv_info.printInfo(recv_fout);
428
430 //
431 // compute mailing list for mat mult communication operation
432 //
433 // INFO to send to neighbour processor
434 std::vector<std::vector<Integer>> send_ids(nproc);
435 nb_neighbour = 0;
436 Integer send_count = 0;
437 std::vector<Integer> buffer;
438 for (Integer ip = 0; ip < nproc; ++ip) {
439 if (ip == my_rank) {
440 Integer offset = 0;
441 for (Integer ip2 = 0; ip2 < nproc; ++ip2) {
442 if (ip2 != my_rank) {
443 // Integer nids = lids[ip2].size();
444 // Integer nids = count[ip2];
445 Integer nids = gids[ip2].size();
446 // trace->info()<<"SEND to "<<ip2<<" nids="<<nids;
447 Arccore::MessagePassing::mpSend(
448 parallel_mng, ConstArrayView<Integer>(1, &nids), ip2);
449 if (nids > 0) {
450 buffer.clear();
451 buffer.resize(nids);
452 // buffer.reserve(nids);
453 std::map<Integer, Integer>::iterator iter = lids[ip2].begin();
454 while (iter != lids[ip2].end()) {
455 // buffer.push_back((*iter).first);
456 buffer[(*iter).second] = (*iter).first;
457 m_recv_info.m_uids[offset + (*iter).second] = (*iter).first;
458 ++iter;
459 }
460
461 Arccore::MessagePassing::mpSend(
462 parallel_mng, ConstArrayView<Integer>(nids, &buffer[0]), ip2);
463 offset += nids;
464 }
465 }
466 }
467 }
468 else {
469 Integer nids = 0;
470 Arccore::MessagePassing::mpReceive(parallel_mng, ArrayView<Integer>(1, &nids), ip);
471 // trace->info()<<"RECV from "<<ip<<" nids="<<nids;
472 if (nids > 0) {
473 ++nb_neighbour;
474 send_count += nids;
475 send_ids[ip].resize(nids);
476 Arccore::MessagePassing::mpReceive(
477 parallel_mng, ArrayView<Integer>(nids, &send_ids[ip][0]), ip);
478 }
479 }
480 }
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;
487 nb_neighbour = 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;
493 ++nb_neighbour;
494 if (ip < my_rank)
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;
500 ++icount;
501 block_icount += m_block_sizes[ids[i] - local_offset];
502 }
503 }
504 }
505 m_send_info.m_ids_offset[nb_neighbour] = icount;
506 m_send_info.m_block_ids_offset[nb_neighbour] = block_icount;
507
508 // m_send_info.printInfo(send_fout);
509}
510
511void DistStructInfo::computeBlock2DSizesAndOffsets(Integer const* kcol,
512 Integer const* dcol,
513 Integer const* bcol) const
514{
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]];
522 }
523 {
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;
530 }
531 m_block2d_offsets[nrows + m_ghost_nrow] = offset;
532 }
533 {
534 m_send_info.m_block2d_ids_offset.resize(m_send_info.m_num_neighbours + 1);
535 Integer offset = 0;
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;
541 }
542 }
543 m_send_info.m_block2d_ids_offset[m_send_info.m_num_neighbours] = offset;
544 }
545
546 {
547 m_recv_info.m_block2d_ids_offset.resize(m_recv_info.m_num_neighbours + 1);
548 Integer offset = 0;
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;
554 }
555 }
556 m_recv_info.m_block2d_ids_offset[m_recv_info.m_num_neighbours] = offset;
557 }
558}
559
560void DistStructInfo::copy(const DistStructInfo& src)
561{
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;
566
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);
570
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);
574
575 m_recv_info.copy(src.m_recv_info);
576 m_send_info.copy(src.m_send_info);
577}
578
579} // namespace Alien::SimpleCSRInternal
580
VBlockOffsets.h.
VBlock.h.