Fortran Professional Code Development: Creating a Log File

I developed Fortran code that has the following characteristics:

  • Global variables
  • 13 Modules with multiple routines
  • Independent routines
  • Using Intel MKL Library for LAPACK Libraries (Linear Algebra)
  • Reading and writing text files

The code has become quite large. Although at this point I am trying to get the right answer, code execution speed is required.

I wrote a text log file with tags like ERROR: message or INFO: message . But writing too much information slows down the code. I know that in Java development, we use the log4j library to write log files efficiently, where we can turn different levels of logging on or off. Therefore, when the code is clean, we can turn off low-level logs and simply save high-level logs.

I would like to know from other programmers that the best way to handle this is in Fortran 90+.

+6
source share
4 answers

The easiest way is to create an integer variable verbose and read its value at runtime (from a file or through the command line). By doing this, you can create different levels:

  • verbose = 0 => no output
  • verbose = 1 => only errors
  • verbose> = 2 => errors and information

This would be simple to implement:

 IF(verbose >= 1) CALL OutputError(message) IF(verbose >= 2) CALL OutputInfo(message) 

etc.

+2
source

I use the following preprocessor macros for this task (inside MACROS.h ):

 #ifdef DEBUG #define DWRITE write(*,*) __FILE__,__LINE__, #define dwrite write(*,*) __FILE__,__LINE__, #else #define DWRITE ! #define dwrite ! #endif 

In my code, I have the following header:

 #define DEBUG #include "MACROS.h" ... dwrite 'An error occurred!' 

This gives me the file and the line where the error occurred, and by commenting on the first line, I can easily enable or disable the message.

You can easily expand it to different levels of debugging and writing to files ...

+2
source

I have seen people implement compiler-level logging in a manner similar to the Kyle Canos method with preprocessor instructions. Not a fortran standard, but I know that this can be done with some fortran compilers.

0
source

I personally created a data type that contains message (an array of characters) and a procedure pointer that processes the message. This is not the most efficient system, but the message is written using write(io%message, fmt_statement) fmt_variables , and then the procedure pointer is called, i.e. io%print(msgType, msgLog, message) , e.g. io%print(error, debug, io%message) .

 type, private :: badLogger character(128), private :: message = "" ! Note here that IO is an abstract interface elsewhere ! and that defaultPrint is some printing procedure that ! matches the IO interface procedure(IO), private, pointer :: print => defaultPrint end type badLogger ! Usage: type(badLogger) :: io write(io%message, *) "I love pizza!" call io%print(comment, fun, io%message) 

I recently read about what is called pFLogger . GitHub page for the project: https://github.com/Goddard-Fortran-Ecosystem/pFlogger/blob/master (see https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20170011091 .pdf , https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20170011458.pdf ), which at first glance seems very universal. I haven't used it yet, but I'm definitely going to learn it!

Sorry for the very delayed reply! Hope this is still useful for some!

0
source

Source: https://habr.com/ru/post/956496/


All Articles