Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
SendRecvOp.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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#pragma once
8
9#include <vector>
10
11#include <alien/kernels/simple_csr/SimpleCSRPrecomp.h>
12#include <alien/utils/Precomp.h>
13#include <alien/utils/Trace.h>
14
15#include <arccore/message_passing/Messages.h>
16#include <arccore/message_passing/Request.h>
17
18namespace Alien::SimpleCSRInternal
19{
20
22{
23 typedef enum
24 {
25 Synch,
26 ASynch
27 } ePolicyType;
28};
29
30struct CommInfo
31{
32 CommInfo() {}
33
34 void printInfo(std::ostream& fout) const
35 {
36 fout << "Num of neighbours : " << m_num_neighbours << std::endl;
37 fout << "Ranks : ";
38 for (Integer i = 0; i < m_num_neighbours; ++i)
39 fout << m_ranks[i] << " ";
40 fout << std::endl;
41 if (m_ids.size()) {
42 for (Integer i = 0; i < m_num_neighbours; ++i) {
43 fout << "List[" << i << "] : " << m_ids_offset[i] << " " << m_ids_offset[i + 1]
44 << std::endl;
45 for (Integer k = m_ids_offset[i]; k < m_ids_offset[i + 1]; ++k)
46 fout << " id[" << k << "]=" << m_ids[k] << std::endl;
47 if (m_block_ids_offset.size())
48 fout << "Block list[" << i << "] : " << m_block_ids_offset[i] << " "
49 << m_block_ids_offset[i + 1] << std::endl;
50 }
51 }
52 else {
53 if (m_block_ids_offset.size()) {
54 for (Integer i = 0; i < m_num_neighbours + 1; ++i)
55 fout << "offset[" << i << "]=" << m_ids_offset[i]
56 << ",block=" << m_block_ids_offset[i] << std::endl;
57 }
58 else {
59 for (Integer i = 0; i < m_num_neighbours + 1; ++i) {
60 fout << "offset[" << i << "]" << m_ids_offset[i] << std::endl;
61 }
62 }
63 }
64 }
65 inline Arccore::Integer getDomainId(Arccore::Integer id) const
66 {
67 if (id < m_ids_offset[0])
68 return -1;
69 for (Arccore::Integer ineighb = 0; ineighb < m_num_neighbours; ++ineighb) {
70 if (id < m_ids_offset[ineighb + 1])
71 return m_ranks[ineighb];
72 }
73 return -2;
74 }
75
76 inline Arccore::Integer getNeighbId(Arccore::Integer id) const
77 {
78 if (id < m_ids_offset[0])
79 return -1;
80 for (Arccore::Integer ineighb = 0; ineighb < m_num_neighbours; ++ineighb) {
81 if (id < m_ids_offset[ineighb + 1])
82 return ineighb;
83 }
84 return -2;
85 }
86
87 inline Arccore::Integer getRankNeighbId(Arccore::Integer rank) const
88 {
89 for (Arccore::Integer ineighb = 0; ineighb < m_num_neighbours; ++ineighb) {
90 if (m_ranks[ineighb] == rank)
91 return ineighb;
92 }
93 return -1;
94 }
95
96 Arccore::Integer getLocalId(Arccore::Integer ineighb, Arccore::Integer id) const
97 {
98 for (Arccore::Integer k = m_ids_offset[ineighb]; k < m_ids_offset[ineighb + 1]; ++k) {
99 if (m_ids[k] == id)
100 return k - m_ids_offset[ineighb];
101 }
102 return -1;
103 }
104
105 Arccore::Integer getLocalIdFromUid(Arccore::Integer ineighb, Arccore::Integer uid) const
106 {
107 for (Arccore::Integer k = m_ids_offset[ineighb]; k < m_ids_offset[ineighb + 1]; ++k) {
108 if (m_uids[k - m_ids_offset[0]] == uid)
109 return k;
110 }
111 return -1;
112 }
113
114 Arccore::Integer m_num_neighbours = 0;
115 Arccore::Integer m_first_upper_neighb = 0;
116 Arccore::UniqueArray<Arccore::Integer> m_ranks;
117 Arccore::UniqueArray<Arccore::Integer> m_ids;
118 Arccore::UniqueArray<Arccore::Integer> m_uids;
119 Arccore::UniqueArray<Arccore::Integer> m_rank_ids;
120 Arccore::UniqueArray<Arccore::Integer> m_ids_offset;
121 Arccore::UniqueArray<Arccore::Integer> m_block_ids_offset;
122 Arccore::UniqueArray<Arccore::Integer> m_block2d_ids_offset;
123
124 void copy(const CommInfo& commInfo)
125 {
126 m_num_neighbours = commInfo.m_num_neighbours;
127 m_first_upper_neighb = commInfo.m_first_upper_neighb;
128
129 m_ranks.copy(commInfo.m_ranks);
130 m_ids.copy(commInfo.m_ids);
131 m_uids.copy(commInfo.m_uids);
132 m_rank_ids.copy(commInfo.m_rank_ids);
133 m_ids_offset.copy(commInfo.m_ids_offset);
134 m_block_ids_offset.copy(commInfo.m_block_ids_offset);
135 }
136};
137
138class IASynchOp
139{
140 public:
141 IASynchOp() {}
142
143 virtual ~IASynchOp() {}
144 virtual void start(bool insitu = true) = 0;
145 virtual void end(bool insitu = true) = 0;
146};
147
148template <typename ValueT>
149class SendRecvOp : public IASynchOp
150{
151 public:
152 SendRecvOp(const ValueT* send_buffer,
153 const CommInfo& send_info,
154 CommProperty::ePolicyType send_policy,
155 ValueT* recv_buffer,
156 const CommInfo& recv_info,
157 CommProperty::ePolicyType recv_policy,
158 IMessagePassingMng* mng,
159 Arccore::ITraceMng* trace_mng,
160 Integer unknowns_num = 1)
161 : m_is_variable_block(false)
162 , m_send_buffer(send_buffer)
163 , m_send_info(send_info)
164 , m_send_policy(send_policy)
165 , m_recv_buffer(recv_buffer)
166 , m_recv_info(recv_info)
167 , m_recv_policy(recv_policy)
168 , m_parallel_mng(mng)
169 , m_trace(trace_mng)
170 , m_unknowns_num(unknowns_num)
171 {}
172
173 SendRecvOp(const ValueT* send_buffer,
174 const CommInfo& send_info,
175 CommProperty::ePolicyType send_policy,
176 ValueT* recv_buffer,
177 const CommInfo& recv_info,
178 CommProperty::ePolicyType recv_policy,
179 IMessagePassingMng* mng,
180 Arccore::ITraceMng* trace_mng,
181 ConstArrayView<Integer> block_sizes,
182 ConstArrayView<Integer> block_offsets,
183 bool block2d = false)
184 : m_is_variable_block(true)
185 , m_send_buffer(send_buffer)
186 , m_send_info(send_info)
187 , m_send_policy(send_policy)
188 , m_recv_buffer(recv_buffer)
189 , m_recv_info(recv_info)
190 , m_recv_policy(recv_policy)
191 , m_parallel_mng(mng)
192 , m_trace(trace_mng)
193 , m_block_sizes(block_sizes)
194 , m_block_offsets(block_offsets)
195 {
196
197 m_send_block_ids_offset = m_send_info.m_block_ids_offset;
198 m_recv_block_ids_offset = m_recv_info.m_block_ids_offset;
199 if (block2d) {
200 m_send_block_ids_offset = m_send_info.m_block2d_ids_offset;
201 m_recv_block_ids_offset = m_recv_info.m_block2d_ids_offset;
202 }
203 }
204
205 void start(bool insitu = true)
206 {
207 if (m_is_variable_block)
208 _startBlock(insitu);
209 else
210 _start(insitu);
211 }
212
213 void end(bool insitu = true)
214 {
215 if (m_is_variable_block)
216 _endBlock(insitu);
217 else
218 _end(insitu);
219 }
220
221 void recv(bool insitu = true)
222 {
223 ValueT* rbuffer = m_recv_buffer;
224 if (m_recv_info.m_ids.size() && !insitu) {
225 int size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours];
226 m_rbuffer.resize(size * m_unknowns_num);
227 rbuffer = &m_rbuffer[0];
228 }
229 for (int i = 0; i < m_recv_info.m_num_neighbours; ++i) {
230 int off = m_recv_info.m_ids_offset[i];
231 int size = m_recv_info.m_ids_offset[i + 1] - off;
232 ValueT* ptr = rbuffer + off * m_unknowns_num;
233 int rank = m_recv_info.m_ranks[i];
234 Arccore::MessagePassing::mpReceive(m_parallel_mng, ArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
235 }
236 if (m_recv_info.m_ids.size() && !insitu) {
237 int size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours] -
238 m_recv_info.m_ids_offset[0];
239 if (m_unknowns_num == 1)
240 for (int i = 0; i < size; ++i)
241 m_recv_buffer[m_recv_info.m_ids[i]] = m_rbuffer[i];
242 else
243 for (int i = 0; i < size; ++i)
244 for (std::size_t ui = 0; ui < m_unknowns_num; ++ui)
245 m_recv_buffer[m_recv_info.m_ids[i] * m_unknowns_num + ui] = m_rbuffer[i * m_unknowns_num + ui];
246 }
247 }
248
249 void lowerRecv(bool insitu = true)
250 {
251 ValueT* rbuffer = m_recv_buffer;
252 if (m_recv_info.m_ids.size() && !insitu) {
253 int size = m_recv_info.m_ids_offset[m_recv_info.m_first_upper_neighb];
254 m_rbuffer.resize(size * m_unknowns_num);
255 rbuffer = &m_rbuffer[0];
256 }
257 for (int i = 0; i < m_recv_info.m_first_upper_neighb; ++i) {
258 int off = m_recv_info.m_ids_offset[i];
259 int size = m_recv_info.m_ids_offset[i + 1] - off;
260 ValueT* ptr = rbuffer + off * m_unknowns_num;
261 int rank = m_recv_info.m_ranks[i];
262 Arccore::MessagePassing::mpReceive(m_parallel_mng, ArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
263 }
264 if (m_recv_info.m_ids.size() && !insitu) {
265 int size = m_recv_info.m_ids_offset[m_recv_info.m_first_upper_neighb] -
266 m_recv_info.m_ids_offset[0];
267 if (m_unknowns_num == 1)
268 for (int i = 0; i < size; ++i)
269 m_recv_buffer[m_recv_info.m_ids[i]] = m_rbuffer[i];
270 else
271 for (int i = 0; i < size; ++i)
272 for (int ui = 0; ui < m_unknowns_num; ++ui)
273 m_recv_buffer[m_recv_info.m_ids[i] * m_unknowns_num + ui] = m_rbuffer[i * m_unknowns_num + ui];
274 }
275 }
276
277 void upperRecv(bool insitu = true)
278 {
279 ValueT* rbuffer = m_recv_buffer;
280 int size = 0;
281 if (m_recv_info.m_ids.size() && !insitu) {
282 size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours] - m_recv_info.m_ids_offset[m_recv_info.m_first_upper_neighb];
283 m_rbuffer.resize(size * m_unknowns_num);
284 rbuffer = &m_rbuffer[0];
285 }
286 //for(int i=m_recv_info.m_first_upper_neighb;i<m_recv_info.m_num_neighbours;++i)
287 for (int i = m_recv_info.m_num_neighbours - 1; i > m_recv_info.m_first_upper_neighb - 1; --i) {
288 int off = m_recv_info.m_ids_offset[i];
289 int size = m_recv_info.m_ids_offset[i + 1] - off;
290 ValueT* ptr = rbuffer + off * m_unknowns_num;
291 int rank = m_recv_info.m_ranks[i];
292 Arccore::MessagePassing::mpReceive(m_parallel_mng, ArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
293 }
294 if (m_recv_info.m_ids.size() && !insitu) {
295 int size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours] -
296 m_recv_info.m_ids_offset[m_recv_info.m_first_upper_neighb];
297 if (m_unknowns_num == 1)
298 for (int i = 0; i < size; ++i)
299 m_recv_buffer[m_recv_info.m_ids[i]] = m_rbuffer[i];
300 else
301 for (int i = 0; i < size; ++i)
302 for (int ui = 0; ui < m_unknowns_num; ++ui)
303 m_recv_buffer[m_recv_info.m_ids[i] * m_unknowns_num + ui] = m_rbuffer[i * m_unknowns_num + ui];
304 }
305 }
306
307 void send()
308 {
309 ValueT const* sbuffer = m_send_buffer;
310 if (m_send_info.m_ids.size()) {
311 int size = m_send_info.m_ids_offset[m_send_info.m_num_neighbours] -
312 m_send_info.m_ids_offset[0];
313 m_sbuffer.resize(size * m_unknowns_num);
314 if (m_unknowns_num == 1)
315 for (int i = 0; i < size; ++i) {
316 m_sbuffer[i] = m_send_buffer[m_send_info.m_ids[i]];
317 //m_trace->info()<<"SEND"<<m_sbuffer[i];
318 }
319 else
320 for (int i = 0; i < size; ++i)
321 for (int ui = 0; ui < m_unknowns_num; ++ui)
322 m_sbuffer[i * m_unknowns_num + ui] = m_send_buffer[m_send_info.m_ids[i] * m_unknowns_num + ui];
323 sbuffer = &m_sbuffer[0];
324 }
325 for (int i = 0; i < m_send_info.m_num_neighbours; ++i) {
326 int off = m_send_info.m_ids_offset[i];
327 int size = m_send_info.m_ids_offset[i + 1] - off;
328 ValueT const* ptr = sbuffer + off * m_unknowns_num;
329 int rank = m_send_info.m_ranks[i];
330 Arccore::MessagePassing::mpSend(m_parallel_mng, ConstArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
331 }
332 }
333
334 void lowerSend()
335 {
336 ValueT const* sbuffer = m_send_buffer;
337 if (m_send_info.m_ids.size()) {
338 int size = m_send_info.m_ids_offset[m_send_info.m_first_upper_neighb] -
339 m_send_info.m_ids_offset[0];
340 m_sbuffer.resize(size * m_unknowns_num);
341 if (m_unknowns_num == 1)
342 for (int i = 0; i < size; ++i) {
343 m_sbuffer[i] = m_send_buffer[m_send_info.m_ids[i]];
344 //m_trace->info()<<"SEND"<<m_sbuffer[i];
345 }
346 else
347 for (int i = 0; i < size; ++i)
348 for (int ui = 0; ui < m_unknowns_num; ++ui)
349 m_sbuffer[i * m_unknowns_num + ui] = m_send_buffer[m_send_info.m_ids[i] * m_unknowns_num + ui];
350 sbuffer = &m_sbuffer[0];
351 }
352 //for(int i=0;i<m_send_info.m_first_upper_neighb;++i)
353 for (int i = m_send_info.m_first_upper_neighb - 1; i > -1; --i) {
354 int off = m_send_info.m_ids_offset[i];
355 int size = m_send_info.m_ids_offset[i + 1] - off;
356 ValueT const* ptr = sbuffer + off * m_unknowns_num;
357 int rank = m_send_info.m_ranks[i];
358 Arccore::MessagePassing::mpSend(m_parallel_mng, ConstArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
359 }
360 }
361
362 void upperSend()
363 {
364 ValueT const* sbuffer = nullptr;
365 if (m_send_info.m_ids.size()) {
366 int offset = m_send_info.m_ids_offset[m_send_info.m_first_upper_neighb] - m_send_info.m_ids_offset[0];
367 int size = m_send_info.m_ids_offset[m_send_info.m_num_neighbours] - m_send_info.m_ids_offset[m_send_info.m_first_upper_neighb];
368 m_sbuffer.resize(size * m_unknowns_num);
369 if (m_unknowns_num == 1)
370 for (int i = 0; i < size; ++i) {
371 m_sbuffer[i] = m_send_buffer[m_send_info.m_ids[offset + i]];
372 }
373 else
374 for (int i = 0; i < size; ++i)
375 for (int ui = 0; ui < m_unknowns_num; ++ui)
376 m_sbuffer[i * m_unknowns_num + ui] = m_send_buffer[m_send_info.m_ids[offset + i] * m_unknowns_num + ui];
377 sbuffer = &m_sbuffer[0];
378 }
379 else
380 sbuffer = m_send_buffer + m_send_info.m_ids_offset[m_send_info.m_first_upper_neighb] * m_unknowns_num;
381 ValueT const* ptr = sbuffer;
382 for (int i = m_send_info.m_first_upper_neighb; i < m_send_info.m_num_neighbours; ++i) {
383 int size = m_send_info.m_ids_offset[i + 1] - m_send_info.m_ids_offset[i];
384 int rank = m_send_info.m_ranks[i];
385 Arccore::MessagePassing::mpSend(m_parallel_mng, ConstArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
386 ptr += size * m_unknowns_num;
387 }
388 }
389
390 private:
391 void _start(bool insitu)
392 {
393 if (m_recv_policy == CommProperty::ASynch) {
394 m_recv_request.resize(m_recv_info.m_num_neighbours);
395 ValueT* rbuffer = nullptr;
396 if (m_recv_info.m_ids.size() && !insitu) {
397 Integer size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours] - m_recv_info.m_ids_offset[0];
398 m_rbuffer.resize(size * m_unknowns_num);
399 rbuffer = &m_rbuffer[0];
400 }
401 else
402 rbuffer = m_recv_buffer;
403 for (Integer i = 0; i < m_recv_info.m_num_neighbours; ++i) {
404 Integer off = m_recv_info.m_ids_offset[i];
405 Integer size = m_recv_info.m_ids_offset[i + 1] - off;
406 ValueT* ptr = rbuffer + off * m_unknowns_num;
407 Integer rank = m_recv_info.m_ranks[i];
408 m_recv_request[i] = Arccore::MessagePassing::mpReceive(
409 m_parallel_mng, ArrayView<ValueT>(size * m_unknowns_num, ptr), rank, false);
410 }
411 }
412 if (m_send_policy == CommProperty::ASynch)
413 m_send_request.resize(m_send_info.m_num_neighbours);
414 ValueT const* sbuffer = m_send_buffer;
415 if (m_send_info.m_ids.size()) {
416 Integer size = m_send_info.m_ids_offset[m_send_info.m_num_neighbours] - m_send_info.m_ids_offset[0];
417 m_sbuffer.resize(size * m_unknowns_num);
418 if (m_unknowns_num == 1)
419 for (Integer i = 0; i < size; ++i) {
420 m_sbuffer[i] = m_send_buffer[m_send_info.m_ids[i]];
421 }
422 else
423 for (Integer i = 0; i < size; ++i)
424 for (Integer ui = 0; ui < m_unknowns_num; ++ui)
425 m_sbuffer[i * m_unknowns_num + ui] =
426 m_send_buffer[m_send_info.m_ids[i] * m_unknowns_num + ui];
427 sbuffer = &m_sbuffer[0];
428 }
429 for (Integer i = 0; i < m_send_info.m_num_neighbours; ++i) {
430 Integer off = m_send_info.m_ids_offset[i];
431 Integer size = m_send_info.m_ids_offset[i + 1] - off;
432 ValueT const* ptr = sbuffer + off * m_unknowns_num;
433 Integer rank = m_send_info.m_ranks[i];
434 if (m_send_policy == CommProperty::ASynch)
435 m_send_request[i] = Arccore::MessagePassing::mpSend(m_parallel_mng,
436 ConstArrayView<ValueT>(size * m_unknowns_num, ptr), rank, false);
437 else
438 Arccore::MessagePassing::mpSend(
439 m_parallel_mng, ConstArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
440 }
441 }
442
443 void _end(bool insitu)
444 {
445 if (m_recv_policy == CommProperty::ASynch)
446 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_recv_request);
447 else {
448 ValueT* rbuffer = m_recv_buffer;
449 if (m_recv_info.m_ids.size() && !insitu) {
450 Arccore::Integer size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours];
451 m_rbuffer.resize(size * m_unknowns_num);
452 rbuffer = &m_rbuffer[0];
453 }
454 for (Integer i = 0; i < m_recv_info.m_num_neighbours; ++i) {
455 Integer off = m_recv_info.m_ids_offset[i];
456 Integer size = m_recv_info.m_ids_offset[i + 1] - off;
457 ValueT* ptr = rbuffer + off * m_unknowns_num;
458 Integer rank = m_recv_info.m_ranks[i];
459 Arccore::MessagePassing::mpReceive(
460 m_parallel_mng, ArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
461 }
462 if (m_recv_info.m_ids.size() && !insitu) {
463 Integer size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours] - m_recv_info.m_ids_offset[0];
464 if (m_unknowns_num == 1)
465 for (Integer i = 0; i < size; ++i)
466 m_recv_buffer[m_recv_info.m_ids[i]] = m_rbuffer[i];
467 else
468 for (Integer i = 0; i < size; ++i)
469 for (Integer ui = 0; ui < m_unknowns_num; ++ui)
470 m_recv_buffer[m_recv_info.m_ids[i] * m_unknowns_num + ui] =
471 m_rbuffer[i * m_unknowns_num + ui];
472 }
473 }
474 if (m_send_policy == CommProperty::ASynch)
475 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_send_request);
476 }
477
478 void _startBlock(bool insitu)
479 {
480 // alien_info([&] {cout() << "StartBlock "<<insitu<<" send pol"<<m_send_policy;});
481
482 if (m_recv_policy == CommProperty::ASynch) {
483 m_recv_request.resize(m_recv_info.m_num_neighbours);
484 ValueT* rbuffer = nullptr;
485 if (m_recv_info.m_ids.size() && !insitu) {
486 Integer size = m_recv_block_ids_offset[m_recv_info.m_num_neighbours] - m_recv_block_ids_offset[0];
487 m_rbuffer.resize(size);
488 rbuffer = &m_rbuffer[0];
489 }
490 else
491 rbuffer = m_recv_buffer;
492 // alien_info([&] {cout() << "RecvInfo Nb Neighb :
493 // "<<m_recv_info.m_num_neighbours;}) ;
494 for (Integer i = 0; i < m_recv_info.m_num_neighbours; ++i) {
495 Integer off = m_recv_block_ids_offset[i];
496 Integer size = m_recv_block_ids_offset[i + 1] - off;
497 ValueT* ptr = rbuffer + off;
498 Integer rank = m_recv_info.m_ranks[i];
499 m_recv_request[i] = Arccore::MessagePassing::mpReceive(
500 m_parallel_mng, ArrayView<ValueT>(size, ptr), rank, false);
501 }
502 }
503 if (m_send_policy == CommProperty::ASynch)
504 m_send_request.resize(m_send_info.m_num_neighbours);
505 ValueT const* sbuffer = m_send_buffer;
506 if (m_send_info.m_ids.size()) {
507 {
508 Integer size = m_send_block_ids_offset[m_send_info.m_num_neighbours] - m_send_block_ids_offset[0];
509 m_sbuffer.resize(size);
510 }
511 Integer size = m_send_info.m_ids_offset[m_send_info.m_num_neighbours] - m_send_info.m_ids_offset[0];
512 Integer offset = 0;
513 for (Integer i = 0; i < size; ++i) {
514 Integer id = m_send_info.m_ids[i];
515 Integer block_size = m_block_sizes[id];
516 Integer block_offset = m_block_offsets[id];
517 for (Integer ui = 0; ui < block_size; ++ui)
518 m_sbuffer[offset + ui] = m_send_buffer[block_offset + ui];
519 offset += block_size;
520 }
521 // ARCANE_ASSERT((offset ==
522 // m_send_info.m_block_ids_offset[m_send_info.m_num_neighbours] -
523 // m_send_info.m_block_ids_offset[0]),("size error"));
524 sbuffer = &m_sbuffer[0];
525 }
526 for (Integer i = 0; i < m_send_info.m_num_neighbours; ++i) {
527 Integer off = m_send_block_ids_offset[i];
528 Integer size = m_send_block_ids_offset[i + 1] - off;
529 ValueT const* ptr = sbuffer + off;
530 Integer rank = m_send_info.m_ranks[i];
531 if (m_send_policy == CommProperty::ASynch)
532 m_send_request[i] = Arccore::MessagePassing::mpSend(
533 m_parallel_mng, ConstArrayView<ValueT>(size, ptr), rank, false);
534 else
535 Arccore::MessagePassing::mpSend(
536 m_parallel_mng, ConstArrayView<ValueT>(size, ptr), rank);
537 }
538 }
539
540 void _endBlock(bool insitu)
541 {
542 // alien_info([&] {cout() << "EndBlock "<<insitu<<" recv pol="<<m_recv_policy;});
543 if (m_recv_policy == CommProperty::ASynch) {
544 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_recv_request);
545 }
546 else {
547 ValueT* rbuffer = m_recv_buffer;
548 if (m_recv_info.m_ids.size() && !insitu) {
549 Arccore::Integer size =
550 m_recv_block_ids_offset[m_recv_info.m_num_neighbours];
551 m_rbuffer.resize(size);
552 rbuffer = &m_rbuffer[0];
553 }
554 for (Integer i = 0; i < m_recv_info.m_num_neighbours; ++i) {
555 Integer off = m_recv_block_ids_offset[i];
556 Integer size = m_recv_block_ids_offset[i + 1] - off;
557 ValueT* ptr = rbuffer + off;
558 Integer rank = m_recv_info.m_ranks[i];
559 Arccore::MessagePassing::mpReceive(
560 m_parallel_mng, ArrayView<ValueT>(size, ptr), rank);
561 }
562 if (m_recv_info.m_ids.size() && !insitu) {
563 Arccore::Integer size = m_recv_info.m_ids_offset[m_recv_info.m_num_neighbours] - m_recv_info.m_ids_offset[0];
564 Integer offset = 0;
565 for (Integer i = 0; i < size; ++i) {
566 Integer id = m_recv_info.m_ids[i];
567 Integer block_size = m_block_sizes[id];
568 Integer block_offset = m_block_offsets[id];
569 for (Integer ui = 0; ui < block_size; ++ui)
570 m_recv_buffer[block_offset + ui] = m_rbuffer[offset + ui];
571 offset += block_size;
572 }
573 // ARCANE_ASSERT((offset =
574 // m_recv_info.m_block_ids_offset[m_recv_info.m_num_neighbours] -
575 // m_recv_info.m_block_ids_offset[0]),("size error"));
576 }
577 }
578 if (m_send_policy == CommProperty::ASynch)
579 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_send_request);
580 }
581
582 private:
583 const bool m_is_variable_block = false;
584 const ValueT* m_send_buffer = nullptr;
585 const CommInfo& m_send_info;
586 CommProperty::ePolicyType m_send_policy;
587 ValueT* m_recv_buffer = nullptr;
588 const CommInfo& m_recv_info;
589 CommProperty::ePolicyType m_recv_policy;
590 Arccore::MessagePassing::IMessagePassingMng* m_parallel_mng = nullptr;
591 Arccore::ITraceMng* m_trace = nullptr;
592 Arccore::Integer m_unknowns_num = 0;
593 std::vector<ValueT> m_rbuffer;
594 std::vector<ValueT> m_sbuffer;
595 Arccore::UniqueArray<Arccore::MessagePassing::Request> m_recv_request;
596 Arccore::UniqueArray<Arccore::MessagePassing::Request> m_send_request;
597 Arccore::ConstArrayView<Arccore::Integer> m_block_sizes;
598 Arccore::ConstArrayView<Arccore::Integer> m_block_offsets;
599 Arccore::ConstArrayView<Arccore::Integer> m_send_block_ids_offset;
600 Arccore::ConstArrayView<Arccore::Integer> m_recv_block_ids_offset;
601};
602
603} // namespace Alien::SimpleCSRInternal