14#include "arcane/utils/PlatformUtils.h"
15#include "arcane/utils/ArgumentException.h"
16#include "arcane/utils/CheckedConvert.h"
18#include "arcane/mesh/DynamicMesh.h"
19#include "arcane/mesh/FaceUniqueIdBuilder.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/Timer.h"
24#include "arcane/parallel/BitonicSortT.H"
100 bool m_is_verbose =
false;
142 static const Int64 BITS_CELL_UID = 39;
143 static const Int64 BITS_RANK = 20;
144 static const Int64 BITS_INDEX = 5;
145 static const Int64 ONE_INT64 = 1;
146 static const Int64 MASK_CELL_UID = (ONE_INT64 << BITS_CELL_UID) - 1;
147 static const Int64 MASK_RANK = ((ONE_INT64 << BITS_RANK) - 1) << BITS_CELL_UID;
148 static const Int64 MASK_INDEX = ((ONE_INT64 << BITS_INDEX) - 1) << (BITS_CELL_UID+BITS_RANK);
153 setValue(NULL_ITEM_UNIQUE_ID,-1,-1);
157 bool isMaxValue()
const
159 Int64 max_id = (MASK_CELL_UID - 1);
160 return cellUid()==max_id;
165 Int64 max_id = (MASK_CELL_UID - 1);
166 setValue(max_id,-1,-1);
171 Int64 v_fli = face_local_index+1;
172 Int64 v_rank = _rank+1;
173 Int64 v_uid = cell_uid+1;
174 m_value = v_fli << (BITS_CELL_UID+BITS_RANK);
175 m_value += v_rank << (BITS_CELL_UID);
177 if (cellUid()!=cell_uid)
178 ARCANE_FATAL(
"Bad uid expected='{0}' computed='{1}' v={2}",cell_uid,cellUid(),m_value);
180 ARCANE_FATAL(
"Bad rank expected='{0}' computed='{1}'",_rank,rank());
181 if (faceLocalIndex()!=face_local_index)
182 ARCANE_FATAL(
"Bad local_index expected='{0}' computed='{1}'",face_local_index,faceLocalIndex());
184 Int64 cellUid()
const {
return (m_value & MASK_CELL_UID) - 1; }
188 bool isValid()
const {
return cellUid()!=NULL_ITEM_UNIQUE_ID; }
203 WideCellFaceInfo() : m_cell_uid(NULL_ITEM_UNIQUE_ID), m_rank(-1), m_face_local_index(-1){}
205 bool isMaxValue()
const
207 Int64 max_id = INT64_MAX;
208 return cellUid()==max_id;
213 Int64 max_id = INT64_MAX;
214 setValue(max_id,-1,-1);
218 m_cell_uid = cell_uid;
220 m_face_local_index = face_local_index;
222 Int64 cellUid()
const {
return m_cell_uid; }
223 Int32 rank()
const {
return m_rank; }
224 Int32 faceLocalIndex()
const {
return m_face_local_index; }
225 bool isValid()
const {
return m_cell_uid!=NULL_ITEM_UNIQUE_ID; }
231 Int32 m_face_local_index;
246 : m_node0_uid(NULL_ITEM_UNIQUE_ID), m_node1_uid(NULL_ITEM_UNIQUE_ID),
247 m_node2_uid(NULL_ITEM_UNIQUE_ID), m_cell_uid(NULL_ITEM_UNIQUE_ID),
248 m_rank(-1), m_face_local_index(-1)
250 bool hasSameNodes(
const BoundaryFaceInfo& fsi)
const
252 return fsi.m_node0_uid==m_node0_uid && fsi.m_node1_uid==m_node1_uid
253 && fsi.m_node2_uid==m_node2_uid;
255 void setNodes(
Face face)
271 Int32 m_face_local_index;
288 AnyFaceInfo() =
default;
293 m_cell0.setValue(uid,rank,face_local_index);
297 m_cell1.setValue(uid,rank,face_local_index);
300 CellFaceInfo m_cell0;
301 CellFaceInfo m_cell1;
317 Int32 m_face_local_index_and_owner_rank;
318 Int32 m_index_in_rank_list;
337 if (k1.m_node0_uid<k2.m_node0_uid)
339 if (k1.m_node0_uid>k2.m_node0_uid)
343 if (k1.m_node1_uid<k2.m_node1_uid)
345 if (k1.m_node1_uid>k2.m_node1_uid)
349 if (k1.m_node2_uid<k2.m_node2_uid)
351 if (k1.m_node2_uid>k2.m_node2_uid)
355 return (k1.m_cell_uid<k2.m_cell_uid);
375 fsi.m_cell_uid = INT64_MAX;
376 fsi.m_rank = INT32_MAX;
377 fsi.m_node0_uid = INT64_MAX;
378 fsi.m_node1_uid = INT64_MAX;
379 fsi.m_node2_uid = INT64_MAX;
384 return fsi.m_cell_uid!=INT64_MAX;
406 Int64 k1_cell0_uid = k1.m_cell0.cellUid();
407 Int64 k2_cell0_uid = k2.m_cell0.cellUid();
408 if (k1_cell0_uid<k2_cell0_uid)
410 if (k1_cell0_uid>k2_cell0_uid)
413 Int64 k1_face0_local_index = k1.m_cell0.faceLocalIndex();
414 Int64 k2_face0_local_index = k2.m_cell0.faceLocalIndex();
415 if (k1_face0_local_index<k2_face0_local_index)
417 if (k1_face0_local_index>k2_face0_local_index)
420 return (k1.m_cell1.cellUid()<k2.m_cell1.cellUid());
440 csi.m_cell0.setMaxValue();
441 csi.m_cell1.setMaxValue();
447 return !csi.m_cell0.isMaxValue();
458 bool operator()(
const Item& i1,
const Item& i2)
const
474, m_parallel_mng(
mesh->parallelMng())
489 if (m_parallel_mng->isParallel())
503 info() <<
"Compute FacesUniqueId() Sequential V3";
506 Int64 face_unique_id_counter = 0;
522 for(
Integer i=0; i<nb_cell; ++i ){
523 Cell cell = cells[i];
525 if (face.uniqueId()==NULL_ITEM_UNIQUE_ID){
526 face.mutableItemBase().setUniqueId(face_unique_id_counter);
527 ++face_unique_id_counter;
544 bool is_verbose = m_is_verbose;
548 info() <<
"Compute FacesUniqueId() V3 using parallel sort";
571 bool is_last_already_done =
false;
574 Int64 cell_uid0 = fsi.m_cell_uid;
575 bool is_inside =
false;
579 is_inside = ((i+1)!=n && fsi.hasSameNodes(all_fsi[i+1]));
580 if (is_last_already_done){
581 is_last_already_done =
false;
587 Int64 cell_uid1 = next_fsi.m_cell_uid;
588 if (cell_uid0<cell_uid1){
589 csi.setCell0(cell_uid0,fsi.m_rank,fsi.m_face_local_index);
590 csi.setCell1(cell_uid1,next_fsi.m_rank,next_fsi.m_face_local_index);
593 csi.setCell0(cell_uid1,next_fsi.m_rank,next_fsi.m_face_local_index);
594 csi.setCell1(cell_uid0,fsi.m_rank,fsi.m_face_local_index);
596 is_last_already_done =
true;
599 csi.setCell0(cell_uid0,fsi.m_rank,fsi.m_face_local_index);
601 all_face_list.
add(csi);
604 info() <<
"FACES_KEY i=" << i
605 <<
" n0=" << fsi.m_node0_uid
606 <<
" n1=" << fsi.m_node1_uid
607 <<
" n2=" << fsi.m_node2_uid
608 <<
" cell=" << fsi.m_cell_uid
609 <<
" rank=" << fsi.m_rank
610 <<
" li=" << fsi.m_face_local_index
611 <<
" in=" << is_inside;
620 for(
Integer z=0; z<cell_nb_face; ++z ){
626 Cell next_cell = (cell0==cell) ? cell1 : cell0;
629 if (cell_uid<next_cell_uid){
631 csi.m_cell0.setValue(cell_uid,my_rank,z);
633 csi.m_cell1.setValue(next_cell_uid,my_rank,-1);
634 all_face_list.
add(csi);
643 info() <<
"CELL_TO_SORT i=" << i
644 <<
" cell0=" << csi.m_cell0.cellUid()
645 <<
" lidx0=" << csi.m_cell0.faceLocalIndex()
646 <<
" cell1=" << csi.m_cell1.cellUid();
652 all_face_sorter.setNeedIndexAndRank(
false);
654 all_face_sorter.
sort(all_face_list);
656 info() <<
"END_ALL_FACE_SORTER time=" << (
Real)(sort_end_time - sort_begin_time);
658 _resendCellsAndComputeFacesUniqueId(all_face_sorter.
keys());
672 bool is_verbose = m_is_verbose;
676 boundary_face_sorter.setNeedIndexAndRank(
false);
679 boundary_faces_info.
clear();
686 fsi.m_rank = my_rank;
692 if (cell.
face(z)==face){
693 face_local_index = z;
696 fsi.m_face_local_index = face_local_index;
697 boundary_faces_info.
add(fsi);
705 info() <<
"KEY i=" << i
706 <<
" n0=" << fsi.m_node0_uid
707 <<
" n1=" << fsi.m_node1_uid
708 <<
" n2=" << fsi.m_node2_uid
709 <<
" cell=" << fsi.m_cell_uid
710 <<
" rank=" << fsi.m_rank
711 <<
" li=" << fsi.m_face_local_index;
716 boundary_face_sorter.
sort(boundary_faces_info);
718 info() <<
"END_BOUNDARY_FACE_SORT time=" << (
Real)(sort_end_time - sort_begin_time);
726 info() <<
" AFTER KEY i=" << i
727 <<
" n0=" << bfi.m_node0_uid
728 <<
" n1=" << bfi.m_node1_uid
729 <<
" n2=" << bfi.m_node2_uid
730 <<
" cell=" << bfi.m_cell_uid
731 <<
" rank=" << bfi.m_rank
732 <<
" li=" << bfi.m_face_local_index;
741 Integer begin_own_list_index = 0;
742 if (n!=0 && my_rank!=0){
743 if (BoundaryFaceBitonicSortTraits::isValid(all_bfi[0])){
744 Int64 node0_uid = all_bfi[0].m_node0_uid;
746 if (all_bfi[i].m_node0_uid!=node0_uid){
747 begin_own_list_index = i;
751 end_face_list.
add(all_bfi[i]);
755 info() <<
"BEGIN_OWN_LIST_INDEX=" << begin_own_list_index;
757 for(
Integer k=0, kn=end_face_list.
size(); k<kn; ++k )
758 info() <<
" SEND n0=" << end_face_list[k].m_node0_uid
759 <<
" n1=" << end_face_list[k].m_node1_uid
760 <<
" n2=" << end_face_list[k].m_node2_uid;
767 Integer send_message_size = BoundaryFaceBitonicSortTraits::messageSize(end_face_list);
772 if (my_rank!=(nb_rank-1)){
782 if (recv_message_size!=0){
784 end_face_list_recv.
resize(message_size);
785 requests.
add(BoundaryFaceBitonicSortTraits::recv(pm,my_rank+1,end_face_list_recv));
787 if (send_message_size!=0)
788 requests.
add(BoundaryFaceBitonicSortTraits::send(pm,my_rank-1,end_face_list));
792 boundary_faces_info.
clear();
793 boundary_faces_info.
addRange(all_bfi.
subConstView(begin_own_list_index,n-begin_own_list_index));
794 boundary_faces_info.
addRange(end_face_list_recv);
802void FaceUniqueIdBuilder2::
808 bool is_verbose = m_is_verbose;
815 for(
Integer i=0; i<nb_computed_face; ++i ){
816 const AnyFaceInfo& csi = all_csi[i];
817 info() <<
"CELLS_KEY i=" << i
818 <<
" cell0=" << csi.m_cell0.cellUid()
819 <<
" lidx0=" << csi.m_cell0.faceLocalIndex()
820 <<
" cell1=" << csi.m_cell1.cellUid()
821 <<
" lidx1=" << csi.m_cell1.faceLocalIndex()
822 <<
" rank0=" << csi.m_cell0.rank()
823 <<
" rank1=" << csi.m_cell1.rank();
831 for(
Integer i=0; i<nb_computed_face; ++i ){
832 const AnyFaceInfo& csi = all_csi[i];
833 Int32 rank0 = csi.m_cell0.rank();
834 Int32 rank1 = csi.m_cell1.rank();
836 ++nb_info_to_send[rank0];
839 if (csi.m_cell1.isValid() && rank1!=rank0)
840 ++nb_info_to_send[rank1];
855 for(
Integer i=0; i<nb_rank; ++i ){
856 Int64 next = all_first_face_uid[i];
857 all_first_face_uid[i] = to_add;
864 for(
Integer i=0; i<nb_rank; ++i ){
865 nb_info_to_send_indexes[i] = total_nb_to_send;
866 total_nb_to_send += nb_info_to_send[i];
868 info() <<
"TOTAL_NB_TO_SEND=" << total_nb_to_send;
870 UniqueArray<ResendCellInfo> resend_infos(total_nb_to_send);
872 for(
Integer i=0; i<nb_computed_face; ++i ){
874 Int32 rank0 = csi.m_cell0.rank();
875 Int32 rank1 = csi.m_cell1.rank();
877 ResendCellInfo& rci0 = resend_infos[nb_info_to_send_indexes[rank0]];
878 rci0.m_cell_uid = csi.m_cell0.cellUid();
879 rci0.m_face_local_index_and_owner_rank = (csi.m_cell0.faceLocalIndex() * nb_rank) + rank0;
880 rci0.m_index_in_rank_list = i;
881 ++nb_info_to_send_indexes[rank0];
883 if (csi.m_cell1.isValid() && rank1!=rank0){
884 ResendCellInfo& rci1 = resend_infos[nb_info_to_send_indexes[rank1]];
885 rci1.m_cell_uid = csi.m_cell1.cellUid();
887 rci1.m_face_local_index_and_owner_rank = (csi.m_cell1.faceLocalIndex() * nb_rank) + rank0;
888 rci1.m_index_in_rank_list = i;
889 ++nb_info_to_send_indexes[rank1];
897 info() <<
"TOTAL_NB_COMPUTED_FACE=" << total_nb_computed_face;
901 for(
Integer i=0; i<nb_rank; ++i )
902 info() <<
"NB_TO_SEND: I=" << i <<
" n=" << nb_info_to_send[i];
906 Timer::SimplePrinter sp(
traceMng(),
"Sending size with AllToAll");
907 pm->allToAll(nb_info_to_send,nb_info_to_recv,1);
911 for(
Integer i=0; i<nb_rank; ++i )
912 info() <<
"NB_TO_RECV: I=" << i <<
" n=" << nb_info_to_recv[i];
915 for(
Integer i=0; i<nb_rank; ++i )
916 total_nb_to_recv += nb_info_to_recv[i];
922 UniqueArray<ResendCellInfo> recv_infos;
929 Int32 total_send = 0;
930 Int32 total_recv = 0;
931 for(
Integer i=0; i<nb_rank; ++i ){
932 send_counts[i] = (
Int32)(nb_info_to_send[i] * vsize);
933 recv_counts[i] = (
Int32)(nb_info_to_recv[i] * vsize);
934 send_indexes[i] = total_send;
935 recv_indexes[i] = total_recv;
936 total_send += send_counts[i];
937 total_recv += recv_counts[i];
939 recv_infos.resize(total_nb_to_recv);
944 info() <<
"BUF_SIZES: send=" << send_buf.size() <<
" recv=" << recv_buf.size();
946 Timer::SimplePrinter sp(
traceMng(),
"Send values with AllToAll");
947 pm->allToAllVariable(send_buf,send_counts,send_indexes,recv_buf,recv_counts,recv_indexes);
956 for(
Int32 rank=0; rank<nb_rank; ++rank ){
957 for(
Integer z=0, zs=nb_info_to_recv[rank]; z<zs; ++z ){
961 Int64 cell_uid = rci.m_cell_uid;
962 Int32 full_local_index = rci.m_face_local_index_and_owner_rank;
963 Int32 face_local_index = full_local_index / nb_rank;
964 Int32 owner_rank = full_local_index % nb_rank;
965 Int64 face_uid = all_first_face_uid[rank] + rci.m_index_in_rank_list;
966 info() <<
"RECV index=" << index <<
" uid=" << cell_uid
967 <<
" local_idx=" << full_local_index
968 <<
" face_local_idx=" << face_local_index
969 <<
" owner_rank=" << owner_rank
970 <<
" rank_idx=" << rci.m_index_in_rank_list
972 <<
" first_face_uid=" << all_first_face_uid[rank]
973 <<
" computed_uid=" << face_uid;
981 for(
Int32 i=0; i<nb_rank; ++i ){
983 for(
Integer z=0, zs=nb_info_to_recv[i]; z<zs; ++z ){
987 Int64 cell_uid = rci.m_cell_uid;
988 Int32 full_local_index = rci.m_face_local_index_and_owner_rank;
989 Int32 face_local_index = full_local_index / nb_rank;
990 Int32 owner_rank = full_local_index % nb_rank;
992 Cell cell = cells_map.
tryFind(cell_uid);
994 ARCANE_FATAL(
"Can not find cell data for '{0}'",cell_uid);
995 Face face = cell.face(face_local_index);
996 Int64 face_uid = all_first_face_uid[rank] + rci.m_index_in_rank_list;
997 face.mutableItemBase().setUniqueId(face_uid);
998 face.mutableItemBase().setOwner(owner_rank,my_rank);
1015 info() <<
"Compute FacesUniqueId() V5 (experimental)";
1025 nodes_uid.
resize(nb_node);
1029 nodes_uid[index] = node.uniqueId();
1037 Int32 new_rank = my_rank;
1038 if (is_parallel && face.
nbCell()==1)
1039 new_rank = A_NULL_RANK;
1070 if (face_uid==NULL_ITEM_UNIQUE_ID){
1076 ARCANE_FATAL(
"Internal error in face uniqueId computation: nb_invalid={0}", nb_error);
1086 f.computeFacesUniqueIdAndOwnerVersion3();
1093_computeFaceUniqueIdVersion5(DynamicMesh*
mesh)
1095 FaceUniqueIdBuilder2 f(
mesh);
1096 f.computeFacesUniqueIdAndOwnerVersion5();
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Int64 generateHashUniqueId(SmallSpan< const Int64 > nodes_unique_id)
Génère un identifiant unique à partir d'une liste d'identifiants de noeuds.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
constexpr const_pointer data() const noexcept
Pointeur sur le début de la vue.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
FaceConnectedListViewType faces() const
Liste des faces de la maille.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
Vue constante d'un tableau de type T.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sous-vue (constante) à partir de l'élément abegin et contenant asize éléments.
Cell cell(Int32 i) const
i-ème maille de la face
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Effectue un regroupement sur tous les processeurs. Il s'agit d'une opération collective....
virtual void waitAllRequests(ArrayView< Request > rvalues)=0
Bloque en attendant que les requêtes rvalues soient terminées.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Node node(Int32 i) const
i-ème noeud de l'entité
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
Classe de base d'un élément de maillage.
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
void unsetUniqueId()
Annule l'uniqueId a la valeur NULL_ITEM_UNIQUE_ID.
Algorithme de tri bitonique parallèle.
ConstArrayView< KeyType > keys() const override
Après un tri, retourne la liste des éléments de ce rang.
void sort(ConstArrayView< KeyType > keys) override
Trie en parallèle les éléments de keys sur tous les rangs.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Implémentation d'un maillage.
Fonctor pour trier les AnyFaceInfo via le tri bitonic.
Infos pour gérer les faces des sous-domaines.
Fonctor pour trier les BoundaryFaceInfo via le tri bitonic.
Infos pour gérer les faces frontières des sous-domaines.
Stocke les infos sur une face d'une maille.
Stocke les infos sur une face d'une maille.
Construction des uniqueId() des faces.
void _checkFacesUniqueId()
Vérifie que toutes les faces ont un uid valide.
void _unsetFacesUniqueId()
Invalide les uid pour être certain qu'ils seront tous positionnés.
void _computeAndSortBoundaryFaces(Array< BoundaryFaceInfo > &boundary_faces_info)
Détermine la liste des faces frontières de chaque sous-domaine et les trie sur tous les procs.
void _computeParallel()
Calcul les numéros uniques de chaque face en parallèle.
void computeFacesUniqueIdAndOwnerVersion3()
Calcul les numéros uniques de chaque face en parallèle.
void _computeSequential()
Calcul les numéros uniques de chaque face en sequentiel.
FaceUniqueIdBuilder2(DynamicMesh *mesh)
Construit une instance pour le maillage mesh.
void computeFacesUniqueIdAndOwnerVersion5()
Calcule les uniqueId() via un hash généré par les uniqueId() des noeuds.
Tableau associatif de ItemInternal.
void eachItem(const Lambda &lambda)
Fonction template pour itérer sur les entités de l'instance.
impl::ItemBase tryFind(Int64 key) const
Retourne l'entité associée à key si trouvé ou l'entité nulle sinon.
Int32 count() const
Nombre d'éléments de la table.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
@ ReduceSum
Somme des valeurs.
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
double Real
Type représentant un réel.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
unsigned char Byte
Type d'un octet.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
std::int32_t Int32
Type entier signé sur 32 bits.