Dynamic String Generation and C++-style Output in Fortran

Marcus Mohr
2024-09-05
Abstract:Using standard components of modern Fortran we present a technique to dynamically generate strings with as little coding overhead as possible on the application side. Additionally we demonstrate how this can be extended to allow for output generation with a C++ stream-like look and feel.
Programming Languages
What problem does this paper attempt to address?
The problem that this paper attempts to solve is: in modern Fortran, how to dynamically generate strings with as little coding overhead as possible and achieve a function similar to C++ stream - style output. Specifically, the paper focuses on the generation and formatting of log messages in scientific computing code. ### Problem Background In scientific simulation code, in addition to performing large - scale input - output (I/O) operations to read input data sets and store the final simulation results, it is usually necessary to generate log messages to inform users of various details about the simulation run. These log messages may include: - Echoing control parameters - The current time - step value - The progress of the iterative solver, etc. These log messages are usually sent to the screen/terminal or a dedicated log file, or even both. As the scale of the project increases, the following aspects become particularly important: - **Uniform log format**: Ensure that all log messages have the same format. - **Different log levels**: Allow users or developers to select different log levels (such as debug, info, warning, etc.). - **Indentation or marking**: Indicate which program component generated the log message through different indentation or marking methods. - **Flexible message destinations**: Be able to switch the destination of log messages (terminal, file, or both). In addition, in MPI parallel applications, usually only a specific MPI process (such as rank 0) will generate log messages, so it is necessary to check the rank of the MPI process being executed when generating log messages. ### Solution To reduce code duplication and simplify the generation of log messages, the author proposes a technique based on modern Fortran standard components, which can: 1. **Dynamically generate strings**: Use Fortran's string concatenation operator `//` and deferred - length strings, combined with function overloading and optional parameters, to achieve the conversion of non - character types (such as integers, floating - point numbers, logical values, etc.) to strings. 2. **C++ - style stream - style output**: Overload Fortran's string concatenation operator `//` to make the string generation process more concise, similar to the C++ stream - style output syntax. ### Specific Implementation The paper proposes a two - level conceptual framework: - **First level: Stringification** Use a function named `v2s()` to convert non - character - type values to strings. For example: ```fortran call log_write('iteration count = ' // v2s(iter)) call log_write('eps = ' // v2s(eps, 'F8.2')) call log_write('flag use_petsc is ' // v2s(.true., "switch")) ``` - **Second level: Stream - style output** Overload Fortran's string concatenation operator `//` to make string generation more concise, similar to C++ stream - style output: ```fortran call log_write("Residual after " // it_count // " iterations is " // res_norm) ``` ### Extended Functions The paper also introduces several extended functions, such as multi - line messages, I/O operations of arrays, and the handling of user - defined structure types. In addition, C++ - like I/O manipulators are introduced to control the formatted output of data items. ### Summary This paper aims to provide an efficient and flexible method to reduce the complexity and code volume of log message generation in scientific computing code while maintaining good readability and maintainability. By combining the standard features of modern Fortran, a function similar to C++ stream - style output is achieved, thereby improving the maintainability and flexibility of the code.