Arcane  4.2.3.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
StandaloneMpiMessagePassingMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* StandaloneMpiMessagePassingMng.cc (C) 2000-2026 */
9/* */
10/* Implémentation MPI du gestionnaire des échanges de messages. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/message_passing_mpi/StandaloneMpiMessagePassingMng.h"
15
16#include "arccore/message_passing/Dispatchers.h"
17#include "arccore/message_passing/Stat.h"
18#include "arccore/trace/ITraceMng.h"
19#include "arccore/base/ReferenceCounter.h"
20#include "arccore/base/BFloat16.h"
21#include "arccore/base/Float16.h"
22
23#include "arccore/message_passing_mpi/MpiDatatype.h"
24#include "arccore/message_passing_mpi/internal/MpiMessagePassingMng.h"
25#include "arccore/message_passing_mpi/internal/MpiAdapter.h"
26#include "arccore/message_passing_mpi/internal/MpiTypeDispatcher.h"
27#include "arccore/message_passing_mpi/internal/MpiControlDispatcher.h"
28#include "arccore/message_passing_mpi/internal/MpiSerializeDispatcher.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane::MessagePassing::Mpi
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39class ARCCORE_MESSAGEPASSINGMPI_EXPORT StandaloneMpiMessagePassingMng2
40: public MpiMessagePassingMng
41{
42 class Impl;
43 friend class StandaloneMpiMessagePassingMng;
44
45 private:
46
47 explicit StandaloneMpiMessagePassingMng2(Impl* p);
48
49 public:
50
51 ~StandaloneMpiMessagePassingMng2() override;
52
53 private:
54
55 //! Crée un gestionnaire associé au communicateur \a comm.
56 static MpiMessagePassingMng* create(MPI_Comm comm, bool clean_comm = false);
57
58 /*!
59 * \brief Crée un gestionnaire associé au communicateur \a comm.
60 *
61 * Si \a clean_comm est vrai, MPI_Comm_free() est appelé sur \a comm
62 * lorsque l'instance est détruite.
63 */
64 static Ref<IMessagePassingMng> createRef(MPI_Comm comm, bool clean_comm = false);
65
66 static Ref<IMessagePassingMng> createAndInitializeMPI(int* argc, char** argv[], int wanted_thread_level);
67
68 private:
69
70 Impl* m_p = nullptr;
71
72 private:
73
74 static MpiMessagePassingMng* _create(Impl* p);
75};
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
81{
82 public:
83 explicit Impl(MPI_Comm mpi_comm, bool clean_comm=false)
84 : m_communicator(mpi_comm), m_clean_comm(clean_comm)
85 {
86 _init();
87 }
88
89 explicit Impl(int* argc, char** argv[], int wanted_thread_level)
90 : m_communicator(MPI_COMM_WORLD)
91 {
92 int provided = 0;
93 int r = MPI_Init_thread(argc, argv, wanted_thread_level, &provided);
94 if (r != MPI_SUCCESS)
95 ARCCORE_FATAL("Error when calling MPI_Init_thread err={0}", r);
96 if (provided != wanted_thread_level) {
97 int rank = 0;
98 ::MPI_Comm_rank(m_communicator, &rank);
99 if (rank == 0)
100 std::cerr << "WARNING: MPI_Init_thread provided level (" << provided
101 << ") is not the wanted level (" << wanted_thread_level << ")\n";
102 }
103 m_do_finalize = true;
104 _init();
105 }
106
107 ~Impl()
108 {
109 try {
110 m_adapter->destroy();
111 }
112 catch (const Exception& ex) {
113 std::cerr << "ERROR: msg=" << ex << "\n";
114 }
115
116 delete m_dispatchers;
117 delete m_stat;
118
119 if (m_clean_comm)
120 MPI_Comm_free(&m_communicator);
121 if (m_do_finalize)
122 MPI_Finalize();
123 }
124
125 void _init()
126 {
127 m_trace_mng = Arccore::arccoreCreateDefaultTraceMng();
128 MPI_Comm mpi_comm = m_communicator;
129 ::MPI_Comm_rank(mpi_comm, &m_comm_rank);
130 ::MPI_Comm_size(mpi_comm, &m_comm_size);
131 m_stat = new Stat();
132 MpiLock* mpi_lock = nullptr;
133 m_adapter = new MpiAdapter(m_trace_mng.get(), m_stat, mpi_comm, mpi_lock);
134
135 m_dispatchers = new Dispatchers();
136 m_dispatchers->setDeleteDispatchers(true);
137 }
138
139 MpiMessagePassingMng::BuildInfo
140 buildInfo() const
141 {
142 return MpiMessagePassingMng::BuildInfo(m_comm_rank, m_comm_size, m_dispatchers, m_communicator);
143 }
144
145 public:
146
147 ReferenceCounter<ITraceMng> m_trace_mng;
148 IStat* m_stat = nullptr;
149 Dispatchers* m_dispatchers = nullptr;
150 MpiAdapter* m_adapter = nullptr;
151 int m_comm_rank = A_NULL_RANK;
152 int m_comm_size = A_NULL_RANK;
153 MPI_Comm m_communicator = MPI_COMM_NULL;
154 bool m_clean_comm = false;
155 bool m_do_finalize = false;
156};
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161StandaloneMpiMessagePassingMng2::
162StandaloneMpiMessagePassingMng2(Impl* p)
163: MpiMessagePassingMng(p->buildInfo())
164, m_p(p)
165{
166 setTraceMng(p->m_trace_mng.get());
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172StandaloneMpiMessagePassingMng2::
173~StandaloneMpiMessagePassingMng2()
174{
175 delete m_p;
176}
177
178namespace
179{
180 template <typename DataType> void
181 _createAndSetCustomDispatcher(Dispatchers* dispatchers, IMessagePassingMng* mpm,
182 MpiAdapter* adapter, MpiDatatype* datatype)
183 {
184 auto* x = new MpiTypeDispatcher<DataType>(mpm, adapter, datatype);
185 x->setDestroyDatatype(true);
186 dispatchers->setDispatcher(x);
187 }
188
189 template <typename DataType> void
190 _createAndSetDispatcher(Dispatchers* dispatchers, IMessagePassingMng* mpm,
191 MpiAdapter* adapter)
192 {
193 MPI_Datatype mpi_dt = MpiBuiltIn::datatype(DataType());
194 auto dt = new MpiDatatype(mpi_dt);
195 _createAndSetCustomDispatcher<DataType>(dispatchers, mpm, adapter, dt);
196 }
197
198} // namespace
199
200/*---------------------------------------------------------------------------*/
201/*---------------------------------------------------------------------------*/
202
203MpiMessagePassingMng* StandaloneMpiMessagePassingMng2::
204_create(Impl* p)
205{
206 auto mpm = new StandaloneMpiMessagePassingMng2(p);
207 auto adapter = p->m_adapter;
208 auto dsp = p->m_dispatchers;
209
210 _createAndSetDispatcher<char>(dsp, mpm, adapter);
211 _createAndSetDispatcher<signed char>(dsp, mpm, adapter);
212 _createAndSetDispatcher<unsigned char>(dsp, mpm, adapter);
213 _createAndSetDispatcher<short>(dsp, mpm, adapter);
214 _createAndSetDispatcher<unsigned short>(dsp, mpm, adapter);
215 _createAndSetDispatcher<int>(dsp, mpm, adapter);
216 _createAndSetDispatcher<unsigned int>(dsp, mpm, adapter);
217 _createAndSetDispatcher<long>(dsp, mpm, adapter);
218 _createAndSetDispatcher<unsigned long>(dsp, mpm, adapter);
219 _createAndSetDispatcher<long long>(dsp, mpm, adapter);
220 _createAndSetDispatcher<unsigned long long>(dsp, mpm, adapter);
221 _createAndSetDispatcher<float>(dsp, mpm, adapter);
222 _createAndSetDispatcher<double>(dsp, mpm, adapter);
223 _createAndSetDispatcher<long double>(dsp, mpm, adapter);
224
225 dsp->setDispatcher(new MpiControlDispatcher(adapter, mpm));
226 dsp->setDispatcher(new MpiSerializeDispatcher(adapter, mpm));
227
228 MPI_Datatype uint8_datatype = MpiBuiltIn::datatype(uint8_t{});
229 {
230 // BFloat16
231 MPI_Datatype mpi_datatype;
232 MPI_Type_contiguous(2, uint8_datatype, &mpi_datatype);
233 MPI_Type_commit(&mpi_datatype);
234 auto* x = new MpiDatatype(mpi_datatype, false, new StdMpiReduceOperator<BFloat16>(true));
235 _createAndSetCustomDispatcher<BFloat16>(dsp, mpm, adapter, x);
236 }
237 {
238 // Float16
239 MPI_Datatype mpi_datatype;
240 MPI_Type_contiguous(2, uint8_datatype, &mpi_datatype);
241 MPI_Type_commit(&mpi_datatype);
242 auto* x = new MpiDatatype(mpi_datatype, false, new StdMpiReduceOperator<Float16>(true));
243 _createAndSetCustomDispatcher<Float16>(dsp, mpm, adapter, x);
244 }
245 return mpm;
246}
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251MpiMessagePassingMng* StandaloneMpiMessagePassingMng2::
252create(MPI_Comm mpi_comm, bool clean_comm)
253{
254 Impl* p = new Impl(mpi_comm, clean_comm);
255 return _create(p);
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261Ref<IMessagePassingMng> StandaloneMpiMessagePassingMng2::
262createRef(MPI_Comm mpi_comm, bool clean_comm)
263{
264 MpiMessagePassingMng* v = create(mpi_comm, clean_comm);
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
271Ref<IMessagePassingMng> StandaloneMpiMessagePassingMng2::
272createAndInitializeMPI(int* argc, char** argv[], int wanted_thread_level)
273{
274 Impl* p = new Impl(argc, argv, wanted_thread_level);
275 MpiMessagePassingMng* v = _create(p);
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
282/*---------------------------------------------------------------------------*/
283/*---------------------------------------------------------------------------*/
284
286create(MPI_Comm mpi_comm, bool clean_comm)
287{
288 return StandaloneMpiMessagePassingMng2::create(mpi_comm, clean_comm);
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
295createRef(MPI_Comm mpi_comm, bool clean_comm)
296{
297 return StandaloneMpiMessagePassingMng2::createRef(mpi_comm, clean_comm);
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
305{
306 return StandaloneMpiMessagePassingMng2::createRef(MPI_COMM_WORLD);
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
313createAndInitializeMPI(int* argc, char** argv[], int wanted_thread_level)
314{
315 return StandaloneMpiMessagePassingMng2::createAndInitializeMPI(argc, argv, wanted_thread_level);
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321} // End namespace Arcane::MessagePassing::Mpi
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classe de base d'une exception.
Interface du conteneur des dispatchers.
Definition Dispatchers.h:34
Interface du gestionnaire des échanges de messages.
static Ref< IMessagePassingMng > createAndInitializeMPI(int *argc, char **argv[], int wanted_thread_level)
Initialise MPI et créé un gestionnaire associé au communicateur MPI_WORLD_COMM.
static Ref< IMessagePassingMng > createRef(MPI_Comm comm, bool clean_comm=false)
Créé un gestionnaire associé au communicateur comm.
static Ref< IMessagePassingMng > createWorldRef()
Créé un gestionnaire associé au communicateur MPI_WORLD_COMM.
static IMessagePassingMng * create(MPI_Comm comm, bool clean_comm=false)
Créé un gestionnaire associé au communicateur comm.
Référence à une instance.
Encapsulation d'un pointeur avec compteur de référence.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.