Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
Messages.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/* Messages.cc (C) 2000-2025 */
9/* */
10/* Identifier of a point-to-point message. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
15
16#include "arccore/base/NotSupportedException.h"
17#include "arccore/base/FatalErrorException.h"
18#include "arccore/base/NotImplementedException.h"
19
20#include "arccore/serialize/BasicSerializer.h"
21#include "arccore/serialize/internal/BasicSerializerInternal.h"
22
23#include "arccore/message_passing/BasicSerializeMessage.h"
24#include "arccore/message_passing/ISerializeDispatcher.h"
25#include "arccore/message_passing/IControlDispatcher.h"
26#include "arccore/message_passing/MessageId.h"
27#include "arccore/message_passing/PointToPointMessageInfo.h"
28
29/*!
30 * \file Messages.h
31 *
32 * \brief Brief list of message exchange functions.
33 */
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane
39{
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
45{
46 public:
47
48 void doAllGather(MessagePassing::IMessagePassingMng* pm, const BasicSerializer* send_serializer,
49 BasicSerializer* receive_serializer);
50
51 template <typename DataType> void
52 _doGatherOne(MessagePassing::IMessagePassingMng* pm, Span<const DataType> send_values, Span<DataType> recv_buffer)
53 {
55 mpAllGatherVariable(pm, send_values, buf);
56 recv_buffer.copy(buf);
57 }
58};
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63void BasicSerializeGatherMessage::
64doAllGather(MessagePassing::IMessagePassingMng* pm, const BasicSerializer* send_serializer,
65 BasicSerializer* receive_serializer)
66{
67 // TODO: does not yet support types 'Float16', 'BFloat16'
68 // 'Float128' and 'Int128' because the latter are not supported
69 // in MPI messages.
70
71 const BasicSerializer* sbuf = send_serializer;
72 BasicSerializer* recv_buf = receive_serializer;
73 BasicSerializer::Impl2* sbuf_p2 = sbuf->m_p2;
74 BasicSerializer::Impl2* recv_p2 = recv_buf->m_p2;
75
76 Span<const Real> send_real = sbuf_p2->realBytes();
77 Span<const Int16> send_int16 = sbuf_p2->int16Bytes();
78 Span<const Int32> send_int32 = sbuf_p2->int32Bytes();
79 Span<const Int64> send_int64 = sbuf_p2->int64Bytes();
80 Span<const Byte> send_byte = sbuf_p2->byteBytes();
81 Span<const Int8> send_int8 = sbuf_p2->int8Bytes();
82 Span<const Float16> send_float16 = sbuf_p2->float16Bytes();
83 Span<const BFloat16> send_bfloat16 = sbuf_p2->bfloat16Bytes();
84 Span<const Float32> send_float32 = sbuf_p2->float32Bytes();
85 Span<const Float128> send_float128 = sbuf_p2->float128Bytes();
86 Span<const Int128> send_int128 = sbuf_p2->int128Bytes();
87
88 Int64 sizes[11];
89 sizes[0] = send_real.size();
90 sizes[1] = send_int16.size();
91 sizes[2] = send_int32.size();
92 sizes[3] = send_int64.size();
93 sizes[4] = send_byte.size();
94 sizes[5] = send_int8.size();
95 sizes[6] = send_float16.size();
96 sizes[7] = send_bfloat16.size();
97 sizes[8] = send_float32.size();
98 sizes[9] = send_float128.size();
99 sizes[10] = send_int128.size();
100
102
103 Int64 recv_nb_real = sizes[0];
104 Int64 recv_nb_int16 = sizes[1];
105 Int64 recv_nb_int32 = sizes[2];
106 Int64 recv_nb_int64 = sizes[3];
107 Int64 recv_nb_byte = sizes[4];
108 Int64 recv_nb_int8 = sizes[5];
109 Int64 recv_nb_float16 = sizes[6];
110 Int64 recv_nb_bfloat16 = sizes[7];
111 Int64 recv_nb_float32 = sizes[8];
112 Int64 recv_nb_float128 = sizes[9];
113 Int64 recv_nb_int128 = sizes[10];
114
115 if (recv_nb_float16 != 0)
116 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'float16' is not yet implemented");
117 if (recv_nb_bfloat16 != 0)
118 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'bfloat16' is not yet implemented");
119 if (recv_nb_float128 != 0)
120 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'float128' is not yet implemented");
121 if (recv_nb_int128 != 0)
122 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'int128' is not yet implemented");
123
124 recv_p2->allocateBuffer(recv_nb_real, recv_nb_int16, recv_nb_int32, recv_nb_int64, recv_nb_byte,
125 recv_nb_int8, recv_nb_float16, recv_nb_bfloat16, recv_nb_float32, recv_nb_float128, recv_nb_int128);
126
127 auto recv_p = recv_buf->_p();
128
129 _doGatherOne(pm, send_real, recv_p->getRealBuffer());
130 _doGatherOne(pm, send_int32, recv_p->getInt32Buffer());
131 _doGatherOne(pm, send_int16, recv_p->getInt16Buffer());
132 _doGatherOne(pm, send_int64, recv_p->getInt64Buffer());
133 _doGatherOne(pm, send_byte, recv_p->getByteBuffer());
134 _doGatherOne(pm, send_int8, recv_p->getInt8Buffer());
135 _doGatherOne(pm, send_float32, recv_p->getFloat32Buffer());
136}
137
138} // namespace Arcane
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
144{
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149/*!
150 * \brief Creates a list of requests.
151 *
152 * \sa IRequestList
153 */
154Ref<IRequestList>
156{
157 auto d = pm->dispatchers()->controlDispatcher();
158 return d->createRequestListRef();
159}
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
165{
166 auto d = pm->dispatchers()->controlDispatcher();
167 d->waitAllRequests(requests);
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
174{
175 mpWaitAll(pm, ArrayView<Request>(1, &request));
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
182{
183 auto d = pm->dispatchers()->controlDispatcher();
184 d->waitSomeRequests(requests, indexes, false);
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
191{
192 auto d = pm->dispatchers()->controlDispatcher();
193 d->waitSomeRequests(requests, indexes, true);
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
200 ArrayView<bool> indexes, eWaitType w_type)
201{
202 switch (w_type) {
203 case WaitAll:
204 mpWaitAll(pm, requests);
205 indexes.fill(true);
206 break;
207 case WaitSome:
208 mpWaitSome(pm, requests, indexes);
209 break;
211 mpTestSome(pm, requests, indexes);
212 break;
213 }
214}
215
216/*---------------------------------------------------------------------------*/
217/*---------------------------------------------------------------------------*/
218
221{
222 auto d = pm->dispatchers()->controlDispatcher();
223 return d->probe(message);
224}
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
231{
232 auto d = pm->dispatchers()->controlDispatcher();
233 return d->legacyProbe(message);
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
241{
242 auto d = pm->dispatchers()->controlDispatcher();
243 return d->commSplit(keep);
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
250{
251 auto d = pm->dispatchers()->controlDispatcher();
252 d->barrier();
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
260{
261 auto d = pm->dispatchers()->controlDispatcher();
262 return d->nonBlockingBarrier();
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
270{
271 auto d = pm->dispatchers()->serializeDispatcher();
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
280 const PointToPointMessageInfo& message)
281{
282 auto d = pm->dispatchers()->serializeDispatcher();
283 return d->sendSerializer(values, message);
284}
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
291 const PointToPointMessageInfo& message)
292{
293 auto d = pm->dispatchers()->serializeDispatcher();
294 return d->receiveSerializer(values, message);
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300MessageSourceInfo IControlDispatcher::
301legacyProbe(const PointToPointMessageInfo&)
302{
303 ARCCORE_THROW(NotSupportedException, "pure virtual call to legacyProbe()");
304}
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
309void mpAllGather(IMessagePassingMng* pm, const ISerializer* send_serializer, ISerializer* receive_serialize)
310{
311 auto* s = dynamic_cast<const BasicSerializer*>(send_serializer);
312 if (!s)
313 ARCCORE_FATAL("send_serializer is not a BasicSerializer");
314 auto* r = dynamic_cast<BasicSerializer*>(receive_serialize);
315 if (!r)
316 ARCCORE_FATAL("receive_serializer is not a BasicSerializer");
318 message.doAllGather(pm, s, r);
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
323
326{
327 return internal::BasicSerializeMessage::create(MessageRank(pm->commRank()), target, type);
328}
329
332{
333 return internal::BasicSerializeMessage::create(MessageRank(pm->commRank()), id);
334}
335
336ARCCORE_MESSAGEPASSING_EXPORT Ref<ISerializeMessage>
338{
339 return mpCreateSerializeMessage(pm, destination, ePointToPointMessageType::MsgSend);
340}
341
342ARCCORE_MESSAGEPASSING_EXPORT Ref<ISerializeMessage>
344{
345 return mpCreateSerializeMessage(pm, source, ePointToPointMessageType::MsgReceive);
346}
347
348/*---------------------------------------------------------------------------*/
349/*---------------------------------------------------------------------------*/
350
351namespace
352{
353 template <typename DataType> inline ITypeDispatcher<DataType>*
354 _getDispatcher(IMessagePassingMng* pm)
355 {
357 DataType* x = nullptr;
358 auto* dispatcher = pm->dispatchers()->dispatcher(x);
359 ARCCORE_CHECK_POINTER(dispatcher);
360 return dispatcher;
361 }
362} // namespace
363
364#define ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(type) \
365 void mpAllGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf) \
366 { \
367 _getDispatcher<type>(pm)->allGather(send_buf, recv_buf); \
368 } \
369 void mpGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 rank) \
370 { \
371 _getDispatcher<type>(pm)->gather(send_buf, recv_buf, rank); \
372 } \
373 Request mpNonBlockingAllGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf) \
374 { \
375 return _getDispatcher<type>(pm)->nonBlockingAllGather(send_buf, recv_buf); \
376 } \
377 Request mpNonBlockingGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 rank) \
378 { \
379 return _getDispatcher<type>(pm)->nonBlockingGather(send_buf, recv_buf, rank); \
380 } \
381 void mpAllGatherVariable(IMessagePassingMng* pm, Span<const type> send_buf, Array<type>& recv_buf) \
382 { \
383 _getDispatcher<type>(pm)->allGatherVariable(send_buf, recv_buf); \
384 } \
385 void mpGatherVariable(IMessagePassingMng* pm, Span<const type> send_buf, Array<type>& recv_buf, Int32 rank) \
386 { \
387 _getDispatcher<type>(pm)->gatherVariable(send_buf, recv_buf, rank); \
388 } \
389 Request mpGather(IMessagePassingMng* pm, GatherMessageInfo<type>& gather_info) \
390 { \
391 return _getDispatcher<type>(pm)->gather(gather_info); \
392 } \
393 void mpScatterVariable(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 root) \
394 { \
395 return _getDispatcher<type>(pm)->scatterVariable(send_buf, recv_buf, root); \
396 } \
397 type mpAllReduce(IMessagePassingMng* pm, eReduceType rt, type v) \
398 { \
399 return _getDispatcher<type>(pm)->allReduce(rt, v); \
400 } \
401 void mpAllReduce(IMessagePassingMng* pm, eReduceType rt, Span<type> buf) \
402 { \
403 _getDispatcher<type>(pm)->allReduce(rt, buf); \
404 } \
405 Request mpNonBlockingAllReduce(IMessagePassingMng* pm, eReduceType rt, Span<const type> send_buf, Span<type> recv_buf) \
406 { \
407 return _getDispatcher<type>(pm)->nonBlockingAllReduce(rt, send_buf, recv_buf); \
408 } \
409 void mpBroadcast(IMessagePassingMng* pm, Span<type> send_buf, Int32 rank) \
410 { \
411 _getDispatcher<type>(pm)->broadcast(send_buf, rank); \
412 } \
413 Request mpNonBlockingBroadcast(IMessagePassingMng* pm, Span<type> send_buf, Int32 rank) \
414 { \
415 return _getDispatcher<type>(pm)->nonBlockingBroadcast(send_buf, rank); \
416 } \
417 void mpSend(IMessagePassingMng* pm, Span<const type> values, Int32 rank) \
418 { \
419 _getDispatcher<type>(pm)->send(values, rank, true); \
420 } \
421 void mpReceive(IMessagePassingMng* pm, Span<type> values, Int32 rank) \
422 { \
423 _getDispatcher<type>(pm)->receive(values, rank, true); \
424 } \
425 Request mpSend(IMessagePassingMng* pm, Span<const type> values, Int32 rank, bool is_blocked) \
426 { \
427 return _getDispatcher<type>(pm)->send(values, rank, is_blocked); \
428 } \
429 Request mpSend(IMessagePassingMng* pm, Span<const type> values, const PointToPointMessageInfo& message) \
430 { \
431 return _getDispatcher<type>(pm)->send(values, message); \
432 } \
433 Request mpReceive(IMessagePassingMng* pm, Span<type> values, Int32 rank, bool is_blocked) \
434 { \
435 return _getDispatcher<type>(pm)->receive(values, rank, is_blocked); \
436 } \
437 Request mpReceive(IMessagePassingMng* pm, Span<type> values, const PointToPointMessageInfo& message) \
438 { \
439 return _getDispatcher<type>(pm)->receive(values, message); \
440 } \
441 void mpAllToAll(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 count) \
442 { \
443 return _getDispatcher<type>(pm)->allToAll(send_buf, recv_buf, count); \
444 } \
445 Request mpNonBlockingAllToAll(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 count) \
446 { \
447 return _getDispatcher<type>(pm)->nonBlockingAllToAll(send_buf, recv_buf, count); \
448 } \
449 void mpAllToAllVariable(IMessagePassingMng* pm, Span<const type> send_buf, ConstArrayView<Int32> send_count, \
450 ConstArrayView<Int32> send_index, Span<type> recv_buf, \
451 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) \
452 { \
453 _getDispatcher<type>(pm)->allToAllVariable(send_buf, send_count, send_index, recv_buf, recv_count, recv_index); \
454 } \
455 Request mpNonBlockingAllToAllVariable(IMessagePassingMng* pm, Span<const type> send_buf, ConstArrayView<Int32> send_count, \
456 ConstArrayView<Int32> send_index, Span<type> recv_buf, \
457 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) \
458 { \
459 return _getDispatcher<type>(pm)->nonBlockingAllToAllVariable(send_buf, send_count, send_index, recv_buf, recv_count, recv_index); \
460 }
461
462/*---------------------------------------------------------------------------*/
463/*---------------------------------------------------------------------------*/
464
465ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(char)
466ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(signed char)
467ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned char)
468
469ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(short)
470ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned short)
471ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(int)
472ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned int)
473ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long)
474ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned long)
475ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long long)
476ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned long long)
477
478ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(float)
479ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(double)
480ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long double)
481
482ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(BFloat16)
483ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(Float16)
484
485/*---------------------------------------------------------------------------*/
486/*---------------------------------------------------------------------------*/
487
488} // namespace Arcane::MessagePassing
489
490/*---------------------------------------------------------------------------*/
491/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCCORE_THROW(exception_class,...)
Macro to throw an exception with formatting.
#define ARCCORE_CHECK_POINTER(ptr)
Macro that returns the pointer ptr if it is not null or throws an exception if it is null.
Brief list of message exchange functions.
Modifiable view of an array of type T.
void fill(const T &o) noexcept
Fills the array with the value o.
virtual Ref< IRequestList > createRequestListRef()=0
Creation of a request list associated with this manager.
Interface of the message passing manager.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual Request receiveSerializer(ISerializer *s, const PointToPointMessageInfo &message)=0
Receiving message.
virtual Request sendSerializer(const ISerializer *s, const PointToPointMessageInfo &message)=0
Sending message.
virtual Ref< ISerializeMessageList > createSerializeMessageListRef()=0
Create a list of serialization messages.
Information about the source of a message.
Information for sending/receiving a point-to-point message.
Reference to an instance.
__host__ __device__ void copy(const U &copy_array)
Copies the array copy_array into the instance.
Definition Span.h:477
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:327
View of an array of elements of type T.
Definition Span.h:635
1D data vector with value semantics (STL style).
Declarations of types and methods used by message exchange mechanisms.
Ref< ISerializeMessage > mpCreateSerializeMessage(IMessagePassingMng *pm, MessageRank target, ePointToPointMessageType type)
Creates a serialization message.
Definition Messages.cc:325
void mpTestSome(IMessagePassingMng *pm, ArrayView< Request > requests, ArrayView< bool > indexes)
Tests if any of the requests in request are finished.
Definition Messages.cc:190
Ref< ISerializeMessageList > mpCreateSerializeMessageListRef(IMessagePassingMng *pm)
Creates a serialization message list.
Definition Messages.cc:269
Ref< ISerializeMessage > mpCreateSendSerializeMessage(IMessagePassingMng *pm, MessageRank destination)
Creates a serialization message for sending.
Definition Messages.cc:337
MessageSourceInfo mpLegacyProbe(IMessagePassingMng *pm, const PointToPointMessageInfo &message)
Tests if a message is available.
Definition Messages.cc:230
Ref< ISerializeMessage > mpCreateReceiveSerializeMessage(IMessagePassingMng *pm, MessageRank source)
Creates a serialization message for receiving.
Definition Messages.cc:343
MessageId mpProbe(IMessagePassingMng *pm, const PointToPointMessageInfo &message)
Tests if a message is available.
Definition Messages.cc:220
C char mpAllReduce(IMessagePassingMng *pm, eReduceType rt, char v)
Ref< IRequestList > mpCreateRequestListRef(IMessagePassingMng *pm)
Creates a list of requests.
Definition Messages.cc:155
C void mpAllGatherVariable(IMessagePassingMng *pm, Span< const char > send_buf, Array< char > &recv_buf)
@ WaitSome
Wait until all messages in the list are processed.
void mpBarrier(IMessagePassingMng *pm)
Performs a barrier.
Definition Messages.cc:249
Request mpNonBlockingBarrier(IMessagePassingMng *pm)
Performs a non-blocking barrier.
Definition Messages.cc:259
void mpWait(IMessagePassingMng *pm, Request request)
Blocks until the request request is finished.
Definition Messages.cc:173
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *receive_serialize)
allGather() message for serialization
Definition Messages.cc:309
void mpWaitAll(IMessagePassingMng *pm, ArrayView< Request > requests)
Blocks until the requests in requests are finished.
Definition Messages.cc:164
IMessagePassingMng * mpSplit(IMessagePassingMng *pm, bool keep)
Creates a new instance of IMessagePassingMng.
Definition Messages.cc:240
ePointToPointMessageType
Point-to-point message type.
Request mpReceive(IMessagePassingMng *pm, ISerializer *values, const PointToPointMessageInfo &message)
Receive message using an ISerializer.
Definition Messages.cc:290
void mpWaitSome(IMessagePassingMng *pm, ArrayView< Request > requests, ArrayView< bool > indexes)
Blocks until at least one of the requests in request is finished.
Definition Messages.cc:181
Request mpSend(IMessagePassingMng *pm, const ISerializer *values, const PointToPointMessageInfo &message)
Send message using an ISerializer.
Definition Messages.cc:279
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.