Professional Fortran code development: Log file creation

纵然是瞬间 提交于 2020-01-24 03:52:45

问题


I have developed a Fortran code which has the following characteristics:

  1. Global variables
  2. 13 Modules with multiple subroutines
  3. Independent subroutines
  4. Using Intel MKL library for LAPACK libraries (Linear Algebra)
  5. Reading and writing text files

The code has become quite big. Even though at this stage I am trying to get the correct answer, speed of execution of the code is desired.

I was writing a text log file with tags such as ERROR: message or INFO: message so far. But writing too much information slows down the code. I know in Java development we use log4j library to efficiently write log files where we can switch on or off various levels of logging. So once the code is clean, we can switch off low level logs and just keep the high level logs.

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


回答1:


The easiest way would be to create an integer variable verbose and read in its value at execution (from file or through command line). By doing this, you could create different levels:

  • verbose = 0 => no output
  • verbose = 1 => errors only
  • verbose >= 2 => errors & info

It'd be simple to implement:

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

and so on.




回答2:


I'm using the following preprocessor macros for exactly 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 then have the following header:

#define DEBUG
#include "MACROS.h"

...

dwrite 'An error occurred!'

This gives my the file and the line where the error occurred, and by commenting the first line I can easily switch the message on/off.

You could easily extend this to different debug levels and writing to files...




回答3:


I've seen people implement logging at the compiler level in a manner similar to Kyle Kanos's method with preprocessor directives. Not fortran standard, but I know it can be done with some fortran compilers.




回答4:


I've personally created a data type that contains a message (character array) and a procedure pointer that handles the message. It's not the most efficient system, but the message is written to via write(io%message, fmt_statement) fmt_variables, and then the procedure pointer is called, i.e. io%print(msgType, msgLog, message), for example 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've recently read of something called pFLogger. The GitHub page for the project is 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 seems very versatile at first glance. I haven't used it yet, but I'm definitely going to look into it!

Sorry for the severely delayed response! Hopefully this is still helpful to some!



来源:https://stackoverflow.com/questions/19523671/professional-fortran-code-development-log-file-creation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!