TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
MAIN.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
16#include <MAIN.h>
17#include <sys/types.h>
18#include <stdlib.h>
19#include <mon_main.h>
20#include <EFichier.h>
21#include <Perf_counters.h>
22#ifdef linux
23#include <fenv.h>
24#endif
25#include <errno.h>
26#ifdef VTRACE
27#include <vt_user.h>
28#endif
29#ifdef MICROSOFT
30static const char directory_separator = '\\';
31#else
32static const char directory_separator = '/';
33#endif
34#include <DeviceMemory.h>
35#include <TRUSTTravPool.h>
36#include <Schema_Comm_Vecteurs.h>
37#include <MD_Vector_tools.h>
38
39extern void desalloue_pwd();
40void usage()
41{
42 Cerr << "usage:\n";
43 Cerr << "TRUST_EXECUTABLE [CASE[.data]] [options]\n";
44 Cerr << " CASE is the basename of the trust data file (must have .data extension)\n";
45 Cerr << " If no CASE given, the current directory name is used\n";
46 Cerr << " -help_trust => print options\n";
47 Cerr << " -mpi => run in parallel with MPI (must run with mpirun)\n";
48 Cerr << " -check_enabled=0|1 => enables or disables runtime checking of parallel messages\n";
49 Cerr << " -debugscript=SCRIPT => execute \"SCRIPT n\" after parallel initialisation, n=processor rank\n";
50 Cerr << " -petsc=0 => disable call to PetscInitialize\n";
51 Cerr << " -journal=0..9 => select journal level (0=disable, 9=maximum verbosity)\n";
52 Cerr << " -journal_master => only master processor writes a journal \n";
53 Cerr << " -log_directory=DIR => Writes the .log files into directory DIR\n";
54 Cerr << " -disable_ieee => Disable the detection of NaNs. The detection can also be de-activated with env variable TRUST_DISABLE_FP_EXCEPT set to non zero.\n";
55 Cerr << " -no_verify => Disable the call to verifie function (from Type_Verifie) to catch outdated keywords while reading data file.\n";
56 Cerr << " -disable_stop => Disable the writing of the .stop file.\n";
57 Cerr << " -unit => Only perform TRUST initialisation without trying to execute any data file. Used for unit testing.\n";
58 Cerr << finl;
60}
61
62#ifdef NDEBUG
63#define DEFAULT_CHECK_ENABLED 0
64#else
65#define DEFAULT_CHECK_ENABLED 1
66#endif
67
68int main_TRUST(int argc, char** argv,mon_main*& main_process,bool with_mpi, bool ieee)
69{
70#ifdef VTRACE
71 //VT_USER_END("Initialization");
72#endif
73 // Attention: on n'a pas le droit d'utiliser les communications paralleles au debut.
74 // Cerr et Cout sont OK (variables statiques dans Journal_log_files.cpp)
75 // Le journal peut etre utilise mais ecrit dans Sortie_Nulle jusqu'a ce qu'on ouvre
76 // les fichiers (voir Journal_log_files.cpp)
77 //
78 // Voir <PARALLEL_OK>
79
80 // *************** Process command-line arguments ********************
81 int check_enabled = DEFAULT_CHECK_ENABLED;
82 bool with_petsc = true;
83 int nproc = -1;
84 int verbose_level = -1;
85 bool journal_master = false;
86
87 Nom log_directory = "";
88 bool helptrust = false;
89 // if bool ieee = true => use of feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
90// Crashes bizarres sur compilateurs clang++, fcc, nvc++, nvcc donc on desactive:
91#if defined(_COMPILE_AVEC_CLANG) || defined (_COMPILE_AVEC_FCC) || defined(__NVCOMPILER) || defined(__NVCC__)
92 ieee = false;
93#endif
94 bool apply_verification = true;
95 bool disable_stop = false;
96 bool unit_test = false;
97 Nom data_file;
98 data_file = "";
99 Nom exec_script;
100 exec_script = "";
101 Nom arguments_info;
102 arguments_info = "Executable: ";
103 arguments_info += argv[0];
104 arguments_info += "\n";
105 for (int i = 1; i < argc; i++)
106 {
107 // int error = 0;
108 // Le -help est reserve par Petsc
109 if (strcmp(argv[i], "-help_trust") == 0)
110 {
111 helptrust = true;
112 }
113 else if (strcmp(argv[i], "-disable_ieee") == 0)
114 {
115 ieee = false;
116 arguments_info += "-disable_ieee => disable of feenableexcept\n";
117 }
118 else if (strcmp(argv[i], "-mpi") == 0)
119 {
120 with_mpi = true;
121 arguments_info += "-mpi => parallel computation with mpi\n";
122 }
123 else if (strcmp(argv[i], "-no_verify") == 0)
124 {
125 apply_verification = false;
126 arguments_info += "-no_verify => Disable the call to verifie function (from Type_Verifie) to catch outdated keywords while reading data file.\n";
127 }
128 else if (strcmp(argv[i], "-check_enabled=1") == 0)
129 {
130 check_enabled = true;
131 arguments_info += "-check_enabled=1 => force enable parallel message checking\n";
132 }
133 else if (strcmp(argv[i], "-check_enabled=0") == 0)
134 {
135 check_enabled = false;
136 arguments_info += "-check_enabled=0 => force disable parallel message checking\n";
137 }
138 else if (strncmp(argv[i], "-debugscript=", 13) == 0)
139 {
140 exec_script = argv[i]+13;
141 arguments_info += "-debugscript => execute script ";
142 arguments_info += exec_script;
143 arguments_info += "\n";
144 }
145 else if (strcmp(argv[i], "-petsc=0") == 0)
146 {
147 with_petsc = false;
148 arguments_info += "-petsc=0 => disable call to PetscInitialize\n";
149 }
150 else if (strncmp(argv[i], "-journal=", 9) == 0)
151 {
152 int level = atoi(argv[i]+9);
153 if (level < 0 || level > 9)
154 {
155 Cerr << "Bad journal level : " << argv[i] << finl;
156 // error = 1;
157 }
158 else
159 {
160 verbose_level = level;
161 arguments_info += "-journal=";
162 arguments_info += Nom(level);
163 arguments_info += "\n";
164 }
165 }
166 else if (strcmp(argv[i], "-journal_master") == 0)
167 {
168 journal_master = true;
169 arguments_info += "-journal_master => Only the master processor will write a journal";
170 arguments_info += "\n";
171 }
172 else if (strncmp(argv[i], "-log_directory=", 15) == 0)
173 {
174 log_directory = argv[i]+15;
175 log_directory += directory_separator;
176 arguments_info += "-log_directory => Writes the .log files into directory ";
177 arguments_info += log_directory;
178 arguments_info += "\n";
179 }
180 else if (strcmp(argv[i], "-disable_stop") == 0)
181 {
182 disable_stop = true;
183 arguments_info += "-disable_stop => Disable the writing of the .stop file.\n";
184 }
185 else if (strcmp(argv[i], "-unit") == 0)
186 {
187 unit_test = true;
188 }
189 else if (i == 1)
190 {
191 // Les deux derniers tests doivent rester a la fin, inserer les arguments supplementaires avant.
192 data_file = argv[1];
193 arguments_info += "Data file name = ";
194 arguments_info += data_file;
195 arguments_info += "\n";
196 }
197 else if (i == 2)
198 {
199 errno = 0;
200 int nprocs = (int) strtol(argv[2], (char **)nullptr, 10);
201 if (!errno && nprocs)
202 {
203 nproc = nprocs;
204 if (nproc > 1)
205 {
206 with_mpi = true;
207 arguments_info += "Running in parallel with ";
208 arguments_info += Nom(nproc);
209 arguments_info += " processors\n";
210 }
211 else if (nproc == 1)
212 {
213 arguments_info += "Sequential calculation\n";
214 }
215 else
216 {
217 Cerr << "Bad number of processors in old syntax TRUST case N" << finl;
218 //error = 1;
219 }
220 }
221 else
222 {
223 // Mise en commentaire car dans certains scripts verifie on teste: trust $jdd -ksp_view
224 /*
225 Nom fichier=argv[i];
226 fichier.prefix(".data");
227 fichier+=".data";
228 EFichier fic(fichier);
229 if(fic.fail())
230 {
231 Cerr << "Trying to open file " << fichier << finl;
232 Cerr << "File " << fichier << " doesnt exist !" << finl;
233 Process::exit();
234 }
235 else
236 {
237 data_file = fichier.prefix(".data");
238 }
239 */
240 //error = 1;
241 }
242 }
243 else
244 {
245 //error = 1;
246 }
247 //if (i==1) Cerr << "Arguments lus: " << argv[0];
248 //Cerr << " " << argv[i];
249 /* PL: Je desactive car MPICH rajoute des arguments derriere le nombre de processeurs:
250 ... TRUST_mpich_opt jdd 2 -p4pg .../PINNNN -p4wd pathname
251 if (error) {
252 Cerr << "TRUST error processing command line, argument " << i << " : \n "
253 << argv[i] << finl;
254 usage();
255 } */
256 }
257
258 {
259
260 // ************** Initialisation de Petsc, du parallele (si Petsc) **********
261 // .. et demarrage du journal
262 // (tout ce qu'on veut faire en commun avec l'interface python doit etre
263 // mis dans mon_main)
264 statistics().begin_count(STD_COUNTERS::total_execution_time);
265 main_process=new mon_main(verbose_level, journal_master, log_directory, apply_verification, disable_stop);
266 main_process->init_parallel(argc, argv, with_mpi, check_enabled, with_petsc);
267
268 // Floating point exceptions (moved after MPI_Init cause some MPI installs may seg-fault)
269#ifdef linux
270 fedisableexcept(FE_ALL_EXCEPT);
271#endif
272 if (ieee)
273 {
274 char* theValue = getenv("TRUST_DISABLE_FP_EXCEPT");
275 if (theValue == nullptr || atoi(theValue) == 0)
276 {
277 arguments_info += "feenableexcept enabled.\n";
278#ifdef linux
279 // Detect all NaNs (don't add FE_UNDERFLOW cause exp(-x) with x big throws an exception)
280 // Test pre 1.7.0, on active en optimise:
281 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
282#endif
283 }
284 }
285
286 // A partir d'ici on a le droit d'utiliser les communications entre processeurs,
287 // me() etc...
288 const int master = Process::je_suis_maitre();
289
290 // Modif B.Mathieu 28/09/2004 :
291 // Pour debugger trust, on donne parametre le nom
292 // d'une commande systeme a executer lorsqu'on arrive a cet endroit.
293 // Le plus pratique, c'est d'utiliser un shell script qui ouvre
294 // un xterm et lance gdb. On peut aussi faire un tail -f du fichier log,
295 // etc...
296 // La commande est executee avec comme parametre le numero du PE.
297 if(exec_script != "")
298 {
299 exec_script += " ";
300 exec_script += Nom(Process::me());
301 Cerr << "[" << Process::me() << "] Debug mode => execute command : " << exec_script << finl;
302 std::cerr << system(exec_script) << std::endl;
303 }
304
305 if (master)
306 {
307 if (helptrust) usage();
308
309 // On affiche le resultat de la ligne de commande ici pour ne pas remplir stderr
310 // avec tous les processeurs...
311 Cerr << arguments_info;
312
313 if (nproc != -1 && Process::nproc() != nproc)
314 {
315 Cerr << "Error: nproc on command line does not match mpirun parameter.\n"
316 << " Use same number or -mpi parameter instead." << finl;
317 usage();
318 }
319 }
320
321 cerr.setf(ios::scientific);
322 cerr.precision(12);
323 cout.setf(ios::scientific);
324 cout.precision(12);
325
326 // Handle dataset name - only if we are not in unit_test mode for which we do not want to process any datafile at all.
327 if (!unit_test)
328 {
329 // ****************** Nom du cas ***********************
330 if (data_file == "")
331 {
332 // TRUST sans argument => nom du cas = nom du repertoire courant
333 Nom pwd(::pwd());
334 if (master)
335 Cerr << "No command line argument. Data file name from directory name:\n "
336 << pwd << finl;
337 const int l = pwd.longueur() - 1; // Attention, longueur()=strlen+1
338 int i = l - 1;
339 while(i > 0 && pwd[i] != directory_separator)
340 {
341 i--;
342 }
343 if (i == l - 1)
344 {
345 if (master)
346 {
347 Cerr << "Error : pwd() ends with directory separator " << (int)directory_separator << finl;
349 }
350 }
351 data_file = pwd.substr_old(i + 2, l - i - 1); // Attention, voir Nom::substr()
352 }
353 if (master)
354 {
355 Cerr << "Data file : " << data_file << finl;
356 }
357 // Si le nom du cas finit par .data, on l'enleve.
358 if (data_file.finit_par(".data"))
359 {
360 if (master)
361 {
362 Cerr << " (removing .data extension)" << finl;
363 }
364 data_file.prefix(".data");
365 }
366
367 if (master)
368 {
369 Cerr<<"Localisation etude: " << ::pwd() << finl;
370 Cerr<<"Nom du cas " << data_file << finl;
371 Cerr<<" code : "<< argv[0] << finl;
372 Cerr<<" version : " << TRUST_VERSION << " " << finl;
373 }
374
375 main_process->dowork(data_file);
376 }
377
378
379 if (master)
380 {
381 Cerr << "Arret des processes." << finl;
382#ifndef NDEBUG
383 Cerr << finl;
384 Cerr << "DEBUG: Statistics for Trav arrays (int): " << finl;
386 Cerr << finl;
387 Cerr << "DEBUG: Statistics for Trav arrays (double): " << finl;
389 Cerr << finl;
390 Cerr << "DEBUG: Statistics for Trav arrays (float): " << finl;
392#endif
393 }
394
395 // Clear TravPool (host AND device):
399
400 //Clean static views in Schema_Comm_Vecteurs
402
403 // Clean
405 }
406
407 // In some very tricky cases (typically Pilote_ICoCo keyword) this might have already been closed:
408 if(statistics().is_running(STD_COUNTERS::total_execution_time))
409 statistics().end_count(STD_COUNTERS::total_execution_time);
410
411 // pour detruire les derniers octets
412 desalloue_pwd();
413 return (0);
414}
415
416
static void CleanMyStatics()
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
virtual int finit_par(const char *const n) const
Definition Nom.cpp:324
Nom substr_old(const int, const int) const
Retourne un nom selon la commande usuelle substr ATTENTION : deb = 1 => premier caractere de la chain...
Definition Nom.cpp:473
Nom & prefix(const char *const)
Definition Nom.cpp:329
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 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
static void ClearPool()
static void PrintStats()
Classe creee et executee par main() et lors d'une execution TRUST a travers Python.
Definition mon_main.h:39
void dowork(const Nom &nom_du_cas)
Definition mon_main.cpp:343
void init_parallel(const int argc, char **argv, bool with_mpi, bool check_enabled=false, bool with_petsc=true)
Definition mon_main.cpp:198