Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Array2Data.inst.h
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/* Array2Data.inst.h (C) 2000-2026 */
9/* */
10/* Donnée du type 'Array2'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/Array2Data.h"
15
16#include "arccore/common/AlignedMemoryAllocator.h"
17
18#include "arcane/utils/NotSupportedException.h"
19#include "arcane/utils/Real2.h"
20#include "arcane/utils/Real2x2.h"
21#include "arcane/utils/Real3.h"
22#include "arcane/utils/Real3x3.h"
23#include "arcane/utils/IHashAlgorithm.h"
24#include "arcane/utils/NotImplementedException.h"
25#include "arcane/utils/ArgumentException.h"
26#include "arcane/utils/FatalErrorException.h"
27#include "arcane/utils/ITraceMng.h"
28#include "arcane/utils/CheckedConvert.h"
29#include "arcane/utils/MemoryAllocator.h"
31
32#include "arcane/core/datatype/DataStorageBuildInfo.h"
33#include "arcane/core/datatype/IDataOperation.h"
34
35#include "arcane/core/ISerializer.h"
36
37#include "arcane/impl/SerializedData.h"
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42namespace Arcane
43{
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48namespace
49{
50 inline constexpr Int64 SERIALIZE2_MAGIC_NUMBER = 0x12ff7789;
51}
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56template <typename DataType> Array2DataT<DataType>::
58: m_value(AlignedMemoryAllocator::Simd())
59, m_trace(trace)
60, m_internal(new Impl(this))
61{
62}
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
67template <typename DataType> Array2DataT<DataType>::
68Array2DataT(const Array2DataT<DataType>& rhs)
69: m_value(AlignedMemoryAllocator::Simd())
70, m_trace(rhs.m_trace)
71, m_internal(new Impl(this))
72, m_allocation_info(rhs.m_allocation_info)
73{
74 m_value = rhs.m_value;
75}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80template <typename DataType> Array2DataT<DataType>::
81Array2DataT(const DataStorageBuildInfo& dsbi)
82: m_value(dsbi.memoryAllocator())
83, m_trace(dsbi.traceMng())
84, m_internal(new Impl(this))
85{
86}
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91template <typename DataType> Array2DataT<DataType>::
92~Array2DataT()
93{
94 delete m_internal;
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103template <typename DataType> DataStorageTypeInfo Array2DataT<DataType>::
104staticStorageTypeInfo()
105{
106 typedef DataTypeTraitsT<DataType> TraitsType;
107 eBasicDataType bdt = TraitsType::basicDataType();
108 Int32 nb_basic_type = TraitsType::nbBasicType();
109 Int32 dimension = 2;
110 Int32 multi_tag = 0;
111 return DataStorageTypeInfo(bdt, nb_basic_type, dimension, multi_tag);
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117template <typename DataType> DataStorageTypeInfo Array2DataT<DataType>::
118storageTypeInfo() const
119{
120 return staticStorageTypeInfo();
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126template <typename DataType> void Array2DataT<DataType>::
127resize(Integer new_size)
128{
129 m_value.resize(new_size);
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
135template <typename DataType> Ref<ISerializedData> Array2DataT<DataType>::
136createSerializedDataRef(bool use_basic_type) const
137{
138 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
139
140 Int64 nb_count = 1;
141 eDataType data_type = dataType();
142 Int64 type_size = sizeof(DataType);
143
144 if (use_basic_type) {
147 type_size = sizeof(BasicType);
148 }
149
150 Int64 nb_element = m_value.totalNbElement();
151 Int64 nb_base_element = nb_element * nb_count;
152 Int64 full_size = nb_base_element * type_size;
153 const Byte* bt = reinterpret_cast<const Byte*>(m_value.to1DSpan().data());
154 Span<const Byte> base_values(bt, full_size);
155 UniqueArray<Int64> dimensions;
156 dimensions.resize(2);
157 dimensions[0] = m_value.dim1Size();
158 dimensions[1] = m_value.dim2Size();
159
160 auto sd = arcaneCreateSerializedDataRef(data_type, base_values.size(), 2, nb_element,
161 nb_base_element, false, dimensions, shape());
162 sd->setConstBytes(base_values);
163 return sd;
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
169template <typename DataType> void Array2DataT<DataType>::
170allocateBufferForSerializedData(ISerializedData* sdata)
171{
172 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
173
174 eDataType data_type = sdata->baseDataType();
176
177 if (data_type != dataType() && data_type == base_data_type)
178 ARCANE_FATAL("Bad serialized type");
179 bool is_multi_size = sdata->isMultiSize();
180 if (is_multi_size)
181 ARCANE_FATAL("Can not allocate multi-size array");
182
183 Int64 dim1_size = sdata->extents()[0];
184 Int64 dim2_size = sdata->extents()[1];
185 //m_trace->info() << " ASSIGN DATA dim1=" << dim1_size
186 // << " dim2=" << dim2_size
187 // << " addr=" << m_value.viewAsArray().unguardedBasePointer();
188
189 m_value.resize(dim1_size, dim2_size);
190 m_shape = sdata->shape();
191
192 Byte* byte_data = reinterpret_cast<Byte*>(m_value.to1DSpan().data());
193 Span<Byte> bytes_view(byte_data, sdata->memorySize());
194 sdata->setWritableBytes(bytes_view);
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
200template <typename DataType> void Array2DataT<DataType>::
201assignSerializedData(const ISerializedData* sdata)
202{
203 ARCANE_UNUSED(sdata);
204 // Rien à faire car \a sdata pointe directement vers m_value
205}
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
210template <typename DataType> void Array2DataT<DataType>::
211serialize(ISerializer* sbuf, IDataOperation* operation)
212{
214 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
216
217 ISerializer::eMode mode = sbuf->mode();
218 if (mode == ISerializer::ModeReserve) {
219 // Réserve la mémoire pour
220 // - le nombre d'éléments de la première dimension
221 // - le nombre d'éléments de la deuxième dimension
222 // - le nombre d'éléments de ids.
223 // - le nombre magique pour verification
225 // Réserve la mémoire pour les valeurs
226 Int64 total_nb_element = m_value.totalNbElement();
227 sbuf->reserveSpan(data_type, total_nb_element * nb_count);
228 }
229 else if (mode == ISerializer::ModePut) {
230 Int64 count = m_value.dim1Size();
231 Int64 total = m_value.totalNbElement();
232 Int64 n[4];
233 n[0] = count;
234 n[1] = m_value.dim2Size();
235 n[2] = total;
236 n[3] = SERIALIZE2_MAGIC_NUMBER;
237 sbuf->putSpan(Span<const Int64>(n, 4));
238 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data());
239 Span<const BasicType> v(bt, total * nb_count);
240 //m_trace->info() << "PUT array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType);
241 sbuf->putSpan(v);
242 }
243 else if (mode == ISerializer::ModeGet) {
244 Int64 n[4] = { 0, 0, 0, 0 };
245 sbuf->getSpan(Span<Int64>(n, 4));
246 Int64 count = n[0];
247 Int64 dim2_size = n[1];
248 Int64 total = n[2];
249 if (n[3] != SERIALIZE2_MAGIC_NUMBER)
250 ARCANE_FATAL("Bad magic number");
251 switch (sbuf->readMode()) {
253 //m_trace->info() << "READ REPLACE count=" << count << " dim2_size=" << dim2_size;
254 m_value.resize(count, dim2_size);
255 if (operation)
256 throw NotImplementedException(A_FUNCINFO, "serialize(ReadReplace) with IDataOperation");
257 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data());
258 Span<BasicType> v(bt, total * nb_count);
259 sbuf->getSpan(v);
260 } break;
262 Int64 current_size = m_value.dim1Size();
263 Int64 current_total = m_value.totalNbElement();
264 //m_trace->info() << "READ ADD NEW_SIZE=" << current_size << " COUNT=" << count
265 // << " dim2_size=" << dim2_size << " current_dim2_size=" << m_value.dim2Size()
266 // << " current_total=" << current_total << " read_elem=" << (total*nb_count);
267 m_value.resize(current_size + count, dim2_size);
268 if (operation)
269 throw NotImplementedException(A_FUNCINFO, "serialize(ReadAdd) with IDataOperation");
270 BasicType* bt = reinterpret_cast<BasicType*>(m_value.to1DSpan().data() + current_total);
271 //m_trace->info() << "GET array nb_elem=" << (total*nb_count) << " sizeof=" << sizeof(BasicType);
272 Span<BasicType> v(bt, total * nb_count);
273 sbuf->getSpan(v);
274 } break;
275 }
276 }
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
282template <typename DataType> void Array2DataT<DataType>::
283serialize(ISerializer* sbuf, Int32ConstArrayView ids, IDataOperation* operation)
284{
286 typedef typename DataTypeTraitsT<DataType>::BasicType BasicType;
288
289 ISerializer::eMode mode = sbuf->mode();
290 if (mode == ISerializer::ModeReserve) {
291 // Réserve la mémoire pour
292 // - le nombre d'éléments de la première dimension
293 // - le nombre d'éléments de la deuxième dimension
294 // - le nombre d'éléments de ids.
295 // - le nombre magique pour verification
297 // Réserve la mémoire pour les valeurs
298 Int64 total_nb_value = ((Int64)ids.size()) * ((Int64)m_value.dim2Size());
299 sbuf->reserveSpan(data_type, total_nb_value * nb_count);
300 }
301 else if (mode == ISerializer::ModePut) {
302 Int32 count = ids.size();
303 Int64 dim2_size = m_value.dim2Size();
304 Int64 total_nb_value = count * dim2_size;
305 Int64 total = total_nb_value;
306 Int64 n[4];
307 n[0] = m_value.dim1Size();
308 n[1] = m_value.dim2Size();
309 n[2] = count;
310 n[3] = SERIALIZE2_MAGIC_NUMBER;
311 /*m_trace->info() << "PUT COUNT = " << count << " total=" << total
312 << " dim1 (n[0])=" << n[0]
313 << " dim2 (n[1])=" << n[1]
314 << " count (n[2])=" << n[2]
315 << " magic=" << n[3]
316 << " this=" << this;*/
317 sbuf->putSpan(Span<const Int64>(n, 4));
318 UniqueArray<BasicType> v(total * nb_count);
319 {
320 Integer index = 0;
321 for (Int32 i = 0, is = count; i < is; ++i) {
322 const BasicType* sub_a = reinterpret_cast<const BasicType*>(m_value[ids[i]].data());
323 for (Int64 z = 0, iz = dim2_size * nb_count; z < iz; ++z) {
324 v[index] = sub_a[z];
325 ++index;
326 }
327 }
328 }
329 sbuf->putSpan(v);
330 }
331 else if (mode == ISerializer::ModeGet) {
332 switch (sbuf->readMode()) {
334 Int64 n[4] = { 0, 0, 0, 0 };
335 sbuf->getSpan(Span<Int64>(n, 4));
336 //Integer dim1_size = n[0];
337 Int64 dim2_size = n[1];
338 Int32 count = CheckedConvert::toInt32(n[2]);
339 Int64 total = count * dim2_size;
340 // Une dimension
341 /*m_trace->info() << "COUNT = " << count << " total=" << total
342 << " dim1 (n[0])=" << n[0]
343 << " dim1 current=" << m_value.dim1Size()
344 << " dim2 (n[1])=" << n[1]
345 << " dim2 current=" << m_value.dim2Size()
346 << " count (n[2])=" << n[2]
347 << " magic=" << n[3]
348 << " this=" << this;*/
349 if (n[3] != SERIALIZE2_MAGIC_NUMBER)
350 ARCANE_FATAL("Bad magic number");
351 Int64 current_dim2_size = m_value.dim2Size();
352 if (dim2_size != current_dim2_size) {
353 if (current_dim2_size != 0 && dim2_size != 0)
354 ARCANE_FATAL("serialized data should have the same dim2Size current={0} found={1}",
355 current_dim2_size, dim2_size);
356 else
357 m_value.resize(m_value.dim1Size(), dim2_size);
358 }
359 Int64 nb_value = count;
360 //Array<BasicType> v(total*nb_count);
361 UniqueArray<BasicType> base_value(total * nb_count);
362
363 sbuf->getSpan(base_value);
364
365 Span<DataType> data_value(reinterpret_cast<DataType*>(base_value.data()), nb_value * dim2_size);
366 UniqueArray<DataType> current_value;
367 Span<DataType> transformed_value;
368
369 // Si on applique une transformantion, effectue la transformation dans un
370 // tableau temporaire 'current_value'.
371 if (operation && nb_value != 0) {
372 current_value.resize(data_value.size());
373
374 Int64 index = 0;
375 for (Int32 i = 0, n = count; i < n; ++i) {
376 Span<const DataType> a(m_value[ids[i]]);
377 for (Int64 z = 0, iz = dim2_size; z < iz; ++z) {
378 current_value[index] = a[z];
379 ++index;
380 }
381 }
382
383 transformed_value = current_value.view();
384 operation->applySpan(transformed_value, data_value);
385 }
386 else {
387 transformed_value = data_value;
388 }
389
390 {
391 Int64 index = 0;
392 for (Int32 i = 0, n = count; i < n; ++i) {
393 Span<DataType> a(m_value[ids[i]]);
394 for (Int64 z = 0, iz = dim2_size; z < iz; ++z) {
395 a[z] = transformed_value[index];
396 ++index;
397 }
398 }
399 }
400 } break;
402 throw NotImplementedException(A_FUNCINFO, "option 'ReadAdd'");
403 break;
404 }
405 }
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
411template <typename DataType> void Array2DataT<DataType>::
412fillDefault()
413{
414 m_value.fill(DataType());
415}
416
417/*---------------------------------------------------------------------------*/
418/*---------------------------------------------------------------------------*/
419
420template <typename DataType> void Array2DataT<DataType>::
421setName(const String& name)
422{
423 m_value.setDebugName(name);
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429template <typename DataType> void Array2DataT<DataType>::
430computeHash(IHashAlgorithm* algo, ByteArray& output) const
431{
432 //TODO: passer en 64 bits
433 Span<const DataType> values = m_value.to1DSpan();
434
435 // Calcule la fonction de hashage pour les valeurs
436 Int64 type_size = sizeof(DataType);
437 Int64 nb_element = values.size();
438 const Byte* ptr = reinterpret_cast<const Byte*>(values.data());
439 Span<const Byte> input(ptr, type_size * nb_element);
440 algo->computeHash64(input, output);
441
442 // Calcule la fonction de hashage pour les tailles
443 UniqueArray<Int64> dimensions(2);
444 dimensions[0] = m_value.dim1Size();
445 dimensions[1] = m_value.dim2Size();
446 ptr = reinterpret_cast<const Byte*>(dimensions.data());
447 Int64 array_len = dimensions.size() * sizeof(Int64);
448 input = Span<const Byte>(ptr, array_len);
449 algo->computeHash64(input, output);
450}
451
452/*---------------------------------------------------------------------------*/
453/*---------------------------------------------------------------------------*/
454
455template <typename DataType> void Array2DataT<DataType>::
456computeHash(DataHashInfo& hash_info) const
457{
458 hash_info.setVersion(2);
459 IHashAlgorithmContext* context = hash_info.context();
460
461 // Calcule la fonction de hashage pour les tailles
462 Int64 dimensions[2];
463 dimensions[0] = m_value.dim1Size();
464 dimensions[1] = m_value.dim2Size();
465 Span<const Int64> dimension_span(dimensions, 2);
466 context->updateHash(asBytes(dimension_span));
467
468 // Calcule la fonction de hashage pour les valeurs
469 context->updateHash(asBytes(m_value.to1DSpan()));
470}
471
472/*---------------------------------------------------------------------------*/
473/*---------------------------------------------------------------------------*/
474
475template <typename DataType> void Array2DataT<DataType>::
476copy(const IData* data)
477{
478 auto* true_data = dynamic_cast<const DataInterfaceType*>(data);
479 if (!true_data)
480 throw ArgumentException(A_FUNCINFO, "Can not cast 'IData' to 'IArray2DataT'");
481 m_value.copy(true_data->view());
482}
483
484/*---------------------------------------------------------------------------*/
485/*---------------------------------------------------------------------------*/
486
487template <typename DataType> void Array2DataT<DataType>::
488swapValues(IData* data)
489{
490 auto* true_data = dynamic_cast<ThatClass*>(data);
491 if (!true_data)
492 throw ArgumentException(A_FUNCINFO, "Can not cast 'IData' to 'Array2DataT'");
493 swapValuesDirect(true_data);
494}
495
496/*---------------------------------------------------------------------------*/
497/*---------------------------------------------------------------------------*/
498
499template <typename DataType> void Array2DataT<DataType>::
500swapValuesDirect(ThatClass* true_data)
501{
502 m_value.swap(true_data->m_value);
503}
504
505/*---------------------------------------------------------------------------*/
506/*---------------------------------------------------------------------------*/
507
508template <typename DataType> void Array2DataT<DataType>::
509setAllocationInfo(const DataAllocationInfo& v)
510{
511 if (m_allocation_info == v)
512 return;
513 m_allocation_info = v;
514 m_value.setMemoryLocationHint(v.memoryLocationHint());
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
520template <typename DataType> void Array2DataT<DataType>::
522{
523 m_value.changeAllocator(alloc_info);
524 m_allocation_info.setMemoryLocationHint(alloc_info.memoryLocationHint());
525}
526
527/*---------------------------------------------------------------------------*/
528/*---------------------------------------------------------------------------*/
529
530} // End namespace Arcane
531
532/*---------------------------------------------------------------------------*/
533/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions de gestion mémoire et des allocateurs.
Integer size() const
Nombre d'éléments du vecteur.
Allocateur mémoire avec alignement mémoire spécifique.
Exception lorsqu'un argument est invalide.
Donnée tableau bi-dimensionnel d'un type DataType.
Definition Array2Data.h:49
UniqueArray2< DataType > m_value
Donnée.
Definition Array2Data.h:146
eDataType dataType() const override
Type de la donnée.
Definition Array2Data.h:70
ArrayShape shape() const override
Forme du tableau pour une donnée 1D ou 2D.
Definition Array2Data.h:104
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
const T * data() const
Accès à la racine du tableau hors toute protection.
ArrayView< T > view() const
Vue mutable sur ce tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Informations sur l'allocation d'une donnée.
Informations pour le calcul du hash d'une donnée.
Informations de type pour un conteneur de données.
Interface d'une opération sur une donnée.
Interface d'une donnée.
Definition IData.h:33
Contexte pour calculer un hash de manière incrémentale.
virtual void updateHash(Span< const std::byte > input)=0
Ajoute le tableau input au hash calculé
Interface d'un algorithme de hashage.
virtual void computeHash64(Span< const Byte > input, ByteArray &output)
Calcule la valeur du hash pour le tableau input.
Interface d'une donnée sérialisée.
virtual eDataType baseDataType() const =0
Type de la donnée.
virtual ArrayShape shape() const =0
Forme du tableau associé aux données.
virtual Int64 memorySize() const =0
Indique le nombre d'octets qu'il faut allouer pour stocker ou lire les données.
virtual void setWritableBytes(Span< Byte > bytes)=0
Positionne les valeurs de sérialisation.
virtual Int64ConstArrayView extents() const =0
Tableau contenant le nombre d'éléments pour chaque dimension.
virtual bool isMultiSize() const =0
Indique s'il s'agit d'un tableau multi-taille. (pertinent uniquement si nbDimension()>1).
eMode
Mode de fonctionnement du sérialiseur.
@ ModePut
Le sérialiseur attend des reserve().
virtual eReadMode readMode() const =0
Mode de lecture.
virtual void putSpan(Span< const Real > values)
Ajoute le tableau values.
virtual eMode mode() const =0
Mode de fonctionnement actuel.
@ ReadReplace
Replace les éléments actuels par ceux lus.
@ ReadAdd
Ajoute aux éléments actuels ceux lus.
virtual void getSpan(Span< Real > values)
Récupère le tableau values.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Réserve de la mémoire pour n valeurs de dt.
Interface du gestionnaire de traces.
Exception lorsqu'une fonction n'est pas implémentée.
Référence à une instance.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:537
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
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Ref< ISerializedData > arcaneCreateSerializedDataRef(eDataType data_type, Int64 memory_size, Integer nb_dim, Int64 nb_element, Int64 nb_base_element, bool is_multi_size, Int64ConstArrayView dimensions)
Créé des données sérialisées.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:115
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:480
eBasicDataType
Type d'une donnée de base.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Convertit la vue en un tableau d'octets non modifiables.
Definition Span.h:1028
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:42
eDataType
Type d'une donnée.
Definition DataTypes.h:39
std::int32_t Int32
Type entier signé sur 32 bits.