Arcane  4.2.3.0
User documentation
Loading...
Searching...
No Matches
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/* MPI implementation of the message exchange manager. */
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 //! Creates a manager associated with the communicator \a comm.
56 static MpiMessagePassingMng* create(MPI_Comm comm, bool clean_comm = false);
57
58 /*!
59 * \brief Creates a manager associated with the communicator \a comm.
60 *
61 * If \a clean_comm is true, MPI_Comm_free() is called on \a comm
62 * when the instance is destroyed.
63 */
64 static Ref<IMessagePassingMng> createRef(MPI_Comm comm, bool clean_comm = false);
65
66 private:
67
68 Impl* m_p;
69};
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
75{
76 public:
77
78 explicit Impl(MPI_Comm mpi_comm, bool clean_comm = false)
79 : m_communicator(mpi_comm)
80 , m_clean_comm(clean_comm)
81 {
82 m_trace_mng = Arccore::arccoreCreateDefaultTraceMng();
83 ::MPI_Comm_rank(mpi_comm, &m_comm_rank);
84 ::MPI_Comm_size(mpi_comm, &m_comm_size);
85
86 m_stat = new Stat();
87 MpiLock* mpi_lock = nullptr;
88 m_adapter = new MpiAdapter(m_trace_mng.get(), m_stat, mpi_comm, mpi_lock);
89
90 m_dispatchers = new Dispatchers();
91 m_dispatchers->setDeleteDispatchers(true);
92 }
93
94 ~Impl()
95 {
96 try {
97 m_adapter->destroy();
98 }
99 catch (const Exception& ex) {
100 std::cerr << "ERROR: msg=" << ex << "\n";
101 }
102
103 delete m_dispatchers;
104 delete m_stat;
105
106 if (m_clean_comm)
107 MPI_Comm_free(&m_communicator);
108 }
109
110 MpiMessagePassingMng::BuildInfo
111 buildInfo() const
112 {
113 return MpiMessagePassingMng::BuildInfo(m_comm_rank, m_comm_size, m_dispatchers, m_communicator);
114 }
115
116 public:
117
118 ReferenceCounter<ITraceMng> m_trace_mng;
119 IStat* m_stat = nullptr;
120 Dispatchers* m_dispatchers = nullptr;
121 MpiAdapter* m_adapter = nullptr;
122 int m_comm_rank = A_NULL_RANK;
123 int m_comm_size = A_NULL_RANK;
124 MPI_Comm m_communicator = MPI_COMM_NULL;
125 bool m_clean_comm = false;
126};
127
128/*---------------------------------------------------------------------------*/
129/*---------------------------------------------------------------------------*/
130
131StandaloneMpiMessagePassingMng2::
132StandaloneMpiMessagePassingMng2(Impl* p)
133: MpiMessagePassingMng(p->buildInfo())
134, m_p(p)
135{
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
141StandaloneMpiMessagePassingMng2::
142~StandaloneMpiMessagePassingMng2()
143{
144 delete m_p;
145}
146
147namespace
148{
149 template <typename DataType> void
150 _createAndSetCustomDispatcher(Dispatchers* dispatchers, IMessagePassingMng* mpm,
151 MpiAdapter* adapter, MpiDatatype* datatype)
152 {
153 auto* x = new MpiTypeDispatcher<DataType>(mpm, adapter, datatype);
154 x->setDestroyDatatype(true);
155 dispatchers->setDispatcher(x);
156 }
157
158 template <typename DataType> void
159 _createAndSetDispatcher(Dispatchers* dispatchers, IMessagePassingMng* mpm,
160 MpiAdapter* adapter)
161 {
162 MPI_Datatype mpi_dt = MpiBuiltIn::datatype(DataType());
163 auto dt = new MpiDatatype(mpi_dt);
164 _createAndSetCustomDispatcher<DataType>(dispatchers, mpm, adapter, dt);
165 }
166
167} // namespace
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172MpiMessagePassingMng* StandaloneMpiMessagePassingMng2::
173create(MPI_Comm mpi_comm, bool clean_comm)
174{
175 Impl* p = new Impl(mpi_comm, clean_comm);
176 auto mpm = new StandaloneMpiMessagePassingMng2(p);
177 auto adapter = p->m_adapter;
178 auto dsp = p->m_dispatchers;
179
180 _createAndSetDispatcher<char>(dsp, mpm, adapter);
181 _createAndSetDispatcher<signed char>(dsp, mpm, adapter);
182 _createAndSetDispatcher<unsigned char>(dsp, mpm, adapter);
183 _createAndSetDispatcher<short>(dsp, mpm, adapter);
184 _createAndSetDispatcher<unsigned short>(dsp, mpm, adapter);
185 _createAndSetDispatcher<int>(dsp, mpm, adapter);
186 _createAndSetDispatcher<unsigned int>(dsp, mpm, adapter);
187 _createAndSetDispatcher<long>(dsp, mpm, adapter);
188 _createAndSetDispatcher<unsigned long>(dsp, mpm, adapter);
189 _createAndSetDispatcher<long long>(dsp, mpm, adapter);
190 _createAndSetDispatcher<unsigned long long>(dsp, mpm, adapter);
191 _createAndSetDispatcher<float>(dsp, mpm, adapter);
192 _createAndSetDispatcher<double>(dsp, mpm, adapter);
193 _createAndSetDispatcher<long double>(dsp, mpm, adapter);
194
195 dsp->setDispatcher(new MpiControlDispatcher(adapter, mpm));
196 dsp->setDispatcher(new MpiSerializeDispatcher(adapter, mpm));
197
198 MPI_Datatype uint8_datatype = MpiBuiltIn::datatype(uint8_t{});
199 {
200 // BFloat16
201 MPI_Datatype mpi_datatype;
202 MPI_Type_contiguous(2, uint8_datatype, &mpi_datatype);
203 MPI_Type_commit(&mpi_datatype);
204 auto* x = new MpiDatatype(mpi_datatype, false, new StdMpiReduceOperator<BFloat16>(true));
205 _createAndSetCustomDispatcher<BFloat16>(dsp, mpm, adapter, x);
206 }
207 {
208 // Float16
209 MPI_Datatype mpi_datatype;
210 MPI_Type_contiguous(2, uint8_datatype, &mpi_datatype);
211 MPI_Type_commit(&mpi_datatype);
212 auto* x = new MpiDatatype(mpi_datatype, false, new StdMpiReduceOperator<Float16>(true));
213 _createAndSetCustomDispatcher<Float16>(dsp, mpm, adapter, x);
214 }
215 return mpm;
216}
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220
221Ref<IMessagePassingMng> StandaloneMpiMessagePassingMng2::
222createRef(MPI_Comm mpi_comm, bool clean_comm)
223{
224 MpiMessagePassingMng* v = create(mpi_comm, clean_comm);
226}
227
228/*---------------------------------------------------------------------------*/
229/*---------------------------------------------------------------------------*/
230
232create(MPI_Comm mpi_comm, bool clean_comm)
233{
234 return StandaloneMpiMessagePassingMng2::create(mpi_comm, clean_comm);
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
241createRef(MPI_Comm mpi_comm, bool clean_comm)
242{
243 return StandaloneMpiMessagePassingMng2::createRef(mpi_comm, clean_comm);
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
251{
252 return StandaloneMpiMessagePassingMng2::createRef(MPI_COMM_WORLD);
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258} // End namespace Arcane::MessagePassing::Mpi
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
Interface of the dispatcher container.
Definition Dispatchers.h:35
Interface of the message passing manager.
static Ref< IMessagePassingMng > createRef(MPI_Comm comm, bool clean_comm=false)
Creates a manager associated with the communicator comm.
static Ref< IMessagePassingMng > createWorldRef()
Creates a manager associated with the MPI_WORLD_COMM communicator.
static IMessagePassingMng * create(MPI_Comm comm, bool clean_comm=false)
Creates a manager associated with the communicator comm.
Reference to an instance.
Encapsulation of a pointer with a reference counter.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.