14#include "arccore/message_passing_mpi/internal/MpiAdapter.h"
16#include "arccore/trace/ITraceMng.h"
18#include "arccore/collections/Array.h"
20#include "arccore/message_passing/Request.h"
21#include "arccore/message_passing/IStat.h"
22#include "arccore/message_passing/internal/SubRequestCompletionInfo.h"
24#include "arccore/base/IStackTraceService.h"
25#include "arccore/base/TimeoutException.h"
26#include "arccore/base/String.h"
27#include "arccore/base/NotImplementedException.h"
28#include "arccore/base/PlatformUtils.h"
29#include "arccore/base/FatalErrorException.h"
30#include "arccore/base/TraceInfo.h"
32#include "arccore/message_passing_mpi/StandaloneMpiMessagePassingMng.h"
33#include "arccore/message_passing_mpi/internal/MpiLock.h"
34#include "arccore/message_passing_mpi/internal/NoMpiProfiling.h"
35#include "arccore/message_passing_mpi/internal/MpiRequest.h"
36#include "arccore/message_passing_mpi/internal/MpiMachineShMemWinBaseInternalCreator.h"
43namespace Arcane::MessagePassing::Mpi
62 typedef std::map<MPI_Request, RequestInfo>::iterator Iterator;
72 m_request_error_is_fatal =
true;
75 m_is_report_error_in_request =
false;
77 m_use_trace_full_stack =
true;
79 m_trace_mpirequest =
true;
84 void addRequest(MPI_Request request)
88 if (m_trace_mpirequest)
89 info() <<
"MpiAdapter: AddRequest r=" << request;
92 void addRequest(MPI_Request request,
const TraceInfo& ti)
96 if (m_trace_mpirequest)
97 info() <<
"MpiAdapter: AddRequest r=" << request;
98 _addRequest(request, ti);
100 void removeRequest(MPI_Request request)
104 if (m_trace_mpirequest)
105 info() <<
"MpiAdapter: RemoveRequest r=" << request;
106 _removeRequest(request);
108 void removeRequest(Iterator request_iter)
112 if (request_iter == m_allocated_requests.end()) {
113 if (m_trace_mpirequest)
114 info() <<
"MpiAdapter: RemoveRequestIter null iterator";
117 if (m_trace_mpirequest)
118 info() <<
"MpiAdapter: RemoveRequestIter r=" << request_iter->first;
119 m_allocated_requests.erase(request_iter);
125 return m_allocated_requests.end();
127 if (_isEmptyRequest(request))
128 return m_allocated_requests.end();
129 auto ireq = m_allocated_requests.find(request);
130 if (ireq == m_allocated_requests.end()) {
131 if (m_is_report_error_in_request || m_request_error_is_fatal) {
132 error() <<
"MpiAdapter::testRequest() request not referenced "
133 <<
" id=" << request;
134 _checkFatalInRequest();
145 void _addRequest(MPI_Request request,
const TraceInfo& trace_info)
147 if (request == MPI_REQUEST_NULL) {
148 if (m_is_report_error_in_request || m_request_error_is_fatal) {
149 error() <<
"MpiAdapter::_addRequest() trying to add null request";
150 _checkFatalInRequest();
154 if (_isEmptyRequest(request))
156 ++m_total_added_request;
158 auto i = m_allocated_requests.find(request);
159 if (i != m_allocated_requests.end()) {
160 if (m_is_report_error_in_request || m_request_error_is_fatal) {
161 error() <<
"MpiAdapter::_addRequest() request already referenced "
162 <<
" id=" << request;
163 _checkFatalInRequest();
168 rinfo.m_trace = trace_info;
169 if (m_use_trace_full_stack)
171 m_allocated_requests.insert(std::make_pair(request, rinfo));
177 void _removeRequest(MPI_Request request)
180 if (request == MPI_REQUEST_NULL) {
181 if (m_is_report_error_in_request || m_request_error_is_fatal) {
182 error() <<
"MpiAdapter::_removeRequest() null request (" << MPI_REQUEST_NULL <<
")";
183 _checkFatalInRequest();
187 if (_isEmptyRequest(request))
189 auto i = m_allocated_requests.find(request);
190 if (i == m_allocated_requests.end()) {
191 if (m_is_report_error_in_request || m_request_error_is_fatal) {
192 error() <<
"MpiAdapter::_removeRequest() request not referenced "
193 <<
" id=" << request;
194 _checkFatalInRequest();
198 m_allocated_requests.erase(i);
203 void _checkFatalInRequest()
205 if (m_request_error_is_fatal)
208 Int64 nbRequest()
const {
return m_allocated_requests.size(); }
209 Int64 totalAddedRequest()
const {
return m_total_added_request; }
210 void printRequests()
const
212 info() <<
"PRINT REQUESTS\n";
213 for (
auto& x : m_allocated_requests) {
214 info() <<
"Request id=" << x.first <<
" trace=" << x.second.m_trace
215 <<
" stack=" << x.second.m_stack_trace;
218 void setEmptyRequests(MPI_Request r1, MPI_Request r2)
220 m_empty_request1 = r1;
221 m_empty_request2 = r2;
226 bool m_request_error_is_fatal =
false;
227 bool m_is_report_error_in_request =
true;
228 bool m_trace_mpirequest =
false;
234 std::map<MPI_Request, RequestInfo> m_allocated_requests;
235 bool m_use_trace_full_stack =
false;
236 MPI_Request m_empty_request1 = MPI_REQUEST_NULL;
237 MPI_Request m_empty_request2 = MPI_REQUEST_NULL;
238 Int64 m_total_added_request = 0;
243 bool _isEmptyRequest(MPI_Request r)
const
245 return (r == m_empty_request1 || r == m_empty_request2);
249#define ARCCORE_ADD_REQUEST(request) \
250 m_request_set->addRequest(request, A_FUNCINFO);
257 int _checkSize(
Int64 i64_size)
259 if (i64_size > INT32_MAX)
260 ARCCORE_FATAL(
"Can not convert '{0}' to type integer", i64_size);
261 return (
int)i64_size;
270 MpiLock* mpi_lock, IMpiProfiling* mpi_op)
273, m_mpi_lock(mpi_lock)
275, m_communicator(comm)
278, m_empty_request1(MPI_REQUEST_NULL)
279, m_empty_request2(MPI_REQUEST_NULL)
281 m_request_set =
new RequestSet(trace);
287 if (s ==
"1" || s ==
"TRUE")
288 m_is_allow_null_rank_for_any_source =
true;
289 if (s ==
"0" || s ==
"FALSE")
290 m_is_allow_null_rank_for_any_source =
false;
293 ::MPI_Comm_rank(m_communicator, &m_comm_rank);
294 ::MPI_Comm_size(m_communicator, &m_comm_size);
299 m_mpi_prof =
new NoMpiProfiling();
311 MPI_Irecv(m_recv_buffer_for_empty_request, 1, MPI_CHAR, MPI_PROC_NULL,
312 50505, m_communicator, &m_empty_request1);
321 m_send_buffer_for_empty_request2[0] = 0;
322 MPI_Isend(m_send_buffer_for_empty_request2, 1, MPI_CHAR, m_comm_rank,
323 50505, m_communicator, &m_empty_request2);
325 MPI_Recv(m_recv_buffer_for_empty_request2, 1, MPI_CHAR, m_comm_rank,
326 50505, m_communicator, MPI_STATUS_IGNORE);
328 m_request_set->setEmptyRequests(m_empty_request1, m_empty_request2);
337 if (m_empty_request1 != MPI_REQUEST_NULL)
338 MPI_Request_free(&m_empty_request1);
339 if (m_empty_request2 != MPI_REQUEST_NULL)
340 MPI_Request_free(&m_empty_request2);
342 delete m_request_set;
350buildRequest(
int ret, MPI_Request mpi_request)
352 return MpiRequest(ret,
this, mpi_request);
361 Int64 nb_request = m_request_set->nbRequest();
364 if (nb_request != 0) {
365 warning() <<
" Pending mpi requests size=" << nb_request;
366 m_request_set->printRequests();
367 _checkFatalInRequest();
377 _checkHasNoRequests();
385setRequestErrorAreFatal(
bool v)
387 m_request_set->m_request_error_is_fatal = v;
390isRequestErrorAreFatal()
const
392 return m_request_set->m_request_error_is_fatal;
396setPrintRequestError(
bool v)
398 m_request_set->m_is_report_error_in_request = v;
401isPrintRequestError()
const
403 return m_request_set->m_is_report_error_in_request;
407setCheckRequest(
bool v)
409 m_request_set->m_no_check_request = !v;
413isCheckRequest()
const
415 return !m_request_set->m_no_check_request;
422toMPISize(
Int64 count)
424 return _checkSize(count);
431_trace(
const char* function)
436 info() <<
"MPI_TRACE: " << function <<
"\n"
437 << stack_service->stackTrace().toString();
439 info() <<
"MPI_TRACE: " << function;
447broadcast(
void* buf,
Int64 nb_elem,
Int32 root, MPI_Datatype datatype)
449 int _nb_elem = _checkSize(nb_elem);
450 _trace(MpiInfo(eMpiName::Bcast).name().localstr());
451 double begin_time = MPI_Wtime();
453 info() <<
"MPI_TRACE: MPI broadcast: before"
455 <<
" nb_elem=" << nb_elem
457 <<
" datatype=" << datatype;
459 m_mpi_prof->broadcast(buf, _nb_elem, datatype, root, m_communicator);
460 double end_time = MPI_Wtime();
461 double sr_time = (end_time - begin_time);
463 m_stat->add(MpiInfo(eMpiName::Bcast).name(), sr_time, 0);
470nonBlockingBroadcast(
void* buf,
Int64 nb_elem,
Int32 root, MPI_Datatype datatype)
472 MPI_Request mpi_request = MPI_REQUEST_NULL;
474 int _nb_elem = _checkSize(nb_elem);
475 _trace(
" MPI_Bcast");
476 double begin_time = MPI_Wtime();
477 ret = MPI_Ibcast(buf, _nb_elem, datatype, root, m_communicator, &mpi_request);
478 double end_time = MPI_Wtime();
479 double sr_time = (end_time - begin_time);
481 m_stat->add(
"IBroadcast", sr_time, 0);
482 ARCCORE_ADD_REQUEST(mpi_request);
483 return buildRequest(ret, mpi_request);
490gather(
const void* send_buf,
void* recv_buf,
Int64 nb_elem,
Int32 root, MPI_Datatype datatype)
492 void* _sbuf =
const_cast<void*
>(send_buf);
493 int _nb_elem = _checkSize(nb_elem);
494 int _root =
static_cast<int>(root);
495 _trace(MpiInfo(eMpiName::Gather).name().localstr());
496 double begin_time = MPI_Wtime();
497 m_mpi_prof->gather(_sbuf, _nb_elem, datatype, recv_buf, _nb_elem, datatype, _root, m_communicator);
498 double end_time = MPI_Wtime();
499 double sr_time = (end_time - begin_time);
501 m_stat->add(MpiInfo(eMpiName::Gather).name(), sr_time, 0);
508nonBlockingGather(
const void* send_buf,
void* recv_buf,
509 Int64 nb_elem,
Int32 root, MPI_Datatype datatype)
511 MPI_Request mpi_request = MPI_REQUEST_NULL;
513 void* _sbuf =
const_cast<void*
>(send_buf);
514 int _nb_elem = _checkSize(nb_elem);
515 int _root =
static_cast<int>(root);
516 _trace(
"MPI_Igather");
517 double begin_time = MPI_Wtime();
518 ret = MPI_Igather(_sbuf, _nb_elem, datatype, recv_buf, _nb_elem, datatype, _root,
519 m_communicator, &mpi_request);
520 double end_time = MPI_Wtime();
521 double sr_time = (end_time - begin_time);
523 m_stat->add(
"IGather", sr_time, 0);
524 ARCCORE_ADD_REQUEST(mpi_request);
525 return buildRequest(ret, mpi_request);
532allGather(
const void* send_buf,
void* recv_buf,
533 Int64 nb_elem, MPI_Datatype datatype)
535 void* _sbuf =
const_cast<void*
>(send_buf);
536 int _nb_elem = _checkSize(nb_elem);
537 _trace(MpiInfo(eMpiName::Allgather).name().localstr());
538 double begin_time = MPI_Wtime();
539 m_mpi_prof->allGather(_sbuf, _nb_elem, datatype, recv_buf, _nb_elem, datatype, m_communicator);
540 double end_time = MPI_Wtime();
541 double sr_time = (end_time - begin_time);
543 m_stat->add(MpiInfo(eMpiName::Allgather).name(), sr_time, 0);
550nonBlockingAllGather(
const void* send_buf,
void* recv_buf,
551 Int64 nb_elem, MPI_Datatype datatype)
553 MPI_Request mpi_request = MPI_REQUEST_NULL;
555 void* _sbuf =
const_cast<void*
>(send_buf);
556 int _nb_elem = _checkSize(nb_elem);
557 _trace(
"MPI_Iallgather");
558 double begin_time = MPI_Wtime();
559 ret = MPI_Iallgather(_sbuf, _nb_elem, datatype, recv_buf, _nb_elem, datatype,
560 m_communicator, &mpi_request);
561 double end_time = MPI_Wtime();
562 double sr_time = (end_time - begin_time);
564 m_stat->add(
"IAllGather", sr_time, 0);
565 ARCCORE_ADD_REQUEST(mpi_request);
566 return buildRequest(ret, mpi_request);
573gatherVariable(
const void* send_buf,
void* recv_buf,
const int* recv_counts,
574 const int* recv_indexes,
Int64 nb_elem,
Int32 root, MPI_Datatype datatype)
576 void* _sbuf =
const_cast<void*
>(send_buf);
577 int _nb_elem = _checkSize(nb_elem);
578 int _root =
static_cast<int>(root);
579 _trace(MpiInfo(eMpiName::Gatherv).name().localstr());
580 double begin_time = MPI_Wtime();
581 m_mpi_prof->gatherVariable(_sbuf, _nb_elem, datatype, recv_buf, recv_counts, recv_indexes, datatype, _root, m_communicator);
582 double end_time = MPI_Wtime();
583 double sr_time = (end_time - begin_time);
585 m_stat->add(MpiInfo(eMpiName::Gatherv).name().localstr(), sr_time, 0);
592allGatherVariable(
const void* send_buf,
void* recv_buf,
const int* recv_counts,
593 const int* recv_indexes,
Int64 nb_elem, MPI_Datatype datatype)
595 void* _sbuf =
const_cast<void*
>(send_buf);
596 int _nb_elem = _checkSize(nb_elem);
597 _trace(MpiInfo(eMpiName::Allgatherv).name().localstr());
602 double begin_time = MPI_Wtime();
603 m_mpi_prof->allGatherVariable(_sbuf, _nb_elem, datatype, recv_buf, recv_counts, recv_indexes, datatype, m_communicator);
604 double end_time = MPI_Wtime();
605 double sr_time = (end_time - begin_time);
607 m_stat->add(MpiInfo(eMpiName::Allgatherv).name().localstr(), sr_time, 0);
614scatterVariable(
const void* send_buf,
const int* send_count,
const int* send_indexes,
615 void* recv_buf,
Int64 nb_elem,
Int32 root, MPI_Datatype datatype)
617 void* _sbuf =
const_cast<void*
>(send_buf);
618 int* _send_count =
const_cast<int*
>(send_count);
619 int* _send_indexes =
const_cast<int*
>(send_indexes);
620 int _nb_elem = _checkSize(nb_elem);
621 _trace(MpiInfo(eMpiName::Scatterv).name().localstr());
622 double begin_time = MPI_Wtime();
623 m_mpi_prof->scatterVariable(_sbuf,
632 double end_time = MPI_Wtime();
633 double sr_time = (end_time - begin_time);
635 m_stat->add(MpiInfo(eMpiName::Scatterv).name(), sr_time, 0);
642allToAll(
const void* send_buf,
void* recv_buf,
Integer count, MPI_Datatype datatype)
644 void* _sbuf =
const_cast<void*
>(send_buf);
645 int icount = _checkSize(count);
646 _trace(MpiInfo(eMpiName::Alltoall).name().localstr());
647 double begin_time = MPI_Wtime();
648 m_mpi_prof->allToAll(_sbuf, icount, datatype, recv_buf, icount, datatype, m_communicator);
649 double end_time = MPI_Wtime();
650 double sr_time = (end_time - begin_time);
652 m_stat->add(MpiInfo(eMpiName::Alltoall).name().localstr(), sr_time, 0);
659nonBlockingAllToAll(
const void* send_buf,
void* recv_buf,
Integer count, MPI_Datatype datatype)
661 MPI_Request mpi_request = MPI_REQUEST_NULL;
663 void* _sbuf =
const_cast<void*
>(send_buf);
664 int icount = _checkSize(count);
665 _trace(
"MPI_IAlltoall");
666 double begin_time = MPI_Wtime();
667 ret = MPI_Ialltoall(_sbuf, icount, datatype, recv_buf, icount, datatype, m_communicator, &mpi_request);
668 double end_time = MPI_Wtime();
669 double sr_time = (end_time - begin_time);
671 m_stat->add(
"IAllToAll", sr_time, 0);
672 ARCCORE_ADD_REQUEST(mpi_request);
673 return buildRequest(ret, mpi_request);
680allToAllVariable(
const void* send_buf,
const int* send_counts,
681 const int* send_indexes,
void* recv_buf,
const int* recv_counts,
682 const int* recv_indexes, MPI_Datatype datatype)
684 void* _sbuf =
const_cast<void*
>(send_buf);
685 int* _send_counts =
const_cast<int*
>(send_counts);
686 int* _send_indexes =
const_cast<int*
>(send_indexes);
687 int* _recv_counts =
const_cast<int*
>(recv_counts);
688 int* _recv_indexes =
const_cast<int*
>(recv_indexes);
690 _trace(MpiInfo(eMpiName::Alltoallv).name().localstr());
691 double begin_time = MPI_Wtime();
692 m_mpi_prof->allToAllVariable(_sbuf, _send_counts, _send_indexes, datatype,
693 recv_buf, _recv_counts, _recv_indexes, datatype, m_communicator);
694 double end_time = MPI_Wtime();
695 double sr_time = (end_time - begin_time);
697 m_stat->add(MpiInfo(eMpiName::Alltoallv).name(), sr_time, 0);
704nonBlockingAllToAllVariable(
const void* send_buf,
const int* send_counts,
705 const int* send_indexes,
void* recv_buf,
const int* recv_counts,
706 const int* recv_indexes, MPI_Datatype datatype)
708 MPI_Request mpi_request = MPI_REQUEST_NULL;
710 void* _sbuf =
const_cast<void*
>(send_buf);
711 int* _send_counts =
const_cast<int*
>(send_counts);
712 int* _send_indexes =
const_cast<int*
>(send_indexes);
713 int* _recv_counts =
const_cast<int*
>(recv_counts);
714 int* _recv_indexes =
const_cast<int*
>(recv_indexes);
716 _trace(
"MPI_Ialltoallv");
717 double begin_time = MPI_Wtime();
718 ret = MPI_Ialltoallv(_sbuf, _send_counts, _send_indexes, datatype,
719 recv_buf, _recv_counts, _recv_indexes, datatype,
720 m_communicator, &mpi_request);
721 double end_time = MPI_Wtime();
722 double sr_time = (end_time - begin_time);
724 m_stat->add(
"IAllToAll", sr_time, 0);
725 ARCCORE_ADD_REQUEST(mpi_request);
726 return buildRequest(ret, mpi_request);
739 MPI_Barrier(m_communicator);
748 MPI_Request mpi_request = MPI_REQUEST_NULL;
750 ret = MPI_Ibarrier(m_communicator, &mpi_request);
751 ARCCORE_ADD_REQUEST(mpi_request);
752 return buildRequest(ret, mpi_request);
759allReduce(
const void* send_buf,
void* recv_buf,
Int64 count, MPI_Datatype datatype, MPI_Op op)
761 void* _sbuf =
const_cast<void*
>(send_buf);
762 int _n = _checkSize(count);
763 double begin_time = MPI_Wtime();
764 _trace(MpiInfo(eMpiName::Allreduce).name().localstr());
767 m_mpi_prof->allReduce(_sbuf, recv_buf, _n, datatype, op, m_communicator);
769 catch (TimeoutException& ex) {
770 std::ostringstream ostr;
771 ostr <<
"MPI_Allreduce"
772 <<
" send_buf=" << send_buf
773 <<
" recv_buf=" << recv_buf
775 <<
" datatype=" << datatype
777 <<
" NB=" << m_nb_all_reduce;
778 ex.setAdditionalInfo(ostr.str());
781 double end_time = MPI_Wtime();
782 m_stat->add(MpiInfo(eMpiName::Allreduce).name(), end_time - begin_time, count);
789nonBlockingAllReduce(
const void* send_buf,
void* recv_buf,
Int64 count, MPI_Datatype datatype, MPI_Op op)
791 MPI_Request mpi_request = MPI_REQUEST_NULL;
793 void* _sbuf =
const_cast<void*
>(send_buf);
794 int _n = _checkSize(count);
795 double begin_time = MPI_Wtime();
796 _trace(
"MPI_IAllreduce");
797 ret = MPI_Iallreduce(_sbuf, recv_buf, _n, datatype, op, m_communicator, &mpi_request);
798 double end_time = MPI_Wtime();
799 m_stat->add(
"IReduce", end_time - begin_time, _n);
800 ARCCORE_ADD_REQUEST(mpi_request);
801 return buildRequest(ret, mpi_request);
808reduce(
const void* send_buf,
void* recv_buf,
Int64 count, MPI_Datatype datatype, MPI_Op op,
Integer root)
810 void* _sbuf =
const_cast<void*
>(send_buf);
811 int _n = _checkSize(count);
812 int _root =
static_cast<int>(root);
813 double begin_time = MPI_Wtime();
814 _trace(MpiInfo(eMpiName::Reduce).name().localstr());
817 m_mpi_prof->reduce(_sbuf, recv_buf, _n, datatype, op, _root, m_communicator);
819 catch (TimeoutException& ex) {
820 std::ostringstream ostr;
822 <<
" send_buf=" << send_buf
823 <<
" recv_buf=" << recv_buf
825 <<
" datatype=" << datatype
828 <<
" NB=" << m_nb_reduce;
829 ex.setAdditionalInfo(ostr.str());
833 double end_time = MPI_Wtime();
834 m_stat->add(MpiInfo(eMpiName::Reduce).name(), end_time - begin_time, 0);
841scan(
const void* send_buf,
void* recv_buf,
Int64 count, MPI_Datatype datatype, MPI_Op op)
843 void* _sbuf =
const_cast<void*
>(send_buf);
844 int _n = _checkSize(count);
845 double begin_time = MPI_Wtime();
846 _trace(MpiInfo(eMpiName::Scan).name().localstr());
847 m_mpi_prof->scan(_sbuf, recv_buf, _n, datatype, op, m_communicator);
848 double end_time = MPI_Wtime();
849 m_stat->add(MpiInfo(eMpiName::Scan).name(), end_time - begin_time, count);
856directSendRecv(
const void* send_buffer,
Int64 send_buffer_size,
857 void* recv_buffer,
Int64 recv_buffer_size,
858 Int32 proc,
Int64 elem_size, MPI_Datatype data_type)
860 void* v_send_buffer =
const_cast<void*
>(send_buffer);
861 MPI_Status mpi_status;
862 double begin_time = MPI_Wtime();
863 _trace(MpiInfo(eMpiName::Sendrecv).name().localstr());
864 int sbuf_size = _checkSize(send_buffer_size);
865 int rbuf_size = _checkSize(recv_buffer_size);
866 m_mpi_prof->sendRecv(v_send_buffer, sbuf_size, data_type, proc, 99,
867 recv_buffer, rbuf_size, data_type, proc, 99,
868 m_communicator, &mpi_status);
869 double end_time = MPI_Wtime();
870 Int64 send_size = send_buffer_size * elem_size;
871 Int64 recv_size = recv_buffer_size * elem_size;
872 double sr_time = (end_time - begin_time);
876 m_stat->add(MpiInfo(eMpiName::Sendrecv).name(), sr_time, send_size + recv_size);
883sendNonBlockingNoStat(
const void* send_buffer,
Int64 send_buffer_size,
884 Int32 dest_rank, MPI_Datatype data_type,
int mpi_tag)
886 void* v_send_buffer =
const_cast<void*
>(send_buffer);
887 MPI_Request mpi_request = MPI_REQUEST_NULL;
888 int sbuf_size = _checkSize(send_buffer_size);
890 m_mpi_prof->iSend(v_send_buffer, sbuf_size, data_type, dest_rank, mpi_tag, m_communicator, &mpi_request);
892 info() <<
" ISend ret=" << ret <<
" proc=" << dest_rank <<
" tag=" << mpi_tag <<
" request=" << mpi_request;
893 ARCCORE_ADD_REQUEST(mpi_request);
894 return buildRequest(ret, mpi_request);
901directSend(
const void* send_buffer,
Int64 send_buffer_size,
902 Int32 proc,
Int64 elem_size, MPI_Datatype data_type,
903 int mpi_tag,
bool is_blocked)
905 void* v_send_buffer =
const_cast<void*
>(send_buffer);
906 MPI_Request mpi_request = MPI_REQUEST_NULL;
908 double begin_time = 0.0;
909 double end_time = 0.0;
910 Int64 send_size = send_buffer_size * elem_size;
913 info() <<
"MPI_TRACE: MPI Send: send before"
914 <<
" size=" << send_size
916 <<
" tag=" << mpi_tag
917 <<
" datatype=" << data_type
918 <<
" blocking " << is_blocked;
926 MpiLock::Section mls(m_mpi_lock);
927 begin_time = MPI_Wtime();
928 int sbuf_size = _checkSize(send_buffer_size);
929 m_mpi_prof->iSend(v_send_buffer, sbuf_size, data_type, proc, mpi_tag, m_communicator, &mpi_request);
932 MPI_Status mpi_status;
933 while (is_finished == 0) {
934 MpiLock::Section mls(m_mpi_lock);
935 MPI_Request_get_status(mpi_request, &is_finished, &mpi_status);
936 if (is_finished != 0) {
937 m_mpi_prof->wait(&mpi_request, (MPI_Status*)MPI_STATUS_IGNORE);
938 end_time = MPI_Wtime();
939 mpi_request = MPI_REQUEST_NULL;
944 MpiLock::Section mls(m_mpi_lock);
945 begin_time = MPI_Wtime();
946 int sbuf_size = _checkSize(send_buffer_size);
947 m_mpi_prof->send(v_send_buffer, sbuf_size, data_type, proc, mpi_tag, m_communicator);
948 end_time = MPI_Wtime();
953 MpiLock::Section mls(m_mpi_lock);
954 begin_time = MPI_Wtime();
955 int sbuf_size = _checkSize(send_buffer_size);
956 m_mpi_prof->iSend(v_send_buffer, sbuf_size, data_type, proc, mpi_tag, m_communicator, &mpi_request);
958 info() <<
" ISend ret=" << ret <<
" proc=" << proc <<
" tag=" << mpi_tag <<
" request=" << mpi_request;
959 end_time = MPI_Wtime();
960 ARCCORE_ADD_REQUEST(mpi_request);
963 info() <<
"MPI Send: send after"
964 <<
" request=" << mpi_request;
967 double sr_time = (end_time - begin_time);
969 debug(
Trace::High) <<
"MPI Send: send " << send_size
970 <<
" time " << sr_time <<
" blocking " << is_blocked;
972 m_stat->add(MpiInfo(eMpiName::Send).name(), end_time - begin_time, send_size);
973 return buildRequest(ret, mpi_request);
980directSendPack(
const void* send_buffer,
Int64 send_buffer_size,
981 Int32 proc,
int mpi_tag,
bool is_blocked)
983 return directSend(send_buffer, send_buffer_size, proc, 1, MPI_PACKED, mpi_tag, is_blocked);
989MpiMessagePassingMng* MpiAdapter::
994 MPI_Comm_split(m_communicator, (keep) ? 1 : MPI_UNDEFINED, commRank(), &new_comm);
1006receiveNonBlockingNoStat(
void* recv_buffer,
Int64 recv_buffer_size,
1007 Int32 source_rank, MPI_Datatype data_type,
int mpi_tag)
1009 int rbuf_size = _checkSize(recv_buffer_size);
1011 MPI_Request mpi_request = MPI_REQUEST_NULL;
1012 m_mpi_prof->iRecv(recv_buffer, rbuf_size, data_type, source_rank, mpi_tag, m_communicator, &mpi_request);
1013 ARCCORE_ADD_REQUEST(mpi_request);
1014 return buildRequest(ret, mpi_request);
1021directRecv(
void* recv_buffer,
Int64 recv_buffer_size,
1022 Int32 proc,
Int64 elem_size, MPI_Datatype data_type,
1023 int mpi_tag,
bool is_blocked)
1025 MPI_Status mpi_status;
1026 MPI_Request mpi_request = MPI_REQUEST_NULL;
1028 double begin_time = 0.0;
1029 double end_time = 0.0;
1032 if (proc == A_PROC_NULL_RANK)
1033 ARCCORE_THROW(NotImplementedException,
"Receive with MPI_PROC_NULL");
1034 if (proc == A_NULL_RANK && !m_is_allow_null_rank_for_any_source)
1035 ARCCORE_FATAL(
"Can not use A_NULL_RANK for any source. Use A_ANY_SOURCE_RANK instead");
1036 if (proc == A_NULL_RANK || proc == A_ANY_SOURCE_RANK)
1037 i_proc = MPI_ANY_SOURCE;
1039 i_proc =
static_cast<int>(proc);
1041 Int64 recv_size = recv_buffer_size * elem_size;
1043 info() <<
"MPI_TRACE: MPI Recv: recv before "
1044 <<
" size=" << recv_size
1045 <<
" from=" << i_proc
1046 <<
" tag=" << mpi_tag
1047 <<
" datatype=" << data_type
1048 <<
" blocking=" << is_blocked;
1057 MpiLock::Section mls(m_mpi_lock);
1058 begin_time = MPI_Wtime();
1059 int rbuf_size = _checkSize(recv_buffer_size);
1060 m_mpi_prof->iRecv(recv_buffer, rbuf_size, data_type, i_proc, mpi_tag, m_communicator, &mpi_request);
1062 int is_finished = 0;
1063 MPI_Status mpi_status;
1064 while (is_finished == 0) {
1065 MpiLock::Section mls(m_mpi_lock);
1066 MPI_Request_get_status(mpi_request, &is_finished, &mpi_status);
1067 if (is_finished != 0) {
1068 end_time = MPI_Wtime();
1069 m_mpi_prof->wait(&mpi_request, (MPI_Status*)MPI_STATUS_IGNORE);
1070 mpi_request = MPI_REQUEST_NULL;
1075 MpiLock::Section mls(m_mpi_lock);
1076 begin_time = MPI_Wtime();
1077 int rbuf_size = _checkSize(recv_buffer_size);
1078 m_mpi_prof->recv(recv_buffer, rbuf_size, data_type, i_proc, mpi_tag, m_communicator, &mpi_status);
1079 end_time = MPI_Wtime();
1084 MpiLock::Section mls(m_mpi_lock);
1085 begin_time = MPI_Wtime();
1086 int rbuf_size = _checkSize(recv_buffer_size);
1087 m_mpi_prof->iRecv(recv_buffer, rbuf_size, data_type, i_proc, mpi_tag, m_communicator, &mpi_request);
1088 end_time = MPI_Wtime();
1089 ARCCORE_ADD_REQUEST(mpi_request);
1092 info() <<
"MPI Recv: recv after "
1093 <<
" request=" << mpi_request;
1096 double sr_time = (end_time - begin_time);
1098 debug(
Trace::High) <<
"MPI Recv: recv after " << recv_size
1099 <<
" time " << sr_time <<
" blocking " << is_blocked;
1100 m_stat->add(MpiInfo(eMpiName::Recv).name(), end_time - begin_time, recv_size);
1101 return buildRequest(ret, mpi_request);
1108probeRecvPack(UniqueArray<Byte>& recv_buffer,
Int32 proc)
1110 double begin_time = MPI_Wtime();
1112 int recv_buffer_size = 0;
1113 _trace(
"MPI_Probe");
1114 m_mpi_prof->probe(proc, 101, m_communicator, &status);
1115 m_mpi_prof->getCount(&status, MPI_PACKED, &recv_buffer_size);
1117 recv_buffer.resize(recv_buffer_size);
1118 m_mpi_prof->recv(recv_buffer.data(), recv_buffer_size, MPI_PACKED, proc, 101, m_communicator, &status);
1120 double end_time = MPI_Wtime();
1121 Int64 recv_size = recv_buffer_size;
1122 double sr_time = (end_time - begin_time);
1123 debug(
Trace::High) <<
"MPI probeRecvPack " << recv_size
1124 <<
" time " << sr_time;
1125 m_stat->add(MpiInfo(eMpiName::Recv).name(), end_time - begin_time, recv_size);
1131MessageSourceInfo MpiAdapter::
1132_buildSourceInfoFromStatus(
const MPI_Status& mpi_status)
1135 MPI_Count message_size = 0;
1136 MPI_Get_elements_x(&mpi_status, MPI_BYTE, &message_size);
1137 MessageTag tag(mpi_status.MPI_TAG);
1138 MessageRank rank(mpi_status.MPI_SOURCE);
1139 return MessageSourceInfo(rank, tag, message_size);
1145MessageId MpiAdapter::
1146_probeMessage(MessageRank source, MessageTag tag,
bool is_blocking)
1148 MPI_Status mpi_status;
1149 int has_message = 0;
1150 MPI_Message message;
1152 int mpi_source = source.value();
1153 if (source.isProcNull())
1154 ARCCORE_THROW(NotImplementedException,
"Probe with MPI_PROC_NULL");
1155 if (source.isNull() && !m_is_allow_null_rank_for_any_source)
1156 ARCCORE_FATAL(
"Can not use MPI_Mprobe with null rank. Use MessageRank::anySourceRank() instead");
1157 if (source.isNull() || source.isAnySource())
1158 mpi_source = MPI_ANY_SOURCE;
1159 int mpi_tag = tag.value();
1161 mpi_tag = MPI_ANY_TAG;
1163 ret = MPI_Mprobe(mpi_source, mpi_tag, m_communicator, &message, &mpi_status);
1167 ret = MPI_Improbe(mpi_source, mpi_tag, m_communicator, &has_message, &message, &mpi_status);
1170 ARCCORE_FATAL(
"Error during call to MPI_Mprobe r={0}", ret);
1171 MessageId ret_message;
1172 if (has_message != 0) {
1173 MessageSourceInfo si(_buildSourceInfoFromStatus(mpi_status));
1174 ret_message = MessageId(si, message);
1182MessageId MpiAdapter::
1183probeMessage(PointToPointMessageInfo message)
1185 if (!message.isValid())
1189 if (!message.isRankTag())
1190 ARCCORE_FATAL(
"Invalid message_info: message.isRankTag() is false");
1192 return _probeMessage(message.destinationRank(), message.tag(), message.isBlocking());
1198MessageSourceInfo MpiAdapter::
1199_legacyProbeMessage(MessageRank source, MessageTag tag,
bool is_blocking)
1201 MPI_Status mpi_status;
1202 int has_message = 0;
1204 int mpi_source = source.value();
1205 if (source.isProcNull())
1206 ARCCORE_THROW(NotImplementedException,
"Probe with MPI_PROC_NULL");
1207 if (source.isNull() && !m_is_allow_null_rank_for_any_source)
1208 ARCCORE_FATAL(
"Can not use MPI_Probe with null rank. Use MessageRank::anySourceRank() instead");
1209 if (source.isNull() || source.isAnySource())
1210 mpi_source = MPI_ANY_SOURCE;
1211 int mpi_tag = tag.value();
1213 mpi_tag = MPI_ANY_TAG;
1215 ret = MPI_Probe(mpi_source, mpi_tag, m_communicator, &mpi_status);
1219 ret = MPI_Iprobe(mpi_source, mpi_tag, m_communicator, &has_message, &mpi_status);
1221 ARCCORE_FATAL(
"Error during call to MPI_Mprobe r={0}", ret);
1222 if (has_message != 0)
1223 return _buildSourceInfoFromStatus(mpi_status);
1230MessageSourceInfo MpiAdapter::
1231legacyProbeMessage(PointToPointMessageInfo message)
1233 if (!message.isValid())
1237 if (!message.isRankTag())
1238 ARCCORE_FATAL(
"Invalid message_info: message.isRankTag() is false");
1240 return _legacyProbeMessage(message.destinationRank(), message.tag(), message.isBlocking());
1248directRecv(
void* recv_buffer,
Int64 recv_buffer_size,
1249 MessageId message,
Int64 elem_size, MPI_Datatype data_type,
1252 MPI_Status mpi_status;
1253 MPI_Request mpi_request = MPI_REQUEST_NULL;
1254 MPI_Message mpi_message = (MPI_Message)message;
1256 double begin_time = 0.0;
1257 double end_time = 0.0;
1259 Int64 recv_size = recv_buffer_size * elem_size;
1261 info() <<
"MPI_TRACE: MPI Mrecv: recv before "
1262 <<
" size=" << recv_size
1263 <<
" from_msg=" << message
1264 <<
" datatype=" << data_type
1265 <<
" blocking=" << is_blocked;
1274 MpiLock::Section mls(m_mpi_lock);
1275 begin_time = MPI_Wtime();
1276 int rbuf_size = _checkSize(recv_buffer_size);
1277 MPI_Imrecv(recv_buffer, rbuf_size, data_type, &mpi_message, &mpi_request);
1280 int is_finished = 0;
1281 MPI_Status mpi_status;
1282 while (is_finished == 0) {
1283 MpiLock::Section mls(m_mpi_lock);
1284 MPI_Request_get_status(mpi_request, &is_finished, &mpi_status);
1285 if (is_finished != 0) {
1286 end_time = MPI_Wtime();
1287 m_mpi_prof->wait(&mpi_request, (MPI_Status*)MPI_STATUS_IGNORE);
1288 mpi_request = MPI_REQUEST_NULL;
1293 MpiLock::Section mls(m_mpi_lock);
1294 begin_time = MPI_Wtime();
1295 int rbuf_size = _checkSize(recv_buffer_size);
1296 MPI_Mrecv(recv_buffer, rbuf_size, data_type, &mpi_message, &mpi_status);
1298 end_time = MPI_Wtime();
1303 MpiLock::Section mls(m_mpi_lock);
1304 begin_time = MPI_Wtime();
1305 int rbuf_size = _checkSize(recv_buffer_size);
1307 ret = MPI_Imrecv(recv_buffer, rbuf_size, data_type, &mpi_message, &mpi_request);
1309 end_time = MPI_Wtime();
1310 ARCCORE_ADD_REQUEST(mpi_request);
1313 info() <<
"MPI Recv: recv after "
1314 <<
" request=" << mpi_request;
1317 double sr_time = (end_time - begin_time);
1319 debug(
Trace::High) <<
"MPI Recv: recv after " << recv_size
1320 <<
" time " << sr_time <<
" blocking " << is_blocked;
1321 m_stat->add(MpiInfo(eMpiName::Recv).name(), end_time - begin_time, recv_size);
1322 return buildRequest(ret, mpi_request);
1329directRecvPack(
void* recv_buffer,
Int64 recv_buffer_size,
1330 Int32 proc,
int mpi_tag,
bool is_blocking)
1332 return directRecv(recv_buffer, recv_buffer_size, proc, 1, MPI_PACKED, mpi_tag, is_blocking);
1340waitAllRequests(ArrayView<Request> requests)
1342 UniqueArray<bool> indexes(requests.size());
1343 UniqueArray<MPI_Status> mpi_status(requests.size());
1344 while (_waitAllRequestsMPI(requests, indexes, mpi_status)) {
1354waitSomeRequests(ArrayView<Request> requests,
1355 ArrayView<bool> indexes,
1356 bool is_non_blocking)
1358 UniqueArray<MPI_Status> mpi_status(requests.size());
1359 waitSomeRequestsMPI(requests, indexes, mpi_status, is_non_blocking);
1370 , mpi_source_rank(source_rank)
1371 , mpi_source_tag(source_tag)
1376 int mpi_source_rank = MPI_PROC_NULL;
1377 int mpi_source_tag = 0;
1390 MpiLock::Section mls(m_mpi_lock);
1391 for (
Integer i = 0; i < size; ++i) {
1392 if (done_indexes[i]) {
1398 if (r.hasSubRequest()) {
1400 info() <<
"Done request with sub-request r=" << r <<
" mpi_r=" << r <<
" i=" << i
1401 <<
" source_rank=" << status[i].MPI_SOURCE
1402 <<
" source_tag=" << status[i].MPI_TAG;
1403 new_requests.
add(
SubRequestInfo(r.subRequest(), i, status[i].MPI_SOURCE, status[i].MPI_TAG));
1406 _removeRequest((MPI_Request)(r));
1415 bool has_new_request =
false;
1416 if (!new_requests.
empty()) {
1418 UniqueArray<MPI_Status> old_status(size);
1421 for (
Integer i = 0; i < size; ++i) {
1422 if (done_indexes[i]) {
1423 old_status[i] = status[index];
1432 info() <<
"Before handle new request index=" << index
1433 <<
" sri.source_rank=" << sri.mpi_source_rank
1434 <<
" sri.source_tag=" << sri.mpi_source_tag;
1435 SubRequestCompletionInfo completion_info(MessageRank(old_status[index].MPI_SOURCE), MessageTag(old_status[index].MPI_TAG));
1436 Request r = sri.sub_request->executeOnCompletion(completion_info);
1438 info() <<
"Handle new request index=" << index <<
" old_r=" << requests[index] <<
" new_r=" << r;
1443 has_new_request =
true;
1444 requests[index] = r;
1445 done_indexes[index] =
false;
1450 for (
Integer i = 0; i < size; ++i) {
1451 if (done_indexes[i]) {
1452 status[index] = old_status[i];
1458 return has_new_request;
1465_waitAllRequestsMPI(ArrayView<Request> requests,
1466 ArrayView<bool> indexes,
1467 ArrayView<MPI_Status> mpi_status)
1469 Integer size = requests.size();
1473 UniqueArray<MPI_Request> mpi_request(size);
1474 for (
Integer i = 0; i < size; ++i) {
1475 mpi_request[i] = (MPI_Request)(requests[i]);
1478 info() <<
" MPI_waitall begin size=" << size;
1479 double diff_time = 0.0;
1481 double begin_time = MPI_Wtime();
1482 for (
Integer i = 0; i < size; ++i) {
1483 MPI_Request request = (MPI_Request)(mpi_request[i]);
1484 int is_finished = 0;
1485 while (is_finished == 0) {
1486 MpiLock::Section mls(m_mpi_lock);
1487 m_mpi_prof->test(&request, &is_finished, (MPI_Status*)MPI_STATUS_IGNORE);
1490 double end_time = MPI_Wtime();
1491 diff_time = end_time - begin_time;
1495 MpiLock::Section mls(m_mpi_lock);
1496 double begin_time = MPI_Wtime();
1497 m_mpi_prof->waitAll(size, mpi_request.data(), mpi_status.data());
1498 double end_time = MPI_Wtime();
1499 diff_time = end_time - begin_time;
1503 for (
Integer i = 0; i < size; ++i) {
1507 bool has_new_request = _handleEndRequests(requests, indexes, mpi_status);
1509 info() <<
" MPI_waitall end size=" << size;
1510 m_stat->add(MpiInfo(eMpiName::Waitall).name(), diff_time, size);
1511 return has_new_request;
1518waitSomeRequestsMPI(ArrayView<Request> requests, ArrayView<bool> indexes,
1519 ArrayView<MPI_Status> mpi_status,
bool is_non_blocking)
1521 Integer size = requests.size();
1525 UniqueArray<MPI_Request> mpi_request(size);
1526 UniqueArray<MPI_Request> saved_mpi_request(size);
1527 UniqueArray<int> completed_requests(size);
1528 int nb_completed_request = 0;
1532 for (
Integer i = 0; i < size; ++i) {
1536 if (!requests[i].isValid()) {
1537 saved_mpi_request[i] = MPI_REQUEST_NULL;
1540 saved_mpi_request[i] =
static_cast<MPI_Request
>(requests[i]);
1546 bool is_print_debug = m_is_trace || (!is_non_blocking);
1548 debug() <<
"WaitRequestBegin is_non_blocking=" << is_non_blocking <<
" n=" << size;
1550 double begin_time = MPI_Wtime();
1553 if (is_non_blocking) {
1554 _trace(MpiInfo(eMpiName::Testsome).name().localstr());
1556 MpiLock::Section mls(m_mpi_lock);
1557 m_mpi_prof->testSome(size, saved_mpi_request.data(), &nb_completed_request,
1558 completed_requests.data(), mpi_status.data());
1561 if (nb_completed_request == MPI_UNDEFINED)
1562 nb_completed_request = 0;
1564 debug() <<
"WaitSomeRequestMPI: TestSome nb_completed=" << nb_completed_request;
1567 _trace(MpiInfo(eMpiName::Waitsome).name().localstr());
1571 MpiLock::Section mls(m_mpi_lock);
1572 m_mpi_prof->waitSome(size, saved_mpi_request.data(), &nb_completed_request,
1573 completed_requests.data(), mpi_status.data());
1577 if (nb_completed_request == MPI_UNDEFINED)
1578 nb_completed_request = 0;
1580 debug() <<
"WaitSomeRequest nb_completed=" << nb_completed_request;
1583 catch (TimeoutException& ex) {
1584 std::ostringstream ostr;
1585 if (is_non_blocking)
1586 ostr << MpiInfo(eMpiName::Testsome).name();
1588 ostr << MpiInfo(eMpiName::Waitsome).name();
1589 ostr <<
" size=" << size
1590 <<
" is_non_blocking=" << is_non_blocking;
1591 ex.setAdditionalInfo(ostr.str());
1595 for (
int z = 0; z < nb_completed_request; ++z) {
1596 int index = completed_requests[z];
1598 debug() <<
"Completed my_rank=" << m_comm_rank <<
" z=" << z
1599 <<
" index=" << index
1600 <<
" tag=" << mpi_status[z].MPI_TAG
1601 <<
" source=" << mpi_status[z].MPI_SOURCE;
1603 indexes[index] =
true;
1606 bool has_new_request = _handleEndRequests(requests, indexes, mpi_status);
1607 if (has_new_request) {
1612 double end_time = MPI_Wtime();
1613 m_stat->add(MpiInfo(eMpiName::Waitsome).name(), end_time - begin_time, size);
1620freeRequest(Request& request)
1622 if (!request.isValid()) {
1623 warning() <<
"MpiAdapter::freeRequest() null request r=" << (MPI_Request)request;
1624 _checkFatalInRequest();
1628 MpiLock::Section mls(m_mpi_lock);
1630 auto mr = (MPI_Request)request;
1632 MPI_Request_free(&mr);
1641testRequest(Request& request)
1644 if (!request.isValid())
1647 auto mr = (MPI_Request)request;
1648 int is_finished = 0;
1651 MpiLock::Section mls(m_mpi_lock);
1656 RequestSet::Iterator request_iter = m_request_set->findRequest(mr);
1658 m_mpi_prof->test(&mr, &is_finished, (MPI_Status*)MPI_STATUS_IGNORE);
1660 if (is_finished != 0) {
1661 m_request_set->removeRequest(request_iter);
1662 if (request.hasSubRequest())
1663 ARCCORE_THROW(NotImplementedException,
"SubRequest support");
1679_addRequest(MPI_Request request)
1681 m_request_set->addRequest(request);
1691_removeRequest(MPI_Request request)
1693 m_request_set->removeRequest(request);
1700enableDebugRequest(
bool enable_debug_request)
1702 m_stat->enable(enable_debug_request);
1711_checkFatalInRequest()
1713 if (isRequestErrorAreFatal())
1721setMpiProfiling(IMpiProfiling* mpi_profiling)
1723 m_mpi_prof = mpi_profiling;
1729IMpiProfiling* MpiAdapter::
1730getMpiProfiling()
const
1739setProfiler(IProfiler* profiler)
1742 m_mpi_prof =
nullptr;
1746 IMpiProfiling* p =
dynamic_cast<IMpiProfiling*
>(profiler);
1748 ARCCORE_FATAL(
"Invalid profiler. Profiler has to implemented interface 'IMpiProfiling'");
1755IProfiler* MpiAdapter::
1766initializeWindowCreator(MPI_Comm comm_machine)
1768 if (m_window_creator.isNull()) {
1769 Integer machine_comm_rank = 0;
1770 Integer machine_comm_size = 0;
1771 ::MPI_Comm_rank(comm_machine, &machine_comm_rank);
1772 ::MPI_Comm_size(comm_machine, &machine_comm_size);
1773 m_window_creator =
makeRef(
new MpiMachineShMemWinBaseInternalCreator(comm_machine, machine_comm_rank, machine_comm_size, m_communicator, m_comm_size));
1780MpiMachineShMemWinBaseInternalCreator* MpiAdapter::
1781windowCreator()
const
1783 return m_window_creator.get();
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCCORE_THROW(exception_class,...)
Macro to throw an exception with formatting.
bool empty() const
Capacity (number of allocated elements) of the vector.
Modifiable view of an array of type T.
constexpr Integer size() const noexcept
Returns the size of the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Statistics on parallelism.
Iterator findRequest(MPI_Request request)
Checks that the request is in the list.
bool m_no_check_request
True if requests are not checked.
static MpiMessagePassingMng * create(MPI_Comm comm, bool clean_comm=false)
Creates a manager associated with the communicator comm.
Reference to an instance.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
1D data vector with value semantics (STL style).
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
bool arccoreIsCheck()
True if in check mode.
std::int32_t Int32
Signed integer type of 32 bits.