Arcane  v3.15.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Messages.cc
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/* Messages.cc (C) 2000-2024 */
9/* */
10/* Identifiant d'un message point à point. */
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/ISerializeDispatcher.h"
24#include "arccore/message_passing/IControlDispatcher.h"
25#include "arccore/message_passing/MessageId.h"
26#include "arccore/message_passing/PointToPointMessageInfo.h"
27
28/*!
29 * \file Messages.h
30 *
31 * \brief Liste des fonctions d'échange de message.
32 */
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arccore
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
44{
45 public:
46
47 void doAllGather(MessagePassing::IMessagePassingMng* pm, const BasicSerializer* send_serializer,
48 BasicSerializer* receive_serializer);
49
50 template <typename DataType> void
51 _doGatherOne(MessagePassing::IMessagePassingMng* pm, Span<const DataType> send_values, Span<DataType> recv_buffer)
52 {
54 mpAllGatherVariable(pm, send_values, buf);
55 recv_buffer.copy(buf);
56 }
57};
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62void BasicSerializeGatherMessage::
63doAllGather(MessagePassing::IMessagePassingMng* pm, const BasicSerializer* send_serializer,
64 BasicSerializer* receive_serializer)
65{
66 // TODO: ne supporte pas encore les types 'Float16', 'BFloat16'
67 // 'Float128' et 'Int128' car ces derniers ne sont pas supportés
68 // dans les messages MPI.
69
70 const BasicSerializer* sbuf = send_serializer;
71 BasicSerializer* recv_buf = receive_serializer;
72 BasicSerializer::Impl2* sbuf_p2 = sbuf->m_p2;
73 BasicSerializer::Impl2* recv_p2 = recv_buf->m_p2;
74
75 Span<const Real> send_real = sbuf_p2->realBytes();
76 Span<const Int16> send_int16 = sbuf_p2->int16Bytes();
77 Span<const Int32> send_int32 = sbuf_p2->int32Bytes();
78 Span<const Int64> send_int64 = sbuf_p2->int64Bytes();
79 Span<const Byte> send_byte = sbuf_p2->byteBytes();
80 Span<const Int8> send_int8 = sbuf_p2->int8Bytes();
81 Span<const Float16> send_float16 = sbuf_p2->float16Bytes();
82 Span<const BFloat16> send_bfloat16 = sbuf_p2->bfloat16Bytes();
83 Span<const Float32> send_float32 = sbuf_p2->float32Bytes();
84 Span<const Float128> send_float128 = sbuf_p2->float128Bytes();
85 Span<const Int128> send_int128 = sbuf_p2->int128Bytes();
86
87 Int64 sizes[11];
88 sizes[0] = send_real.size();
89 sizes[1] = send_int16.size();
90 sizes[2] = send_int32.size();
91 sizes[3] = send_int64.size();
92 sizes[4] = send_byte.size();
93 sizes[5] = send_int8.size();
94 sizes[6] = send_float16.size();
95 sizes[7] = send_bfloat16.size();
96 sizes[8] = send_float32.size();
97 sizes[9] = send_float128.size();
98 sizes[10] = send_int128.size();
99
100 mpAllReduce(pm, MessagePassing::ReduceSum, Int64ArrayView(11, sizes));
101
102 Int64 recv_nb_real = sizes[0];
103 Int64 recv_nb_int16 = sizes[1];
104 Int64 recv_nb_int32 = sizes[2];
105 Int64 recv_nb_int64 = sizes[3];
106 Int64 recv_nb_byte = sizes[4];
107 Int64 recv_nb_int8 = sizes[5];
108 Int64 recv_nb_float16 = sizes[6];
109 Int64 recv_nb_bfloat16 = sizes[7];
110 Int64 recv_nb_float32 = sizes[8];
111 Int64 recv_nb_float128 = sizes[9];
112 Int64 recv_nb_int128 = sizes[10];
113
114 if (recv_nb_float16 != 0)
115 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'float16' is not yet implemented");
116 if (recv_nb_bfloat16 != 0)
117 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'bfloat16' is not yet implemented");
118 if (recv_nb_float128 != 0)
119 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'float128' is not yet implemented");
120 if (recv_nb_int128 != 0)
121 ARCCORE_THROW(NotImplementedException, "AllGather with serialized type 'int128' is not yet implemented");
122
123 recv_p2->allocateBuffer(recv_nb_real, recv_nb_int16, recv_nb_int32, recv_nb_int64, recv_nb_byte,
124 recv_nb_int8, recv_nb_float16, recv_nb_bfloat16, recv_nb_float32, recv_nb_float128, recv_nb_int128);
125
126 auto recv_p = recv_buf->_p();
127
128 _doGatherOne(pm, send_real, recv_p->getRealBuffer());
129 _doGatherOne(pm, send_int32, recv_p->getInt32Buffer());
130 _doGatherOne(pm, send_int16, recv_p->getInt16Buffer());
131 _doGatherOne(pm, send_int64, recv_p->getInt64Buffer());
132 _doGatherOne(pm, send_byte, recv_p->getByteBuffer());
133 _doGatherOne(pm, send_int8, recv_p->getInt8Buffer());
134 _doGatherOne(pm, send_float32, recv_p->getFloat32Buffer());
135}
136
137} // namespace Arccore
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
143{
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147/*!
148 * \brief Créé une liste de requêtes.
149 *
150 * \sa IRequestList
151 */
152Ref<IRequestList>
154{
155 auto d = pm->dispatchers()->controlDispatcher();
156 return d->createRequestListRef();
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
163{
164 auto d = pm->dispatchers()->controlDispatcher();
165 d->waitAllRequests(requests);
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
172{
173 mpWaitAll(pm, ArrayView<Request>(1, &request));
174}
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
180{
181 auto d = pm->dispatchers()->controlDispatcher();
182 d->waitSomeRequests(requests, indexes, false);
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
189{
190 auto d = pm->dispatchers()->controlDispatcher();
191 d->waitSomeRequests(requests, indexes, true);
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
198 ArrayView<bool> indexes, eWaitType w_type)
199{
200 switch (w_type) {
201 case WaitAll:
202 mpWaitAll(pm, requests);
203 indexes.fill(true);
204 break;
205 case WaitSome:
206 mpWaitSome(pm, requests, indexes);
207 break;
209 mpTestSome(pm, requests, indexes);
210 break;
211 }
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217MessageId
219{
220 auto d = pm->dispatchers()->controlDispatcher();
221 return d->probe(message);
222}
223
224/*---------------------------------------------------------------------------*/
225/*---------------------------------------------------------------------------*/
226
227MessageSourceInfo
229{
230 auto d = pm->dispatchers()->controlDispatcher();
231 return d->legacyProbe(message);
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
237IMessagePassingMng*
239{
240 auto d = pm->dispatchers()->controlDispatcher();
241 return d->commSplit(keep);
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
248{
249 auto d = pm->dispatchers()->controlDispatcher();
250 d->barrier();
251}
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
256Request
258{
259 auto d = pm->dispatchers()->controlDispatcher();
260 return d->nonBlockingBarrier();
261}
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
266Ref<ISerializeMessageList>
268{
269 auto d = pm->dispatchers()->serializeDispatcher();
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
276Request
278 const PointToPointMessageInfo& message)
279{
280 auto d = pm->dispatchers()->serializeDispatcher();
281 return d->sendSerializer(values, message);
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
287Request
289 const PointToPointMessageInfo& message)
290{
291 auto d = pm->dispatchers()->serializeDispatcher();
292 return d->receiveSerializer(values, message);
293}
294
295/*---------------------------------------------------------------------------*/
296/*---------------------------------------------------------------------------*/
297
298MessageSourceInfo IControlDispatcher::
299legacyProbe(const PointToPointMessageInfo&)
300{
301 ARCCORE_THROW(NotSupportedException, "pure virtual call to legacyProbe()");
302}
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
307void mpAllGather(IMessagePassingMng* pm, const ISerializer* send_serializer, ISerializer* receive_serialize)
308{
309 auto* s = dynamic_cast<const BasicSerializer*>(send_serializer);
310 if (!s)
311 ARCCORE_FATAL("send_serializer is not a BasicSerializer");
312 auto* r = dynamic_cast<BasicSerializer*>(receive_serialize);
313 if (!r)
314 ARCCORE_FATAL("receive_serializer is not a BasicSerializer");
316 message.doAllGather(pm, s, r);
317}
318
319/*---------------------------------------------------------------------------*/
320/*---------------------------------------------------------------------------*/
321namespace
322{
323 template <typename DataType> inline ITypeDispatcher<DataType>*
324 _getDispatcher(IMessagePassingMng* pm)
325 {
326 ARCCORE_CHECK_POINTER(pm);
327 DataType* x = nullptr;
328 auto* dispatcher = pm->dispatchers()->dispatcher(x);
329 ARCCORE_CHECK_POINTER(dispatcher);
330 return dispatcher;
331 }
332} // namespace
333
334#define ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(type) \
335 void mpAllGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf) \
336 { \
337 _getDispatcher<type>(pm)->allGather(send_buf, recv_buf); \
338 } \
339 void mpGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 rank) \
340 { \
341 _getDispatcher<type>(pm)->gather(send_buf, recv_buf, rank); \
342 } \
343 Request mpNonBlockingAllGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf) \
344 { \
345 return _getDispatcher<type>(pm)->nonBlockingAllGather(send_buf, recv_buf); \
346 } \
347 Request mpNonBlockingGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 rank) \
348 { \
349 return _getDispatcher<type>(pm)->nonBlockingGather(send_buf, recv_buf, rank); \
350 } \
351 void mpAllGatherVariable(IMessagePassingMng* pm, Span<const type> send_buf, Array<type>& recv_buf) \
352 { \
353 _getDispatcher<type>(pm)->allGatherVariable(send_buf, recv_buf); \
354 } \
355 void mpGatherVariable(IMessagePassingMng* pm, Span<const type> send_buf, Array<type>& recv_buf, Int32 rank) \
356 { \
357 _getDispatcher<type>(pm)->gatherVariable(send_buf, recv_buf, rank); \
358 } \
359 Request mpGather(IMessagePassingMng* pm, GatherMessageInfo<type>& gather_info) \
360 { \
361 return _getDispatcher<type>(pm)->gather(gather_info); \
362 } \
363 void mpScatterVariable(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 root) \
364 { \
365 return _getDispatcher<type>(pm)->scatterVariable(send_buf, recv_buf, root); \
366 } \
367 type mpAllReduce(IMessagePassingMng* pm, eReduceType rt, type v) \
368 { \
369 return _getDispatcher<type>(pm)->allReduce(rt, v); \
370 } \
371 void mpAllReduce(IMessagePassingMng* pm, eReduceType rt, Span<type> buf) \
372 { \
373 _getDispatcher<type>(pm)->allReduce(rt, buf); \
374 } \
375 Request mpNonBlockingAllReduce(IMessagePassingMng* pm, eReduceType rt, Span<const type> send_buf, Span<type> recv_buf) \
376 { \
377 return _getDispatcher<type>(pm)->nonBlockingAllReduce(rt, send_buf, recv_buf); \
378 } \
379 void mpBroadcast(IMessagePassingMng* pm, Span<type> send_buf, Int32 rank) \
380 { \
381 _getDispatcher<type>(pm)->broadcast(send_buf, rank); \
382 } \
383 Request mpNonBlockingBroadcast(IMessagePassingMng* pm, Span<type> send_buf, Int32 rank) \
384 { \
385 return _getDispatcher<type>(pm)->nonBlockingBroadcast(send_buf, rank); \
386 } \
387 void mpSend(IMessagePassingMng* pm, Span<const type> values, Int32 rank) \
388 { \
389 _getDispatcher<type>(pm)->send(values, rank, true); \
390 } \
391 void mpReceive(IMessagePassingMng* pm, Span<type> values, Int32 rank) \
392 { \
393 _getDispatcher<type>(pm)->receive(values, rank, true); \
394 } \
395 Request mpSend(IMessagePassingMng* pm, Span<const type> values, Int32 rank, bool is_blocked) \
396 { \
397 return _getDispatcher<type>(pm)->send(values, rank, is_blocked); \
398 } \
399 Request mpSend(IMessagePassingMng* pm, Span<const type> values, const PointToPointMessageInfo& message) \
400 { \
401 return _getDispatcher<type>(pm)->send(values, message); \
402 } \
403 Request mpReceive(IMessagePassingMng* pm, Span<type> values, Int32 rank, bool is_blocked) \
404 { \
405 return _getDispatcher<type>(pm)->receive(values, rank, is_blocked); \
406 } \
407 Request mpReceive(IMessagePassingMng* pm, Span<type> values, const PointToPointMessageInfo& message) \
408 { \
409 return _getDispatcher<type>(pm)->receive(values, message); \
410 } \
411 void mpAllToAll(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 count) \
412 { \
413 return _getDispatcher<type>(pm)->allToAll(send_buf, recv_buf, count); \
414 } \
415 Request mpNonBlockingAllToAll(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 count) \
416 { \
417 return _getDispatcher<type>(pm)->nonBlockingAllToAll(send_buf, recv_buf, count); \
418 } \
419 void mpAllToAllVariable(IMessagePassingMng* pm, Span<const type> send_buf, ConstArrayView<Int32> send_count, \
420 ConstArrayView<Int32> send_index, Span<type> recv_buf, \
421 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) \
422 { \
423 _getDispatcher<type>(pm)->allToAllVariable(send_buf, send_count, send_index, recv_buf, recv_count, recv_index); \
424 } \
425 Request mpNonBlockingAllToAllVariable(IMessagePassingMng* pm, Span<const type> send_buf, ConstArrayView<Int32> send_count, \
426 ConstArrayView<Int32> send_index, Span<type> recv_buf, \
427 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) \
428 { \
429 return _getDispatcher<type>(pm)->nonBlockingAllToAllVariable(send_buf, send_count, send_index, recv_buf, recv_count, recv_index); \
430 }
431
432/*---------------------------------------------------------------------------*/
433/*---------------------------------------------------------------------------*/
434
435ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(char)
436ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(signed char)
437ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned char)
438
439ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(short)
440ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned short)
441ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(int)
442ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned int)
443ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long)
444ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned long)
445ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long long)
446ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned long long)
447
448ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(float)
449ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(double)
450ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long double)
451
452ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(BFloat16)
453ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(Float16)
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
458} // namespace Arccore::MessagePassing
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
Liste des fonctions d'échange de message.
Vue modifiable d'un tableau d'un type T.
void fill(const T &o) noexcept
Remplit le tableau avec la valeur o.
virtual Ref< IRequestList > createRequestListRef()=0
Création d'une liste de requêtes associé à ce gestionnaire.
Interface du gestionnaire des échanges de messages.
virtual Request receiveSerializer(ISerializer *s, const PointToPointMessageInfo &message)=0
Message de réception.
virtual Ref< ISerializeMessageList > createSerializeMessageListRef()=0
Créé une liste de messages de sérialisation.
virtual Request sendSerializer(const ISerializer *s, const PointToPointMessageInfo &message)=0
Message d'envoi.
Informations pour envoyer/recevoir un message point à point.
Requête d'un message.
Definition Request.h:77
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:209
__host__ __device__ void copy(const U &copy_array)
Recopie le tableau copy_array dans l'instance.
Definition Span.h:357
Vue d'un tableau d'éléments de type T.
Definition Span.h:510
Vecteur 1D de données avec sémantique par valeur (style STL).
Espace de nommage contenant les types et déclarations qui gèrent le mécanisme de parallélisme par éch...
void mpWaitSome(IMessagePassingMng *pm, ArrayView< Request > requests, ArrayView< bool > indexes)
Bloque jusqu'à ce qu'au moins une des requêtes de request soit terminée.
Definition Messages.cc:179
IMessagePassingMng * mpSplit(IMessagePassingMng *pm, bool keep)
Créé une nouvelle instance de IMessagePassingMng.
Definition Messages.cc:238
Request mpReceive(IMessagePassingMng *pm, ISerializer *values, const PointToPointMessageInfo &message)
Message de réception utilisant un ISerializer.
Definition Messages.cc:288
void mpBarrier(IMessagePassingMng *pm)
Effectue une barrière.
Definition Messages.cc:247
MessageId mpProbe(IMessagePassingMng *pm, const PointToPointMessageInfo &message)
Teste si un message est disponible.
Definition Messages.cc:218
Ref< IRequestList > mpCreateRequestListRef(IMessagePassingMng *pm)
Créé une liste de requêtes.
Definition Messages.cc:153
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *receive_serialize)
Message allGather() pour une sérialisation.
Definition Messages.cc:307
void mpWaitAll(IMessagePassingMng *pm, ArrayView< Request > requests)
Bloque tant que les requêtes de requests ne sont pas terminées.
Definition Messages.cc:162
Request mpNonBlockingBarrier(IMessagePassingMng *pm)
Effectue une barrière non bloquante.
Definition Messages.cc:257
void mpTestSome(IMessagePassingMng *pm, ArrayView< Request > requests, ArrayView< bool > indexes)
Teste si des requêtes de request sont terminées.
Definition Messages.cc:188
@ WaitSome
Attend que tous les messages de la liste soient traités.
Ref< ISerializeMessageList > mpCreateSerializeMessageListRef(IMessagePassingMng *pm)
Créé une liste de messages de sérialisation.
Definition Messages.cc:267
@ ReduceSum
Somme des valeurs.
Request mpSend(IMessagePassingMng *pm, const ISerializer *values, const PointToPointMessageInfo &message)
Message d'envoi utilisant un ISerializer.
Definition Messages.cc:277
void mpWait(IMessagePassingMng *pm, Request request)
Bloque jusqu'à ce que la requête request soit terminée.
Definition Messages.cc:171
MessageSourceInfo mpLegacyProbe(IMessagePassingMng *pm, const PointToPointMessageInfo &message)
Teste si un message est disponible.
Definition Messages.cc:228
Espace de nom de Arccore.
Definition ArcaneTypes.h:24
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition BaseTypes.h:121
std::int64_t Int64
Type entier signé sur 64 bits.