149class SendRecvOp :
public IASynchOp
152 SendRecvOp(
const ValueT* send_buffer,
154 CommProperty::ePolicyType send_policy,
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)
170 , m_unknowns_num(unknowns_num)
173 SendRecvOp(
const ValueT* send_buffer,
175 CommProperty::ePolicyType send_policy,
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)
193 , m_block_sizes(block_sizes)
194 , m_block_offsets(block_offsets)
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;
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;
205 void start(
bool insitu =
true)
207 if (m_is_variable_block)
213 void end(
bool insitu =
true)
215 if (m_is_variable_block)
221 void recv(
bool insitu =
true)
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];
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);
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];
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];
249 void lowerRecv(
bool insitu =
true)
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];
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);
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];
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];
277 void upperRecv(
bool insitu =
true)
279 ValueT* rbuffer = m_recv_buffer;
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];
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);
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];
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];
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]];
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];
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);
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]];
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];
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);
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]];
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];
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;
391 void _start(
bool insitu)
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];
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);
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]];
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];
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);
438 Arccore::MessagePassing::mpSend(
439 m_parallel_mng, ConstArrayView<ValueT>(size * m_unknowns_num, ptr), rank);
443 void _end(
bool insitu)
445 if (m_recv_policy == CommProperty::ASynch)
446 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_recv_request);
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];
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);
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];
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];
474 if (m_send_policy == CommProperty::ASynch)
475 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_send_request);
478 void _startBlock(
bool insitu)
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];
491 rbuffer = m_recv_buffer;
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);
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()) {
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);
511 Integer size = m_send_info.m_ids_offset[m_send_info.m_num_neighbours] - m_send_info.m_ids_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;
524 sbuffer = &m_sbuffer[0];
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);
535 Arccore::MessagePassing::mpSend(
536 m_parallel_mng, ConstArrayView<ValueT>(size, ptr), rank);
540 void _endBlock(
bool insitu)
543 if (m_recv_policy == CommProperty::ASynch) {
544 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_recv_request);
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];
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);
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];
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;
578 if (m_send_policy == CommProperty::ASynch)
579 Arccore::MessagePassing::mpWaitAll(m_parallel_mng, m_send_request);
583 const bool m_is_variable_block =
false;
584 const ValueT* m_send_buffer =
nullptr;
586 CommProperty::ePolicyType m_send_policy;
587 ValueT* m_recv_buffer =
nullptr;
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;