TrioCFD 1.9.9_beta
TrioCFD documentation
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 // Warning: parallel communications must not be used at this early stage.
74 // Cerr and Cout are OK (static variables in Journal_log_files.cpp)
75 // The journal can be used but writes to Sortie_Nulle until the log files are opened
76 // (see Journal_log_files.cpp)
77 //
78 // See <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// Strange crashes on clang++, fcc, nvc++, nvcc compilers so we disable this:
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 // -help is reserved by 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 // The last two tests must remain at the end; insert any additional arguments before them.
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 // Commented out because some verification scripts test: 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 read: " << argv[0];
248 //Cerr << " " << argv[i];
249 /* PL: Disabled because MPICH appends arguments after the number of processors:
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 of Petsc and the parallel layer (if Petsc) **********
261 // .. and start of the journal
262 // (everything that should be shared with the Python interface must be
263 // placed in 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 // From here on, inter-processor communications are allowed,
287 // me() etc...
288 const int master = Process::je_suis_maitre();
289
290 // Modif B.Mathieu 28/09/2004:
291 // To debug TRUST, a system command name can be passed as a parameter
292 // to be executed when this point is reached.
293 // The most convenient approach is a shell script that opens
294 // an xterm and launches gdb. A tail -f on the log file also works.
295 // The command is executed with the PE rank as its argument.
296 if(exec_script != "")
297 {
298 exec_script += " ";
299 exec_script += Nom(Process::me());
300 Cerr << "[" << Process::me() << "] Debug mode => execute command : " << exec_script << finl;
301 std::cerr << system(exec_script) << std::endl;
302 }
303
304 if (master)
305 {
306 if (helptrust) usage();
307
308 // The command-line summary is printed here to avoid filling stderr
309 // with output from all processors...
310 Cerr << arguments_info;
311
312 if (nproc != -1 && Process::nproc() != nproc)
313 {
314 Cerr << "Error: nproc on command line does not match mpirun parameter.\n"
315 << " Use same number or -mpi parameter instead." << finl;
316 usage();
317 }
318 }
319
320 cerr.setf(ios::scientific);
321 cerr.precision(12);
322 cout.setf(ios::scientific);
323 cout.precision(12);
324
325 // Handle dataset name - only if we are not in unit_test mode for which we do not want to process any datafile at all.
326 if (!unit_test)
327 {
328 // ****************** Case name ***********************
329 if (data_file == "")
330 {
331 // TRUST without argument => case name = current directory name
332 Nom pwd(::pwd());
333 if (master)
334 Cerr << "No command line argument. Data file name from directory name:\n "
335 << pwd << finl;
336 const int l = pwd.longueur() - 1; // Note: longueur()=strlen+1
337 int i = l - 1;
338 while(i > 0 && pwd[i] != directory_separator)
339 {
340 i--;
341 }
342 if (i == l - 1)
343 {
344 if (master)
345 {
346 Cerr << "Error : pwd() ends with directory separator " << (int)directory_separator << finl;
348 }
349 }
350 data_file = pwd.substr_old(i + 2, l - i - 1); // Note: see Nom::substr()
351 }
352 if (master)
353 {
354 Cerr << "Data file : " << data_file << finl;
355 }
356 // If the case name ends with .data, strip the extension.
357 if (data_file.finit_par(".data"))
358 {
359 if (master)
360 {
361 Cerr << " (removing .data extension)" << finl;
362 }
363 data_file.prefix(".data");
364 }
365
366 if (master)
367 {
368 Cerr<<"Study location: " << ::pwd() << finl;
369 Cerr<<"Case name: " << data_file << finl;
370 Cerr<<" code : "<< argv[0] << finl;
371 Cerr<<" version : " << TRUST_VERSION << " " << finl;
372 }
373
374 main_process->dowork(data_file);
375 }
376
377
378 if (master)
379 {
380 Cerr << "Stopping processes." << finl;
381#ifndef NDEBUG
382 Cerr << finl;
383 Cerr << "DEBUG: Statistics for Trav arrays (int): " << finl;
385 Cerr << finl;
386 Cerr << "DEBUG: Statistics for Trav arrays (double): " << finl;
388 Cerr << finl;
389 Cerr << "DEBUG: Statistics for Trav arrays (float): " << finl;
391#endif
392 }
393
394 // Clear TravPool (host AND device):
398
399 //Clean static views in Schema_Comm_Vecteurs
401
402 // Clean
404 }
405
406 // In some very tricky cases (typically Pilote_ICoCo keyword) this might have already been closed:
407 if(statistics().is_running(STD_COUNTERS::total_execution_time))
408 statistics().end_count(STD_COUNTERS::total_execution_time);
409
410 // free the last remaining bytes
411 desalloue_pwd();
412 return (0);
413}
414
415
static void CleanMyStatics()
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
virtual int finit_par(const char *const n) const
Definition Nom.cpp:319
Nom substr_old(const int, const int) const
Returns a name using the usual substr command. NOTE: deb = 1 means the first character of the string.
Definition Nom.cpp:466
Nom & prefix(const char *const)
Definition Nom.cpp:324
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
Definition Process.cpp:102
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
static void ClearPool()
Empty the TRUSTTrav pool explicitely.
static void PrintStats()
Debug method printing useful stats.
Class created and run by main() and during a TRUST execution through Python.
Definition mon_main.h:38
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