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);
165 Int64
max_id = (MASK_CELL_UID - 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);
184 Int64 cellUid()
const {
return (m_value & MASK_CELL_UID) - 1; }
186 Int32 faceLocalIndex()
const {
return CheckedConvert::toInt32( ((m_value & MASK_INDEX) >> (BITS_CELL_UID+BITS_RANK)) - 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
218 m_cell_uid = cell_uid;
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)
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;
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;
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();
460 return i1.uniqueId() <
i2.uniqueId();
474, m_parallel_mng(mesh->parallelMng())
503 info() <<
"Compute FacesUniqueId() Sequential V3";
522 for( Integer i=0; i<
nb_cell; ++i ){
523 Cell cell = cells[i];
525 if (face.uniqueId()==NULL_ITEM_UNIQUE_ID){
544 bool is_verbose = m_is_verbose;
548 info() <<
"Compute FacesUniqueId() V3 using parallel sort";
572 for( Integer i=0; i<n; ++i ){
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
641 for( Integer i=0; i<n; ++i ){
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();
672 bool is_verbose = m_is_verbose;
691 for( Integer z=0,
zs=cell.
nbFace(); z<
zs; ++z )
692 if (cell.
face(z)==face){
703 for( Integer i=0; i<n; ++i ){
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;
724 for( Integer i=0; i<n; ++i ){
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;
743 if (BoundaryFaceBitonicSortTraits::isValid(
all_bfi[0])){
745 for( Integer i=0; i<n; ++i ){
802void FaceUniqueIdBuilder2::
808 bool is_verbose = m_is_verbose;
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];
851 Int64 nb_cell_to_sort = all_csi.size();
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 ){
873 const AnyFaceInfo& csi = all_csi[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];
896 Int64 total_nb_computed_face = pm->
reduce(Parallel::ReduceSum,nb_computed_face);
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;
924 Int32 vsize =
sizeof(ResendCellInfo) /
sizeof(
Int64);
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 ){
958 const ResendCellInfo& rci = recv_infos[index];
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 ){
984 const ResendCellInfo& rci = recv_infos[index];
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)";
1038 if (is_parallel && face.
nbCell()==1)
1070 if (
face_uid==NULL_ITEM_UNIQUE_ID){
1086 f.computeFacesUniqueIdAndOwnerVersion3();
1093_computeFaceUniqueIdVersion5(DynamicMesh* mesh)
1095 FaceUniqueIdBuilder2 f(mesh);
1096 f.computeFacesUniqueIdAndOwnerVersion5();
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
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.
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.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
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.
impl::ItemBase tryFind(Int64 key) const
Retourne l'entité associée à key si trouvé ou l'entité nulle sinon.
Vue modifiable d'un tableau d'un type T.
Vue constante d'un tableau de type T.
Classe d'accès aux traces.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Int32 Integer
Type représentant un entier.