Arcane  v4.1.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Messages.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* 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/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
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: ne supporte pas encore les types 'Float16', 'BFloat16'
68 // 'Float128' et 'Int128' car ces derniers ne sont pas supportés
69 // dans les messages MPI.
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/*---------------------------------------------------------------------------*/
153Ref<IRequestList>
155{
156 auto d = pm->dispatchers()->controlDispatcher();
157 return d->createRequestListRef();
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
164{
165 auto d = pm->dispatchers()->controlDispatcher();
166 d->waitAllRequests(requests);
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
173{
174 mpWaitAll(pm, ArrayView<Request>(1, &request));
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
181{
182 auto d = pm->dispatchers()->controlDispatcher();
183 d->waitSomeRequests(requests, indexes, false);
184}
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
190{
191 auto d = pm->dispatchers()->controlDispatcher();
192 d->waitSomeRequests(requests, indexes, true);
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
199 ArrayView<bool> indexes, eWaitType w_type)
200{
201 switch (w_type) {
202 case WaitAll:
203 mpWaitAll(pm, requests);
204 indexes.fill(true);
205 break;
206 case WaitSome:
207 mpWaitSome(pm, requests, indexes);
208 break;
210 mpTestSome(pm, requests, indexes);
211 break;
212 }
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
220{
221 auto d = pm->dispatchers()->controlDispatcher();
222 return d->probe(message);
223}
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
230{
231 auto d = pm->dispatchers()->controlDispatcher();
232 return d->legacyProbe(message);
233}
234
235/*---------------------------------------------------------------------------*/
236/*---------------------------------------------------------------------------*/
237
240{
241 auto d = pm->dispatchers()->controlDispatcher();
242 return d->commSplit(keep);
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
249{
250 auto d = pm->dispatchers()->controlDispatcher();
251 d->barrier();
252}
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
256
259{
260 auto d = pm->dispatchers()->controlDispatcher();
261 return d->nonBlockingBarrier();
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
269{
270 auto d = pm->dispatchers()->serializeDispatcher();
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
279 const PointToPointMessageInfo& message)
280{
281 auto d = pm->dispatchers()->serializeDispatcher();
282 return d->sendSerializer(values, message);
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
290 const PointToPointMessageInfo& message)
291{
292 auto d = pm->dispatchers()->serializeDispatcher();
293 return d->receiveSerializer(values, message);
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
299MessageSourceInfo IControlDispatcher::
300legacyProbe(const PointToPointMessageInfo&)
301{
302 ARCCORE_THROW(NotSupportedException, "pure virtual call to legacyProbe()");
303}
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
308void mpAllGather(IMessagePassingMng* pm, const ISerializer* send_serializer, ISerializer* receive_serialize)
309{
310 auto* s = dynamic_cast<const BasicSerializer*>(send_serializer);
311 if (!s)
312 ARCCORE_FATAL("send_serializer is not a BasicSerializer");
313 auto* r = dynamic_cast<BasicSerializer*>(receive_serialize);
314 if (!r)
315 ARCCORE_FATAL("receive_serializer is not a BasicSerializer");
317 message.doAllGather(pm, s, r);
318}
319
320/*---------------------------------------------------------------------------*/
321/*---------------------------------------------------------------------------*/
322
325{
326 return internal::BasicSerializeMessage::create(MessageRank(pm->commRank()), target, type);
327}
328
331{
332 return internal::BasicSerializeMessage::create(MessageRank(pm->commRank()), id);
333}
334
335ARCCORE_MESSAGEPASSING_EXPORT Ref<ISerializeMessage>
337{
338 return mpCreateSerializeMessage(pm, destination, ePointToPointMessageType::MsgSend);
339}
340
341ARCCORE_MESSAGEPASSING_EXPORT Ref<ISerializeMessage>
343{
344 return mpCreateSerializeMessage(pm, source, ePointToPointMessageType::MsgReceive);
345}
346
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
349
350namespace
351{
352 template <typename DataType> inline ITypeDispatcher<DataType>*
353 _getDispatcher(IMessagePassingMng* pm)
354 {
356 DataType* x = nullptr;
357 auto* dispatcher = pm->dispatchers()->dispatcher(x);
358 ARCCORE_CHECK_POINTER(dispatcher);
359 return dispatcher;
360 }
361} // namespace
362
363#define ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(type) \
364 void mpAllGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf) \
365 { \
366 _getDispatcher<type>(pm)->allGather(send_buf, recv_buf); \
367 } \
368 void mpGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 rank) \
369 { \
370 _getDispatcher<type>(pm)->gather(send_buf, recv_buf, rank); \
371 } \
372 Request mpNonBlockingAllGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf) \
373 { \
374 return _getDispatcher<type>(pm)->nonBlockingAllGather(send_buf, recv_buf); \
375 } \
376 Request mpNonBlockingGather(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 rank) \
377 { \
378 return _getDispatcher<type>(pm)->nonBlockingGather(send_buf, recv_buf, rank); \
379 } \
380 void mpAllGatherVariable(IMessagePassingMng* pm, Span<const type> send_buf, Array<type>& recv_buf) \
381 { \
382 _getDispatcher<type>(pm)->allGatherVariable(send_buf, recv_buf); \
383 } \
384 void mpGatherVariable(IMessagePassingMng* pm, Span<const type> send_buf, Array<type>& recv_buf, Int32 rank) \
385 { \
386 _getDispatcher<type>(pm)->gatherVariable(send_buf, recv_buf, rank); \
387 } \
388 Request mpGather(IMessagePassingMng* pm, GatherMessageInfo<type>& gather_info) \
389 { \
390 return _getDispatcher<type>(pm)->gather(gather_info); \
391 } \
392 void mpScatterVariable(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 root) \
393 { \
394 return _getDispatcher<type>(pm)->scatterVariable(send_buf, recv_buf, root); \
395 } \
396 type mpAllReduce(IMessagePassingMng* pm, eReduceType rt, type v) \
397 { \
398 return _getDispatcher<type>(pm)->allReduce(rt, v); \
399 } \
400 void mpAllReduce(IMessagePassingMng* pm, eReduceType rt, Span<type> buf) \
401 { \
402 _getDispatcher<type>(pm)->allReduce(rt, buf); \
403 } \
404 Request mpNonBlockingAllReduce(IMessagePassingMng* pm, eReduceType rt, Span<const type> send_buf, Span<type> recv_buf) \
405 { \
406 return _getDispatcher<type>(pm)->nonBlockingAllReduce(rt, send_buf, recv_buf); \
407 } \
408 void mpBroadcast(IMessagePassingMng* pm, Span<type> send_buf, Int32 rank) \
409 { \
410 _getDispatcher<type>(pm)->broadcast(send_buf, rank); \
411 } \
412 Request mpNonBlockingBroadcast(IMessagePassingMng* pm, Span<type> send_buf, Int32 rank) \
413 { \
414 return _getDispatcher<type>(pm)->nonBlockingBroadcast(send_buf, rank); \
415 } \
416 void mpSend(IMessagePassingMng* pm, Span<const type> values, Int32 rank) \
417 { \
418 _getDispatcher<type>(pm)->send(values, rank, true); \
419 } \
420 void mpReceive(IMessagePassingMng* pm, Span<type> values, Int32 rank) \
421 { \
422 _getDispatcher<type>(pm)->receive(values, rank, true); \
423 } \
424 Request mpSend(IMessagePassingMng* pm, Span<const type> values, Int32 rank, bool is_blocked) \
425 { \
426 return _getDispatcher<type>(pm)->send(values, rank, is_blocked); \
427 } \
428 Request mpSend(IMessagePassingMng* pm, Span<const type> values, const PointToPointMessageInfo& message) \
429 { \
430 return _getDispatcher<type>(pm)->send(values, message); \
431 } \
432 Request mpReceive(IMessagePassingMng* pm, Span<type> values, Int32 rank, bool is_blocked) \
433 { \
434 return _getDispatcher<type>(pm)->receive(values, rank, is_blocked); \
435 } \
436 Request mpReceive(IMessagePassingMng* pm, Span<type> values, const PointToPointMessageInfo& message) \
437 { \
438 return _getDispatcher<type>(pm)->receive(values, message); \
439 } \
440 void mpAllToAll(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 count) \
441 { \
442 return _getDispatcher<type>(pm)->allToAll(send_buf, recv_buf, count); \
443 } \
444 Request mpNonBlockingAllToAll(IMessagePassingMng* pm, Span<const type> send_buf, Span<type> recv_buf, Int32 count) \
445 { \
446 return _getDispatcher<type>(pm)->nonBlockingAllToAll(send_buf, recv_buf, count); \
447 } \
448 void mpAllToAllVariable(IMessagePassingMng* pm, Span<const type> send_buf, ConstArrayView<Int32> send_count, \
449 ConstArrayView<Int32> send_index, Span<type> recv_buf, \
450 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) \
451 { \
452 _getDispatcher<type>(pm)->allToAllVariable(send_buf, send_count, send_index, recv_buf, recv_count, recv_index); \
453 } \
454 Request mpNonBlockingAllToAllVariable(IMessagePassingMng* pm, Span<const type> send_buf, ConstArrayView<Int32> send_count, \
455 ConstArrayView<Int32> send_index, Span<type> recv_buf, \
456 ConstArrayView<Int32> recv_count, ConstArrayView<Int32> recv_index) \
457 { \
458 return _getDispatcher<type>(pm)->nonBlockingAllToAllVariable(send_buf, send_count, send_index, recv_buf, recv_count, recv_index); \
459 }
460
461/*---------------------------------------------------------------------------*/
462/*---------------------------------------------------------------------------*/
463
464ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(char)
465ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(signed char)
466ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned char)
467
468ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(short)
469ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned short)
470ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(int)
471ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned int)
472ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long)
473ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned long)
474ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long long)
475ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(unsigned long long)
476
477ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(float)
478ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(double)
479ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(long double)
480
481ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(BFloat16)
482ARCCORE_GENERATE_MESSAGEPASSING_DEFINITION(Float16)
483
484/*---------------------------------------------------------------------------*/
485/*---------------------------------------------------------------------------*/
486
487} // namespace Arccore::MessagePassing
488
489/*---------------------------------------------------------------------------*/
490/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCCORE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCCORE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
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.
Implémentation basique de 'ISerializer'.
virtual Ref< IRequestList > createRequestListRef()=0
Création d'une liste de requêtes associé à ce gestionnaire.
Interface du gestionnaire des échanges de messages.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Request receiveSerializer(ISerializer *s, const PointToPointMessageInfo &message)=0
Message de réception.
virtual Request sendSerializer(const ISerializer *s, const PointToPointMessageInfo &message)=0
Message d'envoi.
virtual Ref< ISerializeMessageList > createSerializeMessageListRef()=0
Créé une liste de messages de sérialisation.
Gestion des messages parallèles pour le type Type.
Informations sur la source d'un message.
Informations pour envoyer/recevoir un message point à point.
Requête d'un message.
Definition Request.h:77
Exception lorsqu'une fonction n'est pas implémentée.
Exception lorsqu'une opération n'est pas supportée.
Référence à une instance.
__host__ __device__ void copy(const U &copy_array)
Recopie le tableau copy_array dans l'instance.
Definition Span.h:475
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:325
Vue d'un tableau d'éléments de type T.
Definition Span.h:633
Vecteur 1D de données avec sémantique par valeur (style STL).
Déclarations des types et méthodes utilisés par les mécanismes d'échange de messages.
Ref< ISerializeMessage > mpCreateSerializeMessage(IMessagePassingMng *pm, MessageRank target, ePointToPointMessageType type)
Créé un message de sérialisation.
Definition Messages.cc:324
void mpTestSome(IMessagePassingMng *pm, ArrayView< Request > requests, ArrayView< bool > indexes)
Teste si des requêtes de request sont terminées.
Definition Messages.cc:189
Ref< ISerializeMessageList > mpCreateSerializeMessageListRef(IMessagePassingMng *pm)
Créé une liste de messages de sérialisation.
Definition Messages.cc:268
Ref< ISerializeMessage > mpCreateSendSerializeMessage(IMessagePassingMng *pm, MessageRank destination)
Créé un message de sérialisation en envoi.
Definition Messages.cc:336
MessageSourceInfo mpLegacyProbe(IMessagePassingMng *pm, const PointToPointMessageInfo &message)
Teste si un message est disponible.
Definition Messages.cc:229
Ref< ISerializeMessage > mpCreateReceiveSerializeMessage(IMessagePassingMng *pm, MessageRank source)
Créé un message de sérialisation en envoi.
Definition Messages.cc:342
MessageId mpProbe(IMessagePassingMng *pm, const PointToPointMessageInfo &message)
Teste si un message est disponible.
Definition Messages.cc:219
C char mpAllReduce(IMessagePassingMng *pm, eReduceType rt, char v)
Ref< IRequestList > mpCreateRequestListRef(IMessagePassingMng *pm)
Créé une liste de requêtes.
Definition Messages.cc:154
C void mpAllGatherVariable(IMessagePassingMng *pm, Span< const char > send_buf, Array< char > &recv_buf)
@ WaitSome
Attend que tous les messages de la liste soient traités.
void mpBarrier(IMessagePassingMng *pm)
Effectue une barrière.
Definition Messages.cc:248
Request mpNonBlockingBarrier(IMessagePassingMng *pm)
Effectue une barrière non bloquante.
Definition Messages.cc:258
void mpWait(IMessagePassingMng *pm, Request request)
Bloque jusqu'à ce que la requête request soit terminée.
Definition Messages.cc:172
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *receive_serialize)
Message allGather() pour une sérialisation.
Definition Messages.cc:308
void mpWaitAll(IMessagePassingMng *pm, ArrayView< Request > requests)
Bloque tant que les requêtes de requests ne sont pas terminées.
Definition Messages.cc:163
IMessagePassingMng * mpSplit(IMessagePassingMng *pm, bool keep)
Créé une nouvelle instance de IMessagePassingMng.
Definition Messages.cc:239
ePointToPointMessageType
Type de message point à point.
@ ReduceSum
Somme des valeurs.
Request mpReceive(IMessagePassingMng *pm, ISerializer *values, const PointToPointMessageInfo &message)
Message de réception utilisant un ISerializer.
Definition Messages.cc:289
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:180
Request mpSend(IMessagePassingMng *pm, const ISerializer *values, const PointToPointMessageInfo &message)
Message d'envoi utilisant un ISerializer.
Definition Messages.cc:278
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.