Arcane  v3.14.10.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-2024 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-2024 */
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 Arccore::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
56 MpiAdapter(ITraceMng* msg,IStat* stat,
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,
93 Int32 proc,Int64 elem_size,MPI_Datatype data_type);
94
95 Request directSend(const void* send_buffer,Int64 send_buffer_size,
96 Int32 proc,Int64 elem_size,MPI_Datatype data_type,
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,
101 Int32 proc,MPI_Datatype data_type,int mpi_tag);
102
103 Request directRecv(void* recv_buffer,Int64 recv_buffer_size,
104 Int32 source_rank,Int64 elem_size,MPI_Datatype data_type,
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,
109 Int32 source_rank,MPI_Datatype data_type,int mpi_tag);
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,
121 MessageId message,Int64 elem_size,MPI_Datatype data_type,
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,
132 ArrayView<MPI_Status> mpi_status);
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,
140 ArrayView<MPI_Status> mpi_status,bool is_non_blocking);
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.
Vue modifiable d'un tableau d'un type T.
Interface gérant les statistiques sur l'exécution.
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.
void setTraceMPIMessage(bool v)
Indique si on affiche des messages pour chaque appel MPI.
Definition MpiAdapter.h:186
int commSize() const
Nombre de rangs dans le communicateur.
Definition MpiAdapter.h:146
int commRank() const
Rang de cette instance dans le communicateur.
Definition MpiAdapter.h:143
Verrou pour les appels MPI.
Definition MpiLock.h:37
Implémentation MPI du gestionnaire des échanges de messages.
Informations pour envoyer/recevoir un message point à point.
Requête d'un message.
Definition Request.h:77
Vecteur 1D de données avec sémantique par valeur (style STL).
std::int64_t Int64
Type entier signé sur 64 bits.
std::int32_t Int32
Type entier signé sur 32 bits.