Arcane  v3.15.3.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MpiAdapter.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MpiAdapter.h (C) 2000-2025 */
9/* */
10/* Implémentation des messages avec MPI. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_MESSAGEPASSINGMPI_MPIADAPTER_H
13#define ARCCORE_MESSAGEPASSINGMPI_MPIADAPTER_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arccore/trace/TraceAccessor.h"
18
19#include "arccore/message_passing_mpi/MessagePassingMpiGlobal.h"
20#include "arccore/message_passing_mpi/MessagePassingMpiEnum.h"
21#include "arccore/message_passing_mpi/IMpiProfiling.h"
22#include "arccore/message_passing/PointToPointMessageInfo.h"
23#include "arccore/message_passing/Request.h"
24#include "arccore/collections/CollectionsGlobal.h"
25
27
28#include <set>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane::MessagePassing::Mpi
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38/*!
39 * \internal
40 * \brief Adapteur pour MPI.
41 * \warning en hybride MPI/Thread, une instance de cette classe
42 * est partagée entre tous les threads d'un processus MPI et donc
43 * toutes les méthodes de cette classe doivent être thread-safe.
44 * \todo rendre thread-safe les statistiques
45 * \todo rendre thread-safe le m_allocated_request
46 */
47class ARCCORE_MESSAGEPASSINGMPI_EXPORT MpiAdapter
48: public TraceAccessor
49, public IRequestCreator
50{
51 public:
52 class RequestSet;
53 struct SubRequestInfo;
54 public:
55
57 MPI_Comm comm,MpiLock* mpi_lock,
58 IMpiProfiling* mpi_prof = nullptr);
59 MpiAdapter(const MpiAdapter& rhs) = delete;
60 MpiAdapter& operator=(const MpiAdapter& rhs) = delete;
61
62 protected:
63
64 ~MpiAdapter() override;
65
66 public:
67
68 //! Détruit l'instance. Elle ne doit plus être utilisée par la suite.
69 void destroy();
70
71 public:
72
73 void broadcast(void* buf,Int64 nb_elem,Int32 root,MPI_Datatype datatype);
74 void allGather(const void* send_buf,void* recv_buf,
75 Int64 nb_elem,MPI_Datatype datatype);
76 void gather(const void* send_buf,void* recv_buf,
77 Int64 nb_elem,Int32 root,MPI_Datatype datatype);
78 void allGatherVariable(const void* send_buf,void* recv_buf,const int* recv_counts,
79 const int* recv_indexes,Int64 nb_elem,MPI_Datatype datatype);
80 void gatherVariable(const void* send_buf,void* recv_buf,const int* recv_counts,
81 const int* recv_indexes,Int64 nb_elem,Int32 root,MPI_Datatype datatype);
82 void scatterVariable(const void* send_buf,const int* send_count,const int* send_indexes,
83 void* recv_buf,Int64 nb_elem,Int32 root,MPI_Datatype datatype);
84 void allToAll(const void* send_buf,void* recv_buf,Int32 count,MPI_Datatype datatype);
85 void allToAllVariable(const void* send_buf,const int* send_counts,
86 const int* send_indexes,void* recv_buf,const int* recv_counts,
87 const int* recv_indexes,MPI_Datatype datatype);
88 void reduce(const void* send_buf,void* recv_buf,Int64 count,MPI_Datatype datatype,MPI_Op op,Int32 root);
89 void allReduce(const void* send_buf,void* recv_buf,Int64 count,MPI_Datatype datatype,MPI_Op op);
90 void scan(const void* send_buf,void* recv_buf,Int64 count,MPI_Datatype datatype,MPI_Op op);
91 void directSendRecv(const void* send_buffer,Int64 send_buffer_size,
92 void* recv_buffer,Int64 recv_buffer_size,
94
95 Request directSend(const void* send_buffer,Int64 send_buffer_size,
97 int mpi_tag,bool is_blocked);
98
99 //! Version non bloquante de send sans statistique temporelle
100 Request sendNonBlockingNoStat(const void* send_buffer,Int64 send_buffer_size,
102
103 Request directRecv(void* recv_buffer,Int64 recv_buffer_size,
105 int mpi_tag,bool is_blocked);
106
107 //! Version non bloquante de receive sans statistiques temporelles
108 Request receiveNonBlockingNoStat(void* recv_buffer,Int64 recv_buffer_size,
110
111 Request directSendPack(const void* send_buffer,Int64 send_buffer_size,
112 Int32 proc,int mpi_tag,bool is_blocked);
113
114 void probeRecvPack(UniqueArray<Byte>& recv_buffer,Int32 proc);
115
116 MessageId probeMessage(PointToPointMessageInfo message);
117
118 MessageSourceInfo legacyProbeMessage(PointToPointMessageInfo message);
119
120 Request directRecv(void* recv_buffer,Int64 recv_buffer_size,
122 bool is_blocked);
123
124 Request directRecvPack(void* recv_buffer,Int64 recv_buffer_size,
125 Int32 proc,int mpi_tag,bool is_blocking);
126
127 void waitAllRequests(ArrayView<Request> requests);
128
129
130 private:
131 bool _waitAllRequestsMPI(ArrayView<Request> requests,ArrayView<bool> indexes,
133 public:
134 void waitSomeRequests(ArrayView<Request> requests,
135 ArrayView<bool> indexes,
136 bool is_non_blocking);
137
138 void waitSomeRequestsMPI(ArrayView<Request> requests,
139 ArrayView<bool> indexes,
141 public:
142 //! Rang de cette instance dans le communicateur
143 int commRank() const { return m_comm_rank; }
144
145 //! Nombre de rangs dans le communicateur
146 int commSize() const { return m_comm_size; }
147
148 MpiMessagePassingMng* commSplit(bool keep);
149
150 void freeRequest(Request& request);
151 bool testRequest(Request& request);
152
153 void enableDebugRequest(bool enable_debug_request);
154
155 MpiLock* mpiLock() const { return m_mpi_lock; }
156
157 Request nonBlockingBroadcast(void* buf,Int64 nb_elem,Int32 root,MPI_Datatype datatype);
158 Request nonBlockingAllGather(const void* send_buf,void* recv_buf,Int64 nb_elem,MPI_Datatype datatype);
159 Request nonBlockingGather(const void* send_buf,void* recv_buf,Int64 nb_elem,Int32 root,MPI_Datatype datatype);
160
161 Request nonBlockingAllToAll(const void* send_buf,void* recv_buf,Int32 count,MPI_Datatype datatype);
162 Request nonBlockingAllReduce(const void* send_buf,void* recv_buf,Int64 count,MPI_Datatype datatype,MPI_Op op);
163 Request nonBlockingAllToAllVariable(const void* send_buf,const int* send_counts,
164 const int* send_indexes,void* recv_buf,const int* recv_counts,
165 const int* recv_indexes,MPI_Datatype datatype);
166
167 Request nonBlockingBarrier();
168 void barrier();
169
170 int toMPISize(Int64 count);
171
172 //! Construit une requête Arccore à partir d'une requête MPI.
173 Request buildRequest(int ret,MPI_Request request);
174
175 public:
176
177 //! Indique si les erreurs dans la liste des requêtes sont fatales
178 void setRequestErrorAreFatal(bool v);
179 bool isRequestErrorAreFatal() const;
180
181 //! Indique si on affiche des messages pour les erreurs dans les requêtes.
182 void setPrintRequestError(bool v);
183 bool isPrintRequestError() const;
184
185 //! Indique si on affiche des messages pour chaque appel MPI.
186 void setTraceMPIMessage(bool v) { m_is_trace = v; }
187 bool isTraceMPIMessage() const { return m_is_trace; }
188
189 /*!
190 * \brief Indique si on vérifie les requêtes.
191 *
192 * Cette valeur ne doit être modifiée s'il y a des requêtes en cours.
193 */
194 void setCheckRequest(bool v);
195 bool isCheckRequest() const;
196
197 public:
198
199 void setMpiProfiling(IMpiProfiling* mpi_profiling);
200 void setProfiler(IProfiler* profiler);
201 IMpiProfiling* getMpiProfiling() const;
202 IProfiler* profiler() const;
203
204 public:
205
206 ITimeMetricCollector* timeMetricCollector() const { return m_metric_collector; }
207 void setTimeMetricCollector(ITimeMetricCollector* v) { m_metric_collector = v; }
208
209 bool isAllowNullRankForAnySource() const { return m_is_allow_null_rank_for_any_source; }
210
211 private:
212
213 IStat* m_stat;
214 MpiLock* m_mpi_lock;
215 IMpiProfiling* m_mpi_prof;
216 ITimeMetricCollector* m_metric_collector = nullptr;
217 MPI_Comm m_communicator; //!< Communicateur MPI
218 int m_comm_rank = A_PROC_NULL_RANK;
219 int m_comm_size = 0;
220 Int64 m_nb_all_reduce = 0;
221 Int64 m_nb_reduce = 0;
222 bool m_is_trace = false;
223 RequestSet* m_request_set = nullptr;
224 //! Requêtes vides. Voir MpiAdapter.cc pour plus d'infos.
225 MPI_Request m_empty_request1;
226 MPI_Request m_empty_request2;
227 int m_recv_buffer_for_empty_request[1];
228 int m_send_buffer_for_empty_request2[1];
229 int m_recv_buffer_for_empty_request2[1];
230
231 // Si vrai, autorise d'utiliser le rang nul (A_NULL_RANK) pour spécifier MPI_ANY_SOURCE
232 // Cela est le défaut dans les versions de Arccore avant juillet 2024.
233 // A partir de 2025 il faudra l'interdire.
234 // La variable d'environnement ARCCORE_ALLOW_NULL_RANK_FOR_MPI_ANY_SOURCE permettra
235 // de temporairement garder un mode compatible.
236 bool m_is_allow_null_rank_for_any_source = true;
237
238 private:
239
240 void _trace(const char* function);
241 void _addRequest(MPI_Request request);
242 void _removeRequest(MPI_Request request);
243 void _checkFatalInRequest();
244 MessageId _probeMessage(MessageRank source,MessageTag tag,bool is_blocking);
245 MessageSourceInfo _legacyProbeMessage(MessageRank source,MessageTag tag,bool is_blocking);
246 bool _handleEndRequests(ArrayView<Request> requests,ArrayView<bool> done_indexes,
247 ArrayView<MPI_Status> status);
248 void _checkHasNoRequests();
249 MessageSourceInfo _buildSourceInfoFromStatus(const MPI_Status& status);
250};
251
252/*---------------------------------------------------------------------------*/
253/*---------------------------------------------------------------------------*/
254
255} // End namespace Arccore::MessagePassing::Mpi
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
260#endif
Déclarations des types de la composante 'base' de Arccore.
void setTraceMPIMessage(bool v)
Indique si on affiche des messages pour chaque appel MPI.
Definition MpiAdapter.h:186
int commRank() const
Rang de cette instance dans le communicateur.
Definition MpiAdapter.h:143
int commSize() const
Nombre de rangs dans le communicateur.
Definition MpiAdapter.h:146
Verrou pour les appels MPI.
Definition MpiLock.h:37
Implémentation MPI du gestionnaire des échanges de messages.
Interface du gestionnaire de traces.
Interface d'un profiler pour les échanges de messages.
Definition IProfiler.h:31
Interface d'un créateur de requête.
Definition Request.h:52
Informations sur la source d'un message.
Informations pour envoyer/recevoir un message point à point.
Requête d'un message.
Definition Request.h:77
Référence à une instance.