15#include <Partitionneur_Metis.h>
17#include <Static_Int_Lists.h>
21#include <communications.h>
22#include <Domain_Graph.h>
25inline void not_implemented(
const Nom& chaine)
27 Cerr << chaine <<
" is not implemented yet to the METIS API." << finl;
43template<
typename _SIZE_>
44_SIZE_ from_idx_t_to_SIZE(idx_t val)
46 assert(val < std::numeric_limits<_SIZE_>::max());
52template <
typename _SIZE_>
55 Cerr <<
"Partitionneur_Metis_32_64<_SIZE_>::printOn invalid\n" << finl;
61template <
typename _SIZE_>
65 param.
ajouter(
"nb_essais",&nb_essais_);
66 param.
ajouter_condition(
"(value_of_nb_parts_ge_1)_and_(value_of_nb_parts_le_100000)",
"The following condition must be satisfied : 1 <= nb_parties <= 100000");
83 param.
ajouter_flag(
"use_segment_to_build_connectivite_elem_elem",&use_segment_to_build_connectivite_elem_elem_);
86template <
typename _SIZE_>
91 Cerr <<
"WARNING! You're using a sequential algorithm on " << this->
nproc() <<
"processors " << finl;
92 Cerr <<
"Use PARMETIS for parallel domain cutting" << finl;
97 Cerr <<
" Algorithm PMETIS" << finl;
101 else if (mot==
"kmetis")
103 Cerr <<
" Algorithm KMETIS" << finl;
107 else if (mot==
"match_type")
109 not_implemented(mot);
112 else if (mot==
"initial_partition_type")
114 not_implemented(mot);
117 else if (mot==
"refinement_type")
119 not_implemented(mot);
133template <
typename _SIZE_>
137 Cerr <<
"METIS is not compiled with this version. Use another partition tool like Tranche." << finl;
142 Cerr <<
"Error in Partitionneur_Metis_32_64<_SIZE_>::construire_partition\n";
143 Cerr <<
" The domain has not been associated" << finl;
146 if (nb_parties_ <= 0)
148 Cerr <<
"Error in Partitionneur_Metis_32_64<_SIZE_>::construire_partition\n";
149 Cerr <<
" The parts number has not been initialized" << finl;
154 if (nb_parties_ == 1)
156 int_t nb_elem = ref_domaine_->nb_elem_tot();
157 if (use_segment_to_build_connectivite_elem_elem_)
158 nb_elem = ref_domaine_->nb_som();
159 elem_part.
resize(nb_elem);
164 if (ref_domaine_->nb_elem() == 0)
167 Cerr <<
"Partitionneur_Metis_32_64<_SIZE_>::construire_partition" << finl;
168 Cerr <<
" Construction of graph connectivity..." << finl;
172 if (!use_segment_to_build_connectivite_elem_elem_)
175 graph_elements_perio);
179 std::vector<idx_t> partition(graph.
nvtxs);
180 idx_t int_parts = nb_parties_;
187 Cerr <<
"===============" << finl;
188 Cerr <<
"Call for PMETIS" << finl;
189 Cerr <<
"===============" << finl;
191 idx_t options[METIS_NOPTIONS];
192 METIS_SetDefaultOptions(options);
198 options[METIS_OPTION_NCUTS]=nb_essais_;
199 options[METIS_OPTION_NUMBERING]=0;
200 options[METIS_OPTION_DBGLVL]=111111111;
205 int status = METIS_PartGraphRecursive(&graph.
nvtxs, &ncon, graph.
xadj.
addr(),
207 &int_parts,
nullptr,
nullptr, options,
208 &edgecut, partition.data());
209 if (status != METIS_OK)
211 Cerr <<
"Call to METIS failed." << finl;
212 if (status == METIS_ERROR_INPUT) Cerr <<
"It seems there is an input error." << finl;
213 if (status == METIS_ERROR_MEMORY) Cerr <<
"It seems it couldn't allocate enough memory." << finl;
214 if (status == METIS_ERROR) Cerr <<
"It seems there is a METIS internal error." << finl;
215 Cerr <<
"Contact TRUST support." << finl;
218 Cerr <<
"===============" << finl;
223 Cerr <<
" Call for KMETIS" << finl;
224 idx_t options[METIS_NOPTIONS];
225 METIS_SetDefaultOptions(options);
231 options[METIS_OPTION_NCUTS]=nb_essais_;
232 options[METIS_OPTION_NUMBERING]=0;
233 options[METIS_OPTION_DBGLVL]=111111111;
237 int status = METIS_PartGraphKway(&graph.
nvtxs, &ncon, graph.
xadj.
addr(),
239 &int_parts,
nullptr,
nullptr, options ,
240 &edgecut, partition.data());
241 if (status != METIS_OK)
243 Cerr <<
"Call to METIS failed." << finl;
244 if (status == METIS_ERROR_INPUT) Cerr <<
"It seems there is an input error." << finl;
245 if (status == METIS_ERROR_MEMORY) Cerr <<
"It seems it couldn't allocate enough memory." << finl;
246 if (status == METIS_ERROR) Cerr <<
"It seems there is a METIS internal error." << finl;
247 Cerr <<
"Contact TRUST support." << finl;
254 Cerr <<
"Internal error Partitionneur_Metis_32_64: not coded" << finl;
258 Cerr <<
"Partitioning quality : edgecut = " << edgecut << finl;
259 Cerr <<
"-> It is roughly the total number of edges (faces) which will be shared by the processors." << finl;
260 Cerr <<
"-> The lesser this number is, the lesser the total volume of communication between processors." << finl;
261 Cerr <<
"-> You can increase nb_essais option (default 1) to try to reduce (but at a higher CPU cost) this number." << finl;
262 Cerr <<
"===============" << finl;
264 const int_t n = from_idx_t_to_SIZE<_SIZE_>(graph.
nvtxs);
266 for (
int_t i = 0; i < n; i++)
267 elem_part[i] =
static_cast<int>(partition[i]);
272 Cerr <<
"Correction of the partition for the periodicity" << finl;
274 Cerr <<
" If this number is high, you can improve the splitting with the option use_weights\n"
275 <<
" but it takes more memory)" << finl;
278 if (!use_segment_to_build_connectivite_elem_elem_)
280 Cerr <<
"Correction elem0 on processor 0" << finl;
Build the graph of the domain that the METIS/PARMETIS/PTSCOTCH libraries need.
void construire_graph_elem_elem(const Domaine_32_64< _SIZE_ > &dom, bool use_weights, Static_Int_Lists_32_64< _SIZE_ > &graph_elements_perio)
void construire_graph_from_segment(const Domaine_32_64< _SIZE_ > &dom, bool use_weights)
Une chaine de caractere (Nom) en majuscules.
class Nom Une chaine de caractere pour nommer les objets de TRUST
virtual void set_param(Param &) const
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
void ajouter_condition(const char *condition, const char *message, const char *name=0)
Declare a post-read logical condition that must hold on the parameter values.
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Partition d'un domaine en nb_parties parties equilibrees en utilisant la librairie METIS.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
TRUSTVect< int, _SIZE_ > BigIntVect_
void construire_partition(BigIntVect_ &elem_part, int &nb_parts_tot) const override
Calcule le graphe de connectivite pour Metis, appelle le partitionneur et remplit elem_part (pour cha...
Classe de base des partitionneurs de domaine (pour decouper un maillage avant un calcul parallele).
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
static void corriger_bords_avec_liste(const Domaine_t &dom, const int_t my_offset, BigIntVect_ &elem_part)
Calcul des graphes de connectivite elements periodiques et appel a corriger_periodique_avec_graphe.
static void corriger_elem0_sur_proc0(BigIntVect_ &elem_part)
corrige la partition pour que l'element 0 du domaine initial se trouve sur le premier sous-domaine de...
static bool is_parallel()
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Classe de base des flux de sortie.
Cette classe permet de stocker des listes d'entiers accessibles en temps constant.
int_t get_nb_lists() const
renvoie le nombre de listes stockees
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)