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);
856scanExclusive(
const void* send_buf,
void* recv_buf,
Int64 count, MPI_Datatype datatype, MPI_Op op)
858 void* _sbuf =
const_cast<void*
>(send_buf);
859 int _n = _checkSize(count);
860 double begin_time = MPI_Wtime();
861 _trace(MpiInfo(eMpiName::Scan).name().localstr());
862 m_mpi_prof->scanExclusive(_sbuf, recv_buf, _n, datatype, op, m_communicator);
863 double end_time = MPI_Wtime();
864 m_stat->add(MpiInfo(eMpiName::Scan).name(), end_time - begin_time, count);
871directSendRecv(
const void* send_buffer,
Int64 send_buffer_size,
872 void* recv_buffer,
Int64 recv_buffer_size,
873 Int32 proc,
Int64 elem_size, MPI_Datatype data_type)
875 void* v_send_buffer =
const_cast<void*
>(send_buffer);
876 MPI_Status mpi_status;
877 double begin_time = MPI_Wtime();
878 _trace(MpiInfo(eMpiName::Sendrecv).name().localstr());
879 int sbuf_size = _checkSize(send_buffer_size);
880 int rbuf_size = _checkSize(recv_buffer_size);
881 m_mpi_prof->sendRecv(v_send_buffer, sbuf_size, data_type, proc, 99,
882 recv_buffer, rbuf_size, data_type, proc, 99,
883 m_communicator, &mpi_status);
884 double end_time = MPI_Wtime();
885 Int64 send_size = send_buffer_size * elem_size;
886 Int64 recv_size = recv_buffer_size * elem_size;
887 double sr_time = (end_time - begin_time);
891 m_stat->add(MpiInfo(eMpiName::Sendrecv).name(), sr_time, send_size + recv_size);
898sendNonBlockingNoStat(
const void* send_buffer,
Int64 send_buffer_size,
899 Int32 dest_rank, MPI_Datatype data_type,
int mpi_tag)
901 void* v_send_buffer =
const_cast<void*
>(send_buffer);
902 MPI_Request mpi_request = MPI_REQUEST_NULL;
903 int sbuf_size = _checkSize(send_buffer_size);
905 m_mpi_prof->iSend(v_send_buffer, sbuf_size, data_type, dest_rank, mpi_tag, m_communicator, &mpi_request);
907 info() <<
" ISend ret=" << ret <<
" proc=" << dest_rank <<
" tag=" << mpi_tag <<
" request=" << mpi_request;
908 ARCCORE_ADD_REQUEST(mpi_request);
909 return buildRequest(ret, mpi_request);
916directSend(
const void* send_buffer,
Int64 send_buffer_size,
917 Int32 proc,
Int64 elem_size, MPI_Datatype data_type,
918 int mpi_tag,
bool is_blocked)
920 void* v_send_buffer =
const_cast<void*
>(send_buffer);
921 MPI_Request mpi_request = MPI_REQUEST_NULL;
923 double begin_time = 0.0;
924 double end_time = 0.0;
925 Int64 send_size = send_buffer_size * elem_size;
928 info() <<
"MPI_TRACE: MPI Send: send before"
929 <<
" size=" << send_size
931 <<
" tag=" << mpi_tag
932 <<
" datatype=" << data_type
933 <<
" blocking " << is_blocked;
941 MpiLock::Section mls(m_mpi_lock);
942 begin_time = MPI_Wtime();
943 int sbuf_size = _checkSize(send_buffer_size);
944 m_mpi_prof->iSend(v_send_buffer, sbuf_size, data_type, proc, mpi_tag, m_communicator, &mpi_request);
947 MPI_Status mpi_status;
948 while (is_finished == 0) {
949 MpiLock::Section mls(m_mpi_lock);
950 MPI_Request_get_status(mpi_request, &is_finished, &mpi_status);
951 if (is_finished != 0) {
952 m_mpi_prof->wait(&mpi_request, (MPI_Status*)MPI_STATUS_IGNORE);
953 end_time = MPI_Wtime();
954 mpi_request = MPI_REQUEST_NULL;
959 MpiLock::Section mls(m_mpi_lock);
960 begin_time = MPI_Wtime();
961 int sbuf_size = _checkSize(send_buffer_size);
962 m_mpi_prof->send(v_send_buffer, sbuf_size, data_type, proc, mpi_tag, m_communicator);
963 end_time = MPI_Wtime();
968 MpiLock::Section mls(m_mpi_lock);
969 begin_time = MPI_Wtime();
970 int sbuf_size = _checkSize(send_buffer_size);
971 m_mpi_prof->iSend(v_send_buffer, sbuf_size, data_type, proc, mpi_tag, m_communicator, &mpi_request);
973 info() <<
" ISend ret=" << ret <<
" proc=" << proc <<
" tag=" << mpi_tag <<
" request=" << mpi_request;
974 end_time = MPI_Wtime();
975 ARCCORE_ADD_REQUEST(mpi_request);
978 info() <<
"MPI Send: send after"
979 <<
" request=" << mpi_request;
982 double sr_time = (end_time - begin_time);
984 debug(
Trace::High) <<
"MPI Send: send " << send_size
985 <<
" time " << sr_time <<
" blocking " << is_blocked;
987 m_stat->add(MpiInfo(eMpiName::Send).name(), end_time - begin_time, send_size);
988 return buildRequest(ret, mpi_request);
995directSendPack(
const void* send_buffer,
Int64 send_buffer_size,
996 Int32 proc,
int mpi_tag,
bool is_blocked)
998 return directSend(send_buffer, send_buffer_size, proc, 1, MPI_PACKED, mpi_tag, is_blocked);
1004IMessagePassingMng* MpiAdapter::
1009 MPI_Comm_split(m_communicator, (keep) ? 1 : MPI_UNDEFINED, commRank(), &new_comm);
1021receiveNonBlockingNoStat(
void* recv_buffer,
Int64 recv_buffer_size,
1022 Int32 source_rank, MPI_Datatype data_type,
int mpi_tag)
1024 int rbuf_size = _checkSize(recv_buffer_size);
1026 MPI_Request mpi_request = MPI_REQUEST_NULL;
1027 m_mpi_prof->iRecv(recv_buffer, rbuf_size, data_type, source_rank, mpi_tag, m_communicator, &mpi_request);
1028 ARCCORE_ADD_REQUEST(mpi_request);
1029 return buildRequest(ret, mpi_request);
1036directRecv(
void* recv_buffer,
Int64 recv_buffer_size,
1037 Int32 proc,
Int64 elem_size, MPI_Datatype data_type,
1038 int mpi_tag,
bool is_blocked)
1040 MPI_Status mpi_status;
1041 MPI_Request mpi_request = MPI_REQUEST_NULL;
1043 double begin_time = 0.0;
1044 double end_time = 0.0;
1047 if (proc == A_PROC_NULL_RANK)
1048 ARCCORE_THROW(NotImplementedException,
"Receive with MPI_PROC_NULL");
1049 if (proc == A_NULL_RANK && !m_is_allow_null_rank_for_any_source)
1050 ARCCORE_FATAL(
"Can not use A_NULL_RANK for any source. Use A_ANY_SOURCE_RANK instead");
1051 if (proc == A_NULL_RANK || proc == A_ANY_SOURCE_RANK)
1052 i_proc = MPI_ANY_SOURCE;
1054 i_proc =
static_cast<int>(proc);
1056 Int64 recv_size = recv_buffer_size * elem_size;
1058 info() <<
"MPI_TRACE: MPI Recv: recv before "
1059 <<
" size=" << recv_size
1060 <<
" from=" << i_proc
1061 <<
" tag=" << mpi_tag
1062 <<
" datatype=" << data_type
1063 <<
" blocking=" << is_blocked;
1072 MpiLock::Section mls(m_mpi_lock);
1073 begin_time = MPI_Wtime();
1074 int rbuf_size = _checkSize(recv_buffer_size);
1075 m_mpi_prof->iRecv(recv_buffer, rbuf_size, data_type, i_proc, mpi_tag, m_communicator, &mpi_request);
1077 int is_finished = 0;
1078 MPI_Status mpi_status;
1079 while (is_finished == 0) {
1080 MpiLock::Section mls(m_mpi_lock);
1081 MPI_Request_get_status(mpi_request, &is_finished, &mpi_status);
1082 if (is_finished != 0) {
1083 end_time = MPI_Wtime();
1084 m_mpi_prof->wait(&mpi_request, (MPI_Status*)MPI_STATUS_IGNORE);
1085 mpi_request = MPI_REQUEST_NULL;
1090 MpiLock::Section mls(m_mpi_lock);
1091 begin_time = MPI_Wtime();
1092 int rbuf_size = _checkSize(recv_buffer_size);
1093 m_mpi_prof->recv(recv_buffer, rbuf_size, data_type, i_proc, mpi_tag, m_communicator, &mpi_status);
1094 end_time = MPI_Wtime();
1099 MpiLock::Section mls(m_mpi_lock);
1100 begin_time = MPI_Wtime();
1101 int rbuf_size = _checkSize(recv_buffer_size);
1102 m_mpi_prof->iRecv(recv_buffer, rbuf_size, data_type, i_proc, mpi_tag, m_communicator, &mpi_request);
1103 end_time = MPI_Wtime();
1104 ARCCORE_ADD_REQUEST(mpi_request);
1107 info() <<
"MPI Recv: recv after "
1108 <<
" request=" << mpi_request;
1111 double sr_time = (end_time - begin_time);
1113 debug(
Trace::High) <<
"MPI Recv: recv after " << recv_size
1114 <<
" time " << sr_time <<
" blocking " << is_blocked;
1115 m_stat->add(MpiInfo(eMpiName::Recv).name(), end_time - begin_time, recv_size);
1116 return buildRequest(ret, mpi_request);
1123probeRecvPack(UniqueArray<Byte>& recv_buffer,
Int32 proc)
1125 double begin_time = MPI_Wtime();
1127 int recv_buffer_size = 0;
1128 _trace(
"MPI_Probe");
1129 m_mpi_prof->probe(proc, 101, m_communicator, &status);
1130 m_mpi_prof->getCount(&status, MPI_PACKED, &recv_buffer_size);
1132 recv_buffer.resize(recv_buffer_size);
1133 m_mpi_prof->recv(recv_buffer.data(), recv_buffer_size, MPI_PACKED, proc, 101, m_communicator, &status);
1135 double end_time = MPI_Wtime();
1136 Int64 recv_size = recv_buffer_size;
1137 double sr_time = (end_time - begin_time);
1138 debug(
Trace::High) <<
"MPI probeRecvPack " << recv_size
1139 <<
" time " << sr_time;
1140 m_stat->add(MpiInfo(eMpiName::Recv).name(), end_time - begin_time, recv_size);
1146MessageSourceInfo MpiAdapter::
1147_buildSourceInfoFromStatus(
const MPI_Status& mpi_status)
1150 MPI_Count message_size = 0;
1151 MPI_Get_elements_x(&mpi_status, MPI_BYTE, &message_size);
1152 MessageTag tag(mpi_status.MPI_TAG);
1153 MessageRank rank(mpi_status.MPI_SOURCE);
1154 return MessageSourceInfo(rank, tag, message_size);
1160MessageId MpiAdapter::
1161_probeMessage(MessageRank source, MessageTag tag,
bool is_blocking)
1163 MPI_Status mpi_status;
1164 int has_message = 0;
1165 MPI_Message message;
1167 int mpi_source = source.value();
1168 if (source.isProcNull())
1169 ARCCORE_THROW(NotImplementedException,
"Probe with MPI_PROC_NULL");
1170 if (source.isNull() && !m_is_allow_null_rank_for_any_source)
1171 ARCCORE_FATAL(
"Can not use MPI_Mprobe with null rank. Use MessageRank::anySourceRank() instead");
1172 if (source.isNull() || source.isAnySource())
1173 mpi_source = MPI_ANY_SOURCE;
1174 int mpi_tag = tag.value();
1176 mpi_tag = MPI_ANY_TAG;
1178 ret = MPI_Mprobe(mpi_source, mpi_tag, m_communicator, &message, &mpi_status);
1182 ret = MPI_Improbe(mpi_source, mpi_tag, m_communicator, &has_message, &message, &mpi_status);
1185 ARCCORE_FATAL(
"Error during call to MPI_Mprobe r={0}", ret);
1186 MessageId ret_message;
1187 if (has_message != 0) {
1188 MessageSourceInfo si(_buildSourceInfoFromStatus(mpi_status));
1189 ret_message = MessageId(si, message);
1197MessageId MpiAdapter::
1198probeMessage(PointToPointMessageInfo message)
1200 if (!message.isValid())
1204 if (!message.isRankTag())
1205 ARCCORE_FATAL(
"Invalid message_info: message.isRankTag() is false");
1207 return _probeMessage(message.destinationRank(), message.tag(), message.isBlocking());
1213MessageSourceInfo MpiAdapter::
1214_legacyProbeMessage(MessageRank source, MessageTag tag,
bool is_blocking)
1216 MPI_Status mpi_status;
1217 int has_message = 0;
1219 int mpi_source = source.value();
1220 if (source.isProcNull())
1221 ARCCORE_THROW(NotImplementedException,
"Probe with MPI_PROC_NULL");
1222 if (source.isNull() && !m_is_allow_null_rank_for_any_source)
1223 ARCCORE_FATAL(
"Can not use MPI_Probe with null rank. Use MessageRank::anySourceRank() instead");
1224 if (source.isNull() || source.isAnySource())
1225 mpi_source = MPI_ANY_SOURCE;
1226 int mpi_tag = tag.value();
1228 mpi_tag = MPI_ANY_TAG;
1230 ret = MPI_Probe(mpi_source, mpi_tag, m_communicator, &mpi_status);
1234 ret = MPI_Iprobe(mpi_source, mpi_tag, m_communicator, &has_message, &mpi_status);
1236 ARCCORE_FATAL(
"Error during call to MPI_Mprobe r={0}", ret);
1237 if (has_message != 0)
1238 return _buildSourceInfoFromStatus(mpi_status);
1245MessageSourceInfo MpiAdapter::
1246legacyProbeMessage(PointToPointMessageInfo message)
1248 if (!message.isValid())
1252 if (!message.isRankTag())
1253 ARCCORE_FATAL(
"Invalid message_info: message.isRankTag() is false");
1255 return _legacyProbeMessage(message.destinationRank(), message.tag(), message.isBlocking());
1263directRecv(
void* recv_buffer,
Int64 recv_buffer_size,
1264 MessageId message,
Int64 elem_size, MPI_Datatype data_type,
1267 MPI_Status mpi_status;
1268 MPI_Request mpi_request = MPI_REQUEST_NULL;
1269 MPI_Message mpi_message = (MPI_Message)message;
1271 double begin_time = 0.0;
1272 double end_time = 0.0;
1274 Int64 recv_size = recv_buffer_size * elem_size;
1276 info() <<
"MPI_TRACE: MPI Mrecv: recv before "
1277 <<
" size=" << recv_size
1278 <<
" from_msg=" << message
1279 <<
" datatype=" << data_type
1280 <<
" blocking=" << is_blocked;
1289 MpiLock::Section mls(m_mpi_lock);
1290 begin_time = MPI_Wtime();
1291 int rbuf_size = _checkSize(recv_buffer_size);
1292 MPI_Imrecv(recv_buffer, rbuf_size, data_type, &mpi_message, &mpi_request);
1295 int is_finished = 0;
1296 MPI_Status mpi_status;
1297 while (is_finished == 0) {
1298 MpiLock::Section mls(m_mpi_lock);
1299 MPI_Request_get_status(mpi_request, &is_finished, &mpi_status);
1300 if (is_finished != 0) {
1301 end_time = MPI_Wtime();
1302 m_mpi_prof->wait(&mpi_request, (MPI_Status*)MPI_STATUS_IGNORE);
1303 mpi_request = MPI_REQUEST_NULL;
1308 MpiLock::Section mls(m_mpi_lock);
1309 begin_time = MPI_Wtime();
1310 int rbuf_size = _checkSize(recv_buffer_size);
1311 MPI_Mrecv(recv_buffer, rbuf_size, data_type, &mpi_message, &mpi_status);
1313 end_time = MPI_Wtime();
1318 MpiLock::Section mls(m_mpi_lock);
1319 begin_time = MPI_Wtime();
1320 int rbuf_size = _checkSize(recv_buffer_size);
1322 ret = MPI_Imrecv(recv_buffer, rbuf_size, data_type, &mpi_message, &mpi_request);
1324 end_time = MPI_Wtime();
1325 ARCCORE_ADD_REQUEST(mpi_request);
1328 info() <<
"MPI Recv: recv after "
1329 <<
" request=" << mpi_request;
1332 double sr_time = (end_time - begin_time);
1334 debug(
Trace::High) <<
"MPI Recv: recv after " << recv_size
1335 <<
" time " << sr_time <<
" blocking " << is_blocked;
1336 m_stat->add(MpiInfo(eMpiName::Recv).name(), end_time - begin_time, recv_size);
1337 return buildRequest(ret, mpi_request);
1344directRecvPack(
void* recv_buffer,
Int64 recv_buffer_size,
1345 Int32 proc,
int mpi_tag,
bool is_blocking)
1347 return directRecv(recv_buffer, recv_buffer_size, proc, 1, MPI_PACKED, mpi_tag, is_blocking);
1355waitAllRequests(ArrayView<Request> requests)
1357 UniqueArray<bool> indexes(requests.size());
1358 UniqueArray<MPI_Status> mpi_status(requests.size());
1359 while (_waitAllRequestsMPI(requests, indexes, mpi_status)) {
1369waitSomeRequests(ArrayView<Request> requests,
1370 ArrayView<bool> indexes,
1371 bool is_non_blocking)
1373 UniqueArray<MPI_Status> mpi_status(requests.size());
1374 waitSomeRequestsMPI(requests, indexes, mpi_status, is_non_blocking);
1385 , mpi_source_rank(source_rank)
1386 , mpi_source_tag(source_tag)
1391 int mpi_source_rank = MPI_PROC_NULL;
1392 int mpi_source_tag = 0;
1405 MpiLock::Section mls(m_mpi_lock);
1406 for (
Integer i = 0; i < size; ++i) {
1407 if (done_indexes[i]) {
1413 if (r.hasSubRequest()) {
1415 info() <<
"Done request with sub-request r=" << r <<
" mpi_r=" << r <<
" i=" << i
1416 <<
" source_rank=" << status[i].MPI_SOURCE
1417 <<
" source_tag=" << status[i].MPI_TAG;
1418 new_requests.
add(
SubRequestInfo(r.subRequest(), i, status[i].MPI_SOURCE, status[i].MPI_TAG));
1421 _removeRequest((MPI_Request)(r));
1430 bool has_new_request =
false;
1431 if (!new_requests.
empty()) {
1433 UniqueArray<MPI_Status> old_status(size);
1436 for (
Integer i = 0; i < size; ++i) {
1437 if (done_indexes[i]) {
1438 old_status[i] = status[index];
1447 info() <<
"Before handle new request index=" << index
1448 <<
" sri.source_rank=" << sri.mpi_source_rank
1449 <<
" sri.source_tag=" << sri.mpi_source_tag;
1450 SubRequestCompletionInfo completion_info(MessageRank(old_status[index].MPI_SOURCE), MessageTag(old_status[index].MPI_TAG));
1451 Request r = sri.sub_request->executeOnCompletion(completion_info);
1453 info() <<
"Handle new request index=" << index <<
" old_r=" << requests[index] <<
" new_r=" << r;
1458 has_new_request =
true;
1459 requests[index] = r;
1460 done_indexes[index] =
false;
1465 for (
Integer i = 0; i < size; ++i) {
1466 if (done_indexes[i]) {
1467 status[index] = old_status[i];
1473 return has_new_request;
1480_waitAllRequestsMPI(ArrayView<Request> requests,
1481 ArrayView<bool> indexes,
1482 ArrayView<MPI_Status> mpi_status)
1484 Integer size = requests.size();
1488 UniqueArray<MPI_Request> mpi_request(size);
1489 for (
Integer i = 0; i < size; ++i) {
1490 mpi_request[i] = (MPI_Request)(requests[i]);
1493 info() <<
" MPI_waitall begin size=" << size;
1494 double diff_time = 0.0;
1496 double begin_time = MPI_Wtime();
1497 for (
Integer i = 0; i < size; ++i) {
1498 MPI_Request request = (MPI_Request)(mpi_request[i]);
1499 int is_finished = 0;
1500 while (is_finished == 0) {
1501 MpiLock::Section mls(m_mpi_lock);
1502 m_mpi_prof->test(&request, &is_finished, (MPI_Status*)MPI_STATUS_IGNORE);
1505 double end_time = MPI_Wtime();
1506 diff_time = end_time - begin_time;
1510 MpiLock::Section mls(m_mpi_lock);
1511 double begin_time = MPI_Wtime();
1512 m_mpi_prof->waitAll(size, mpi_request.data(), mpi_status.data());
1513 double end_time = MPI_Wtime();
1514 diff_time = end_time - begin_time;
1518 for (
Integer i = 0; i < size; ++i) {
1522 bool has_new_request = _handleEndRequests(requests, indexes, mpi_status);
1524 info() <<
" MPI_waitall end size=" << size;
1525 m_stat->add(MpiInfo(eMpiName::Waitall).name(), diff_time, size);
1526 return has_new_request;
1533waitSomeRequestsMPI(ArrayView<Request> requests, ArrayView<bool> indexes,
1534 ArrayView<MPI_Status> mpi_status,
bool is_non_blocking)
1536 Integer size = requests.size();
1540 UniqueArray<MPI_Request> mpi_request(size);
1541 UniqueArray<MPI_Request> saved_mpi_request(size);
1542 UniqueArray<int> completed_requests(size);
1543 int nb_completed_request = 0;
1547 for (
Integer i = 0; i < size; ++i) {
1551 if (!requests[i].isValid()) {
1552 saved_mpi_request[i] = MPI_REQUEST_NULL;
1555 saved_mpi_request[i] =
static_cast<MPI_Request
>(requests[i]);
1561 bool is_print_debug = m_is_trace || (!is_non_blocking);
1563 debug() <<
"WaitRequestBegin is_non_blocking=" << is_non_blocking <<
" n=" << size;
1565 double begin_time = MPI_Wtime();
1568 if (is_non_blocking) {
1569 _trace(MpiInfo(eMpiName::Testsome).name().localstr());
1571 MpiLock::Section mls(m_mpi_lock);
1572 m_mpi_prof->testSome(size, saved_mpi_request.data(), &nb_completed_request,
1573 completed_requests.data(), mpi_status.data());
1576 if (nb_completed_request == MPI_UNDEFINED)
1577 nb_completed_request = 0;
1579 debug() <<
"WaitSomeRequestMPI: TestSome nb_completed=" << nb_completed_request;
1582 _trace(MpiInfo(eMpiName::Waitsome).name().localstr());
1586 MpiLock::Section mls(m_mpi_lock);
1587 m_mpi_prof->waitSome(size, saved_mpi_request.data(), &nb_completed_request,
1588 completed_requests.data(), mpi_status.data());
1592 if (nb_completed_request == MPI_UNDEFINED)
1593 nb_completed_request = 0;
1595 debug() <<
"WaitSomeRequest nb_completed=" << nb_completed_request;
1598 catch (TimeoutException& ex) {
1599 std::ostringstream ostr;
1600 if (is_non_blocking)
1601 ostr << MpiInfo(eMpiName::Testsome).name();
1603 ostr << MpiInfo(eMpiName::Waitsome).name();
1604 ostr <<
" size=" << size
1605 <<
" is_non_blocking=" << is_non_blocking;
1606 ex.setAdditionalInfo(ostr.str());
1610 for (
int z = 0; z < nb_completed_request; ++z) {
1611 int index = completed_requests[z];
1613 debug() <<
"Completed my_rank=" << m_comm_rank <<
" z=" << z
1614 <<
" index=" << index
1615 <<
" tag=" << mpi_status[z].MPI_TAG
1616 <<
" source=" << mpi_status[z].MPI_SOURCE;
1618 indexes[index] =
true;
1621 bool has_new_request = _handleEndRequests(requests, indexes, mpi_status);
1622 if (has_new_request) {
1627 double end_time = MPI_Wtime();
1628 m_stat->add(MpiInfo(eMpiName::Waitsome).name(), end_time - begin_time, size);
1635freeRequest(Request& request)
1637 if (!request.isValid()) {
1638 warning() <<
"MpiAdapter::freeRequest() null request r=" << (MPI_Request)request;
1639 _checkFatalInRequest();
1643 MpiLock::Section mls(m_mpi_lock);
1645 auto mr = (MPI_Request)request;
1647 MPI_Request_free(&mr);
1656testRequest(Request& request)
1659 if (!request.isValid())
1662 auto mr = (MPI_Request)request;
1663 int is_finished = 0;
1666 MpiLock::Section mls(m_mpi_lock);
1671 RequestSet::Iterator request_iter = m_request_set->findRequest(mr);
1673 m_mpi_prof->test(&mr, &is_finished, (MPI_Status*)MPI_STATUS_IGNORE);
1675 if (is_finished != 0) {
1676 m_request_set->removeRequest(request_iter);
1677 if (request.hasSubRequest())
1678 ARCCORE_THROW(NotImplementedException,
"SubRequest support");
1694_addRequest(MPI_Request request)
1696 m_request_set->addRequest(request);
1706_removeRequest(MPI_Request request)
1708 m_request_set->removeRequest(request);
1715enableDebugRequest(
bool enable_debug_request)
1717 m_stat->enable(enable_debug_request);
1726_checkFatalInRequest()
1728 if (isRequestErrorAreFatal())
1736setMpiProfiling(IMpiProfiling* mpi_profiling)
1738 m_mpi_prof = mpi_profiling;
1744IMpiProfiling* MpiAdapter::
1745getMpiProfiling()
const
1754setProfiler(IProfiler* profiler)
1757 m_mpi_prof =
nullptr;
1761 IMpiProfiling* p =
dynamic_cast<IMpiProfiling*
>(profiler);
1763 ARCCORE_FATAL(
"Invalid profiler. Profiler has to implemented interface 'IMpiProfiling'");
1770IProfiler* MpiAdapter::
1781initializeWindowCreator(MPI_Comm comm_machine)
1783 if (m_window_creator.isNull()) {
1784 Integer machine_comm_rank = 0;
1785 Integer machine_comm_size = 0;
1786 ::MPI_Comm_rank(comm_machine, &machine_comm_rank);
1787 ::MPI_Comm_size(comm_machine, &machine_comm_size);
1788 m_window_creator =
makeRef(
new MpiMachineShMemWinBaseInternalCreator(comm_machine, machine_comm_rank, machine_comm_size, m_communicator, m_comm_size));
1795MpiMachineShMemWinBaseInternalCreator* MpiAdapter::
1796windowCreator()
const
1798 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 IMessagePassingMng * 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.