1 #ifndef __CS_BASE_H__
2 #define __CS_BASE_H__
3 
4 /*============================================================================
5  * Definitions, global variables, and base functions
6  *============================================================================*/
7 
8 /*
9   This file is part of Code_Saturne, a general-purpose CFD tool.
10 
11   Copyright (C) 1998-2021 EDF S.A.
12 
13   This program is free software; you can redistribute it and/or modify it under
14   the terms of the GNU General Public License as published by the Free Software
15   Foundation; either version 2 of the License, or (at your option) any later
16   version.
17 
18   This program is distributed in the hope that it will be useful, but WITHOUT
19   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21   details.
22 
23   You should have received a copy of the GNU General Public License along with
24   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25   Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27 
28 /*----------------------------------------------------------------------------*/
29 
30 #include "cs_defs.h"
31 
32 /*----------------------------------------------------------------------------
33  * Standard C library headers
34  *----------------------------------------------------------------------------*/
35 
36 #include <stdio.h>
37 
38 /*----------------------------------------------------------------------------
39  *  Local headers
40  *----------------------------------------------------------------------------*/
41 
42 /*=============================================================================
43  * Macro definitions
44  *============================================================================*/
45 
46 /* Application type name */
47 
48 #define CS_APP_NAME     "Code_Saturne"
49 #define CS_APP_VERSION  PACKAGE_VERSION  /* PACKAGE_VERSION from autoconf */
50 
51 /* System type name */
52 
53 #if defined(__linux__) || defined(__linux) || defined(linux)
54 #define _CS_ARCH_Linux
55 
56 #endif
57 
58 /* On certain architectures such as IBM Blue Gene, some operations may
59  * be better optimized on memory-aligned data (if 0 here, no alignment
60  * is leveraged). This alignment is not exploited yet in Code_Saturne. */
61 
62 #define CS_MEM_ALIGN 0
63 
64 #define CS_BASE_STRING_LEN                             80
65 
66 /*----------------------------------------------------------------------------*/
67 
68 BEGIN_C_DECLS
69 
70 /*============================================================================
71  * Type definitions
72  *============================================================================*/
73 
74 /* Function pointers for extra cleanup operations to be called when
75    entering cs_exit() or bft_error() */
76 
77 typedef void (cs_base_atexit_t) (void);
78 
79 /*=============================================================================
80  * Global variable definitions
81  *============================================================================*/
82 
83 /*=============================================================================
84  * Public function prototypes
85  *============================================================================*/
86 
87 /*----------------------------------------------------------------------------*/
88 /*!
89  * \brief  Return a string "true" or "false" according to the boolean
90  *
91  * \param[in]  boolean  bool type
92  *
93  * \return a string "true" or "false"
94  */
95 /*----------------------------------------------------------------------------*/
96 
97 static inline const char *
cs_base_strtf(bool boolean)98 cs_base_strtf(bool  boolean)
99 {
100   if (boolean)
101     return "**True**";
102   else
103     return "**False**";
104 }
105 
106 /*----------------------------------------------------------------------------
107  * First analysis of the command line to determine an application name.
108  *
109  * If no name is defined by the command line, a name is determined based
110  * on the working directory.
111  *
112  * The caller is responsible for freeing the returned string.
113  *
114  * parameters:
115  *   argc  <-- number of command line arguments
116  *   argv  <-- array of command line arguments
117  *
118  * returns:
119  *   pointer to character string with application name
120  *----------------------------------------------------------------------------*/
121 
122 char *
123 cs_base_get_app_name(int          argc,
124                      const char  *argv[]);
125 
126 /*----------------------------------------------------------------------------
127  * Print logfile header
128  *
129  * parameters:
130  *   argc  <-- number of command line arguments
131  *   argv  <-- array of command line arguments
132  *----------------------------------------------------------------------------*/
133 
134 void
135 cs_base_logfile_head(int    argc,
136                      char  *argv[]);
137 
138 #if defined(HAVE_MPI)
139 
140 /*----------------------------------------------------------------------------
141  * First analysis of the command line and environment variables to determine
142  * if we require MPI, and initialization if necessary.
143  *
144  * parameters:
145  *   argc  <-> number of command line arguments
146  *   argv  <-> array of command line arguments
147  *
148  * Global variables `cs_glob_n_ranks' (number of Code_Saturne processes)
149  * and `cs_glob_rank_id' (rank of local process) are set by this function.
150  *----------------------------------------------------------------------------*/
151 
152 void
153 cs_base_mpi_init(int    *argc,
154                  char  **argv[]);
155 
156 /*----------------------------------------------------------------------------*/
157 /*!
158  * \brief Return a reduced communicator matching a multiple of the total
159  *        number of ranks.
160  *
161  * This updates the number of reduced communicators if necessary.
162  *
163  * \param[in]  rank_step  associated multiple of total ranks
164  */
165 /*----------------------------------------------------------------------------*/
166 
167 MPI_Comm
168 cs_base_get_rank_step_comm(int  rank_step);
169 
170 #endif /* defined(HAVE_MPI) */
171 
172 /*----------------------------------------------------------------------------
173  * Exit, with handling for both normal and error cases.
174  *
175  * Finalize MPI if necessary.
176  *
177  * parameters:
178  *   status <-- value to be returned to the parent:
179  *              EXIT_SUCCESS / 0 for the normal case,
180  *              EXIT_FAILURE or other nonzero code for error cases.
181  *----------------------------------------------------------------------------*/
182 
183 void
184 cs_exit(int  status);
185 
186 /*----------------------------------------------------------------------------
187  * Initialize error and signal handlers.
188  *
189  * parameters:
190  *   signal_defaults <-- leave default signal handlers in place if true.
191  *----------------------------------------------------------------------------*/
192 
193 void
194 cs_base_error_init(bool  signal_defaults);
195 
196 /*----------------------------------------------------------------------------
197  * Initialize management of memory allocated through BFT.
198  *----------------------------------------------------------------------------*/
199 
200 void
201 cs_base_mem_init(void);
202 
203 /*----------------------------------------------------------------------------
204  * Finalize management of memory allocated through BFT.
205  *
206  * A summary of the consumed memory is given.
207  *----------------------------------------------------------------------------*/
208 
209 void
210 cs_base_mem_finalize(void);
211 
212 /*----------------------------------------------------------------------------
213  * Print summary of running time, including CPU and elapsed times.
214  *----------------------------------------------------------------------------*/
215 
216 void
217 cs_base_time_summary(void);
218 
219 /*----------------------------------------------------------------------------*/
220 /*!
221  * \brief Update status file.
222  *
223  * If the format string is NULL, the file is removed.
224 
225  * \param[in]  format  format string, or NULL
226  * \param[in]  ...     format arguments
227  */
228 /*----------------------------------------------------------------------------*/
229 
230 void
231 cs_base_update_status(const char  *format,
232                       ...);
233 
234 /*----------------------------------------------------------------------------
235  * Set tracing of progress on or off.
236  *
237  * parameters:
238  *   trace  <-- trace progress to stdout
239  *----------------------------------------------------------------------------*/
240 
241 void
242 cs_base_trace_set(bool trace);
243 
244 
245 /*----------------------------------------------------------------------------
246  * Set output file name and suppression flag for bft_printf().
247  *
248  * This allows redirecting or suppressing logging for different ranks.
249  *
250  * parameters:
251  *   log_name    <-- base file name for log
252  *   rn_log_flag <-- redirection for ranks > 0 log:
253  *   rn_log_flag <-- redirection for ranks > 0 log:
254  *                   false: to "/dev/null" (suppressed)
255  *                   true: to <log_name>_r*.log" file;
256  *----------------------------------------------------------------------------*/
257 
258 void
259 cs_base_bft_printf_init(const char  *log_name,
260                         bool         rn_log_flag);
261 
262 /*----------------------------------------------------------------------------
263  * Replace default bft_printf() mechanism with internal mechanism.
264  *
265  * This allows redirecting or suppressing logging for different ranks.
266  *
267  * parameters:
268  *   log_name    <-- base file name for log
269  *----------------------------------------------------------------------------*/
270 
271 void
272 cs_base_bft_printf_set(const char  *log_name,
273                        bool         rn_log_flag);
274 
275 /*----------------------------------------------------------------------------
276  * Return name of default log file.
277  *
278  * cs_base_bft_printf_set or cs_base_c_bft_printf_set() must have
279  * been called before this.
280  *
281  * returns:
282  *   name of default log file
283  *----------------------------------------------------------------------------*/
284 
285 const char *
286 cs_base_bft_printf_name(void);
287 
288 /*----------------------------------------------------------------------------
289  * Return flag indicating if the default log file output is suppressed.
290  *
291  * cs_base_bft_printf_set or cs_base_c_bft_printf_set() must have
292  * been called before this.
293  *
294  * returns:
295  *   output suppression flag
296  *----------------------------------------------------------------------------*/
297 
298 bool
299 cs_base_bft_printf_suppressed(void);
300 
301 /*----------------------------------------------------------------------------
302  * Print a warning message header.
303  *
304  * parameters:
305  *   file_name <-- name of source file
306  *   line_nume <-- line number in source file
307  *----------------------------------------------------------------------------*/
308 
309 void
310 cs_base_warn(const char  *file_name,
311              int          line_num);
312 
313 /*----------------------------------------------------------------------------
314  * Define a function to be called when entering cs_exit() or bft_error().
315  *
316  * Compared to the C atexit(), only one function may be called (latest
317  * setting wins), but the function is called slightly before exit,
318  * so it is well adapted to cleanup such as flushing of non-C API logging.
319  *
320  * parameters:
321  *   fct <-- pointer tu function to be called
322  *----------------------------------------------------------------------------*/
323 
324 void
325 cs_base_atexit_set(cs_base_atexit_t  *const fct);
326 
327 /*----------------------------------------------------------------------------
328  * Convert a character string from the Fortran API to the C API.
329  *
330  * Eventual leading and trailing blanks are removed.
331  *
332  * parameters:
333  *   f_str <-- Fortran string
334  *   f_len <-- Fortran string length
335  *
336  * returns:
337  *   pointer to C string
338  *----------------------------------------------------------------------------*/
339 
340 char *
341 cs_base_string_f_to_c_create(const char  *f_str,
342                              int          f_len);
343 
344 /*----------------------------------------------------------------------------
345  * Free a string converted from the Fortran API to the C API.
346  *
347  * parameters:
348  *   str <-> pointer to C string
349  *----------------------------------------------------------------------------*/
350 
351 void
352 cs_base_string_f_to_c_free(char  **c_str);
353 
354 /*----------------------------------------------------------------------------
355  * Clean a string representing options.
356  *
357  * Characters are converted to lowercase, leading and trailing whitespace
358  * is removed, and multiple whitespaces or tabs are replaced by single
359  * spaces.
360  *
361  * parameters:
362  *   s <-> string to be cleaned
363  *----------------------------------------------------------------------------*/
364 
365 void
366 cs_base_option_string_clean(char  *s);
367 
368 /*----------------------------------------------------------------------------
369  * Return a string providing locale path information.
370  *
371  * This is normally the path determined upon configuration, but may be
372  * adapted for movable installs using the CS_ROOT_DIR environment variable.
373  *
374  * returns:
375  *   locale path
376  *----------------------------------------------------------------------------*/
377 
378 const char *
379 cs_base_get_localedir(void);
380 
381 /*----------------------------------------------------------------------------
382  * Return a string providing package data path information.
383  *
384  * This is normally the path determined upon configuration, but may be
385  * adapted for movable installs using the CS_ROOT_DIR environment variable.
386  *
387  * returns:
388  *   package data path
389  *----------------------------------------------------------------------------*/
390 
391 const char *
392 cs_base_get_pkgdatadir(void);
393 
394 /*----------------------------------------------------------------------------
395  * Return a string providing loadable library path information.
396  *
397  * This is normally the path determined upon configuration, but may be
398  * adapted for movable installs using the CS_ROOT_DIR environment variable.
399  *
400  * returns:
401  *   package loadable library (plugin) path
402  *----------------------------------------------------------------------------*/
403 
404 const char *
405 cs_base_get_pkglibdir(void);
406 
407 /*----------------------------------------------------------------------------
408  * Ensure bool argument has value 0 or 1.
409  *
410  * This allows working around issues with Intel compiler C bindings,
411  * which seem to pass incorrect values in some cases.
412  *
413  * parameters:
414  *   b <-> pointer to bool
415  *----------------------------------------------------------------------------*/
416 
417 void
418 cs_base_check_bool(bool *b);
419 
420 /*----------------------------------------------------------------------------
421  * Open a data file in read mode.
422  *
423  * If a file of the given name in the working directory is found, it
424  * will be opened. Otherwise, it will be searched for in the "data/thch"
425  * subdirectory of pkgdatadir.
426  *
427  * parameters:
428  *   base_name      <-- base file name
429  *
430  * returns:
431  *   pointer to opened file
432  *----------------------------------------------------------------------------*/
433 
434 FILE *
435 cs_base_open_properties_data_file(const char  *base_name);
436 
437 #if defined(HAVE_DLOPEN)
438 
439 /*----------------------------------------------------------------------------*/
440 /*!
441  * \brief Load a dynamic library.
442  *
443  * \param[in]  filename  path to shared library file.
444  *
445  * \return  handle to shared library
446  */
447 /*----------------------------------------------------------------------------*/
448 
449 void*
450 cs_base_dlopen(const char *filename);
451 
452 /*----------------------------------------------------------------------------*/
453 /*!
454  * \brief Load a plugin's dynamic library
455  *
456  * This function is similar to \ref cs_base_dlopen, except that only
457  * the base plugin file name (with no extension) needs to be given.
458  * It is assumed the file is available in the code's "pkglibdir" directory,
459  *
460  * \param[in]  name  path to shared library file
461  *
462  * \return  handle to shared library
463  */
464 /*----------------------------------------------------------------------------*/
465 
466 void*
467 cs_base_dlopen_plugin(const char *name);
468 
469 /*----------------------------------------------------------------------------*/
470 /*!
471  * \brief Get flags for dlopen.
472  *
473  * \return  flags used for dlopen.
474  */
475 /*----------------------------------------------------------------------------*/
476 
477 int
478 cs_base_dlopen_get_flags(void);
479 
480 /*----------------------------------------------------------------------------*/
481 /*!
482  * \brief Set flags for dlopen.
483  *
484  * \param[in]  flags  flags to set
485  */
486 /*----------------------------------------------------------------------------*/
487 
488 void
489 cs_base_dlopen_set_flags(int flags);
490 
491 /*----------------------------------------------------------------------------*/
492 /*!
493  * \brief Unload a dynamic library.
494  *
495  * Note that the dlopen underlying mechanism uses a reference count, so
496  * a library is really unloaded only one \ref cs_base_dlclose has been called
497  * the same number of times as \ref cs_base_dlopen.
498  *
499  * \param[in]  filename  optional path to shared library file name for error
500  *                       logging, or NULL
501  * \param[in]  handle    handle to shared library
502  */
503 /*----------------------------------------------------------------------------*/
504 
505 void
506 cs_base_dlclose(const char  *filename,
507                 void        *handle);
508 
509 /*----------------------------------------------------------------------------*/
510 /*!
511  * \brief Get a shared library function pointer
512  *
513  * \param[in]  handle            handle to shared library
514  * \param[in]  name              name of function symbol in library
515  * \param[in]  errors_are_fatal  abort if true, silently ignore if false
516  *
517  * \return  pointer to function in shared library
518  */
519 /*----------------------------------------------------------------------------*/
520 
521 void *
522 cs_base_get_dl_function_pointer(void        *handle,
523                                 const char  *name,
524                                 bool         errors_are_fatal);
525 
526 
527 #endif /* defined(HAVE_DLOPEN) */
528 
529 /*----------------------------------------------------------------------------*/
530 /*!
531  * \brief Dump a stack trace to a file
532  *
533  * \param[in]  f         pointer to file in which to dump trace
534  * \param[in]  lv_start  start level in stack trace
535  */
536 /*----------------------------------------------------------------------------*/
537 
538 void
539 cs_base_backtrace_dump(FILE  *f,
540                        int    lv_start);
541 
542 /*----------------------------------------------------------------------------*/
543 /*!
544  * \brief Query run-time directory info, using working directory names.
545  *
546  * Returned names are allocated if non-NULL, so should be deallocated by
547  * the caller when no longer needed.
548  *
549  * Names are extracted from the working directory structure, which is expected
550  * to be of the form:
551  * <prefix>/study_name/case_name/RESU/run_id
552  *
553  * or, in the case o a coupled run:
554  * <prefix>/study_name/RESU_COUPLING/run_id/case_name
555  *
556  * If some names cannot be queried, NULL is returned.
557  *
558  * \param[out]  run_id      run_id, or NULL
559  * \param[out]  case_name   case name, or NULL
560  * \param[out]  study_name  study name, or NULL
561  */
562 /*----------------------------------------------------------------------------*/
563 
564 void
565 cs_base_get_run_identity(char  **run_id,
566                          char  **case_name,
567                          char  **study_name);
568 
569 /*----------------------------------------------------------------------------*/
570 
571 END_C_DECLS
572 
573 #endif /* __CS_BASE_H__ */
574