TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Decouper.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15#include <Decouper.h>
16#include <Domaine.h>
17#include <DomaineCutter.h>
18#include <Format_Post_Lata.h>
19#include <EChaine.h>
20#include <SFichier.h>
21#include <Param.h>
22#include <communications.h>
23#include <Synonyme_info.h>
24#include <vector>
25#include <set>
26
27Implemente_instanciable_32_64(Decouper_32_64,"Decouper",Interprete);
28Add_synonym(Decouper, "Partition");
29Add_synonym(Decouper_64, "Partition_64");
30
31template <typename _SIZE_>
33{
35 return os;
36}
37
38template <typename _SIZE_>
40{
42 return is;
43}
44
45/*! @brief lecture du partitionneur dans le jeu de donnees (lecture du type et des parametres et initialisation de d_part)
46 */
47template <typename _SIZE_>
48void Decouper_32_64<_SIZE_>::lire_partitionneur(Entree& is)
49{
50 Nom n;
51 is >> n;
52 Nom type_partitionneur("Partitionneur_");
53 type_partitionneur += n;
54 Cerr << " Creation of a partitioner of type: " << type_partitionneur << finl;
55 deriv_partitionneur_.typer(type_partitionneur);
56 // En cas d'echec (si le nom du type est invalide) : exit
57 if (!deriv_partitionneur_)
59
60 // Initialisation des parametres du partitionneur
61 Partitionneur_base_32_64<_SIZE_>& part = deriv_partitionneur_.valeur();
62 part.associer_domaine(this->domaine());
63 is >> part;
64}
65
66template <typename _SIZE_>
67void Decouper_32_64<_SIZE_>::ecrire_fichier_decoupage() const
68{
69 Cerr << "Writing of the splitting array at the format IntVect ascii\n"
70 << " in the file " << nom_fichier_decoupage_
71 << "\n(for each element, number of the destination processor)" << finl;
72 SFichier file; // Fichier ascii
73 if (! file.ouvrir(nom_fichier_decoupage_))
74 {
75 Cerr << " Error in the opening of the file." << finl;
77 }
78 file << elem_part_;
79 file << nb_parts_tot_;
80}
81
82template <typename _SIZE_>
83void Decouper_32_64<_SIZE_>::ecrire_fichier_decoupage_som() const
84{
85 Cerr << "Writing of the splitting array at the format IntVect ascii\n"
86 << " in the file " << nom_fichier_decoupage_sommets_
87 << "\n(for each node, list of the destination processors)" << finl;
88 SFichier file; // Fichier ascii
89 if (! file.ouvrir(nom_fichier_decoupage_sommets_))
90 Process::exit(" Error in the opening of the file.");
91
92 const Domaine_t& domaine = this->domaine();
93 const IntTab_t& elems = domaine.les_elems();
94 int nbOfNodesPerElems = elems.dimension_int(1);
95 int_t nbSom = domaine.nb_som();
96 std::vector<std::set<int_t>> node_part(nbSom);
97 for(int i=0; i<elem_part_.size(); i++)
98 {
99 for (int j = 0; j < nbOfNodesPerElems; j++)
100 {
101 int_t node = elems(i, j);
102 node_part[node].insert(elem_part_[i]);
103 }
104 }
105 file << domaine.nb_som() << finl;
106 for(int_t i=0; i<nbSom; i++)
107 {
108 file << i << " " << node_part[i].size() << " ";
109 for(const auto& set_elem: node_part[i])
110 file << set_elem << " ";
111 file << finl;
112 }
113}
114
115template <typename _SIZE_>
116void Decouper_32_64<_SIZE_>::postraiter_decoupage(const Nom& nom_fichier) const
117{
118 if (!std::is_same<_SIZE_,int>::value)
119 Process::exit("Postprocessing of partitioning is not yet implemented for big (64b) domains!");
120
121 const Domaine& domaine = reinterpret_cast<const Domaine&>(this->domaine());
122 // Check and strip ".lata" :
123 Nom basename;
124 if (nom_fichier.finit_par(".lata"))
125 {
126 basename = nom_fichier;
127 basename.prefix(".lata");
128 }
129 else if (nom_fichier.finit_par(".med"))
130 {
131 basename = nom_fichier;
132 basename.prefix(".med");
133 }
134 else
135 Process::exit("Decouper: postraiter_decoupage(): the file name for postprocessing the domain should end with extension '.lata' or '.med' !!");
136
137 // Compute dummy field indicating partitioning:
138 if (!std::is_same<_SIZE_,int>::value)
139 {
140 // FOR DEVELOPPERS : remove cast to int below if you are porting this for 64b!
141 Cerr << "did you remove cast?" << finl;
142 Process::exit(-1);
143 }
144 const int n = (int)elem_part_.size_reelle();
145
146 DoubleTab data(n);
147 for (int i = 0; i < n; i++)
148 data(i) = static_cast<double>(elem_part_[i]);
149
150 Noms units, noms_compo;
151 units.add("");
152 noms_compo.add("I");
153 constexpr int IS_FIRST = 1;
154
155 if (nom_fichier.finit_par(".lata"))
156 {
157 Cerr << "Postprocessing of the splitting at the lata (V2) format: " << nom_fichier << finl;
158 Format_Post_Lata post;
159
161 post.ecrire_entete(0.0, 0, IS_FIRST);
162 post.ecrire_domaine(domaine, IS_FIRST);
163 post.ecrire_temps(0.0);
164 post.ecrire_champ(domaine,
165 units,
166 noms_compo,
167 1, // ncomp,
168 0.0, //temps,
169 "partition", // id_du_champ,
170 domaine.le_nom(), // id_du_domaine
171 "ELEM", // localisation,
172 "scalar", //nature,
173 data // valeurs
174 );
175 post.finir(1);
176 }
177 else if (nom_fichier.finit_par(".med"))
178 {
179 Cerr << "Postprocessing of the splitting at the MED format: " << nom_fichier << finl;
180 OWN_PTR(Format_Post_base) post;
181 post.typer("Format_Post_Med");
182 Nom filename(nom_fichier.getPrefix(".med"));
183 post->initialize(filename, 1, "SIMPLE");
184 post->ecrire_entete(0.0, 0, IS_FIRST);
185 post->ecrire_domaine(domaine, IS_FIRST);
186 post->ecrire_temps(0.0);
187 post->ecrire_champ(domaine,
188 units,
189 noms_compo,
190 -1, // ncomp,
191 0.0, //temps,
192 "partition", // id_du_champ,
193 "domain", // id_du_domaine
194 "ELEM", // localisation,
195 "scalar", //nature,
196 data // valeurs
197 );
198 post->finir(1);
199 }
200}
201
202template <typename _SIZE_>
203void Decouper_32_64<_SIZE_>::ecrire_sous_domaines(const int nb_parties, const Static_Int_Lists_t* som_raccord) const
204{
206 cutter.initialiser(this->domaine(), elem_part_, nb_parties, epaisseur_joint_);
207 // Reflexion provisoire:
208 // Les joints sont construits dans ecrire_domaines -> construire_sous_domaine
209 // Donc apres renumerotation des PEs et donc de elem_part_, il faudrait
210 // reinitialiser ? Ou bien, tout renumeroter apres le calcul des joints...
211 // Cela parait mieux...
212 cutter.ecrire_domaines(nom_domaines_decoup_, format_, reorder_, som_raccord);
213}
214
216#if INT_is_64_ == 2
218#endif
219
220// XD partition interprete decouper INHERITS_BRACE Class for parallel calculation to cut a domain for each processor. By
221// XD_CONT default, this keyword is commented in the reference test cases.
222// XD attr domaine ref_domaine domaine REQ Name of the domain to be cut.
223// XD attr bloc_decouper bloc_decouper bloc_decouper REQ Description how to cut a domain.
224// XD bloc_decouper objet_lecture nul BRACE Auxiliary class to cut a domain.
225// XD attr partitionneur|Partition_tool partitionneur_deriv partitionneur OPT Defines the partitionning algorithm (the
226// XD_CONT effective C++ object used is \'Partitionneur_ALGORITHM_NAME\').
227// XD attr larg_joint entier larg_joint OPT This keyword specifies the thickness of the virtual ghost domaine (data
228// XD_CONT known by one processor though not owned by it). The default value is 1 and is generally correct for all
229// XD_CONT algorithms except the QUICK convection scheme that require a thickness of 2. Since the 1.5.5 version, the VEF
230// XD_CONT discretization imply also a thickness of 2 (except VEF P0). Any non-zero positive value can be used, but the
231// XD_CONT amount of data to store and exchange between processors grows quickly with the thickness.
232// XD attr nom_zones chaine zones_name OPT Name of the files containing the different partition of the domain. The files
233// XD_CONT will be : NL2 name_0001.Zones NL2 name_0002.Zones NL2 ... NL2 name_000n.Zones. If this keyword is not
234// XD_CONT specified, the geometry is not written on disk (you might just want to generate a \'ecrire_decoupage\' or
235// XD_CONT \'ecrire_lata\').
236// XD attr ecrire_decoupage chaine ecrire_decoupage OPT After having called the partitionning algorithm, the resulting
237// XD_CONT partition is written on disk in the specified filename. See also partitionneur Fichier_Decoupage. This
238// XD_CONT keyword is useful to change the partition numbers: first, you write the partition into a file with the option
239// XD_CONT ecrire_decoupage. This file contains the domaine number for each element\'s mesh. Then you can easily permute
240// XD_CONT domaine numbers in this file. Then read the new partition to create the .Zones files with the
241// XD_CONT Fichier_Decoupage keyword.
242// XD attr ecrire_lata chaine ecrire_lata OPT Save the partition field in a LATA format file for visualization
243// XD attr ecrire_med chaine ecrire_med OPT Save the partition field in a MED format file for visualization
244// XD attr nb_parts_tot entier nb_parts_tot OPT Keyword to generates N .Domaine files, instead of the default number M
245// XD_CONT obtained after the partitionning algorithm. N must be greater or equal to M. This option might be used to
246// XD_CONT perform coupled parallel computations. Supplemental empty domaines from M to N-1 are created. This keyword is
247// XD_CONT used when you want to run a parallel calculation on several domains with for example, 2 processors on a first
248// XD_CONT domain and 10 on the second domain because the first domain is very small compare to second one. You will
249// XD_CONT write Nb_parts 2 and Nb_parts_tot 10 for the first domain and Nb_parts 10 for the second domain.
250// XD attr reorder entier reorder OPT If this option is set to 1 (0 by default), the partition is renumbered in order
251// XD_CONT that the processes which communicate the most are nearer on the network. This may slighlty improves parallel
252// XD_CONT performance.
253// XD attr single_hdf rien single_hdf OPT Optional keyword to enable you to write the partitioned domaines in a single
254// XD_CONT file in hdf5 format.
255// XD attr print_more_infos entier print_more_infos OPT If this option is set to 1 (0 by default), print infos about
256// XD_CONT number of remote elements (ghosts) and additional infos about the quality of partitionning. Warning, it slows
257// XD_CONT down the cutting operations.
258template <typename _SIZE_>
260{
261 Cerr << "Decouper: Splitting of a domain" << finl;
262 // Reading parameters
263 lire(is);
264
265 // Generating partition
266 Partitionneur_base_t& partitionneur = deriv_partitionneur_.valeur();
268
269 // Writing out various files (including .zones)
270 ecrire();
271
272 Cerr << "End of the interpreter Decouper" << finl;
273 return is;
274}
275
276template <typename _SIZE_>
278{
279 // Lecture du nom du domaine a decouper:
280 is >> nom_domaine_;
281 Cerr << " Domain name to split : " << nom_domaine_ << finl;
283 // Avant de decouper on imprime des infos
284 const auto& dom = this->domaine();
285 dom.imprimer();
286
287 Noms liste_bords_perio;
288
289 Param param(this->que_suis_je());
290 bool hdf = false;
291 param.ajouter_non_std("partitionneur|partition_tool",(this),Param::REQUIRED);
292 param.ajouter("larg_joint",&epaisseur_joint_);
293 param.ajouter_condition("value_of_larg_joint_ge_1","The joint thickness must greater or equal to 1.");
294 param.ajouter("nom_zones|zones_name",&nom_domaines_decoup_);
295 param.ajouter("ecrire_decoupage",&nom_fichier_decoupage_);
296 param.ajouter("ecrire_decoupage_sommets",&nom_fichier_decoupage_sommets_);
297 param.ajouter("ecrire_lata",&nom_fichier_lata_);
298 param.ajouter("ecrire_med",&nom_fichier_med_);
299 param.ajouter("nb_parts_tot",&nb_parts_tot_);
300 param.ajouter("reorder",&reorder_);
301 param.ajouter_flag("single_hdf",&hdf);
302 param.ajouter("periodique",&liste_bords_perio); // should not be used anymore ... keeping it to have a nice error message.
303 param.ajouter("print_more_infos",&print_more_infos_);
305
306 // TRUST 1.9.8, attribute 'periodique' is now deprecated:
307 if (liste_bords_perio.size() > 0)
308 {
309 Cerr << finl << "ERROR: Option 'periodique' in Decouper/Partition keyword is now obsolete! It must be removed." << finl;
310 Cerr << "Your periodic boundaries in the domain now only needs to be declared once using the 'Declarer_bord_perio|Corriger_frontiere_periodique' keyword." << finl << finl;
312 }
313
314 if (hdf) format_ = DomainesFileOutputType::HDF5_SINGLE;
315
316 return is;
317}
318
319template <typename _SIZE_>
321{
322 // Calcul du nombre de parties generees par le partitionneur
323 int nb_parties = 0;
324 if (elem_part_.size_array() > 0)
325 nb_parties = static_cast<int>(max_array(elem_part_)) + 1; // cast to int, because max among number of procs (or numb of parts)
326 nb_parties = Process::mp_max(nb_parties);
327 Cerr << "The partitioner has generated " << nb_parties << " parts." << finl;
328
329 // Prise en compte de la directive nb_parts_tot_
330 if (nb_parts_tot_ >= 0)
331 {
332 if (nb_parties > nb_parts_tot_)
333 {
334 Cerr << "Error: nb_parts_tot_ is less than the number of parts generated by the partitioner."
335 << finl;
337 }
338 Cerr << "Number of parts requested : " << nb_parts_tot_ << finl
339 << "Generation of " << nb_parts_tot_ - nb_parties << " empty parts." << finl;
340 nb_parties = nb_parts_tot_;
341 }
342 // Force un seul fichier .Zones au dela d'un certain nombre de rangs MPI:
343 if (Process::force_single_file(nb_parties, nom_domaines_decoup_+".Zones"))
344 format_ = DomainesFileOutputType::HDF5_SINGLE;
345
346 if (nom_fichier_decoupage_ != "?")
347 ecrire_fichier_decoupage();
348
350 ecrire_fichier_decoupage_som();
351
352 if (nom_domaines_decoup_ != "?")
353 ecrire_sous_domaines(nb_parties, som_raccord);
354
355 if (nom_fichier_lata_ != "?")
356 postraiter_decoupage(nom_fichier_lata_);
357 if (nom_fichier_med_ != "?")
358 postraiter_decoupage(nom_fichier_med_);
359
360 Cout << finl << "Quality of partitioning --------------------------------------------" << finl;
361 trustIdType total_elem = Process::mp_sum(elem_part_.size_reelle());
362 Cout << "\nTotal number of elements = " << total_elem << finl;
363 Cout << "Number of Domaines : " << nb_parties << finl;
364
366 {
367 DoubleVect A(nb_parties);
368 A = 0;
369 for (int i = 0; i < elem_part_.size_reelle(); i++)
370 A(elem_part_[i]) = static_cast<double>(A(elem_part_[i])) + 1;
371
373 {
374 for(int proc=1; proc<Process::nproc(); proc++)
375 {
376 DoubleVect tmp(nb_parties);
377 tmp = 0;
378 recevoir(tmp, proc, 0, proc+2005);
379
380 for(int i_part=0; i_part<nb_parties; i_part++)
381 A(i_part) += tmp(i_part);
382 }
383
384 double mean_element_domaine = static_cast<double>(total_elem/nb_parties);
385 if (mean_element_domaine>0)
386 {
387 double load_imbalance = double(local_max_vect(A) / mean_element_domaine);
388 Cout << "Number of cells per Domaine (min/mean/max) : " << local_min_vect(A) << " / " << mean_element_domaine << " / "
389 << local_max_vect(A) << " Load imbalance: " << load_imbalance << "\n" << finl;
390 }
391 }
392 else
393 envoyer(A, Process::me(), 0, Process::me()+2005);
394
395 // we could do it as below, but if nb_parties is big, it would involve a lot of collective communication
396 // for (int i = 0; i < nb_parties; i++)
397 // A[i] = Process::mp_sum(A[i]);
398 }
399
400 Cerr << "End of the interpreter Decouper" << finl;
401 if (reorder_==0 && nb_parties>128)
402 {
403 Cerr << "Performance tip: You could add \"reorder 1\" option to have less distance between communicating processes on the network." << finl;
404 Cerr << "Add also \"Ecrire_lata filename.lata\" to post-process the partition numeration and see the difference." << finl;
405 }
406}
407
408template <typename _SIZE_>
410{
411 //Motcle motlu;
412 if (mot=="partitionneur|partition_tool")
413 {
414 Cerr << "domaine = " << nom_domaine_ << finl;
415 lire_partitionneur(is);
416 return 1;
417 }
418 return -1;
419}
420
421template class Decouper_32_64<int>;
422#if INT_is_64_ == 2
423template class Decouper_32_64<trustIdType>;
424#endif
Interprete Decouper.
Definition Decouper.h:36
void ecrire(const Static_Int_Lists_t *som_raccord=nullptr)
Definition Decouper.cpp:320
static int print_more_infos_
Definition Decouper.h:60
BigIntVect_t elem_part_
Definition Decouper.h:67
Entree & lire(Entree &is)
Definition Decouper.cpp:277
Partitionneur_base_32_64< _SIZE_ > Partitionneur_base_t
Definition Decouper.h:47
Nom nom_fichier_lata_
Definition Decouper.h:75
Nom nom_domaines_decoup_
Definition Decouper.h:72
Nom nom_fichier_decoupage_
Definition Decouper.h:73
Nom nom_fichier_med_
Definition Decouper.h:76
int nb_parts_tot_
Definition Decouper.h:65
Entree & interpreter(Entree &is) override
Definition Decouper.cpp:259
Static_Int_Lists_32_64< _SIZE_ > Static_Int_Lists_t
Definition Decouper.h:48
DomainesFileOutputType format_
Definition Decouper.h:77
Nom nom_fichier_decoupage_sommets_
Definition Decouper.h:74
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.
Definition Decouper.cpp:409
int epaisseur_joint_
Definition Decouper.h:71
Classe outil permettant de generer des sous-domaines pour un calcul parallele a partir d'un domaine d...
void ecrire_domaines(const Nom &basename, const DomainesFileOutputType format, const int reorder, const Static_Int_Lists_t *som_raccord=nullptr)
Generation de tous les sous-domaines du calcul et ecriture sur disque des fichiers basename_000n.
void initialiser(const Domaine_t &domaine_global, const BigIntVect_t &elem_part, const int nb_parts, const int epaisseur_joint, const bool permissif=false)
Prepare les structures de donnees pour la construction des sous-domaines en fonction d'un decoupage f...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
: Classe de postraitement des champs euleriens au format lata
int ecrire_entete(const double temps_courant, const int reprise, const int est_le_premier_post) override
Ouvre le fichier maitre en mode ERASE et ecrit l'entete du fichier lata (sur le processeur maitre seu...
virtual int initialize_lata(const Nom &file_basename, const Format format=ASCII, const Options_Para options_para=SINGLE_FILE)
Initialisation de la classe, ouverture du fichier et ecriture de l'entete.
@ BINAIRE
@ SINGLE_FILE
int ecrire_domaine(const Domaine &domaine, const int est_le_premier_post) override
voir Format_Post_base::ecrire_domaine On accepte l'ecriture d'un domaine dans un pas de temps,...
int ecrire_temps(const double temps) override
commence l'ecriture d'un nouveau pas de temps En l'occurence pour le format LATA:
int ecrire_champ(const Domaine &domaine, const Noms &unite_, const Noms &noms_compo, int ncomp, double temps_, const Nom &id_du_champ, const Nom &id_du_domaine, const Nom &localisation, const Nom &nature, const DoubleTab &data) override
voir Format_Post_base::ecrire_champ
int finir(const int est_le_dernier_post) override
int initialize(const Nom &file_basename, const int format, const Nom &option_para) override
Classe de base des formats de postraitements pour les champs (lata, med, cgns, lml,...
Classe de base des objets "interprete".
Definition Interprete.h:38
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:76
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
Definition Param.cpp:474
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.
Definition Param.cpp:496
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
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.
Definition Param.cpp:489
int lire_avec_accolades_depuis(Entree &is)
Parse the parameter block { ... } from is.
Definition Param.cpp:32
Classe de base des partitionneurs de domaine (pour decouper un maillage avant un calcul parallele).
virtual void associer_domaine(const Domaine_t &domaine)=0
virtual void construire_partition(BigIntVect_ &elem_part, int &nb_parts_tot) const =0
static double mp_max(double)
Definition Process.cpp:376
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static bool force_single_file(const int ranks, const Nom &filename)
Definition Process.cpp:60
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Classe de base des flux de sortie.
Definition Sortie.h:52