Fortran 90 documentation
Data types
For Fortran 90, ParameterWeaver supports the following data types:
integerrealdouble precisionlogicalcharacter(len=1024)
Example Fortran 90 program
Suppose we want to pass command line parameters to the following Fortran program:
program main
use iso_fortran_env
implicit none
integer :: unit_nr = 8, i, istat
if (len(trim(out)) > 0) then
open(unit=unit_nr, file=trim(out), action="write")
else
unit_nr = output_unit
end if
if (verbose) then
write (unit_nr, "(A, I20)") "# n = ", n
write (unit_nr, "(A, F24.15)") "# alpha = ", alpha
write (unit_nr, "(A, '''', A, '''')") "# out = ", out
write (unit_nr, "(A, L)") "# verbose = ", verbose
end if
do i = 1, n
write (unit_nr, "(I3, F5.2)") i, i*alpha
end do
if (unit_nr /= output_unit) then
close(unit=unit_nr)
end if
stop
end program main
We would like to set the number of iterations n, the factor alpha, the
name of the file to write the output to out and the verbosity verbose
at runtime, i.e., without modifying the source code of this program.
Moreover, the code to print the values of the variables is error prone, if we later add or remove a parameter, this part of the code has to be updated as well.
Defining the command line parameters in a parameter definition file to automatlically generate the necessary code simplifies matters considerably.
Example parameter definition file
The following file defines four command line parameters named n, alpha,
out and verbose. They are to be interpreted as integer, double
precision, character(len=1024) pointer and logical respectively, and
if no values are passed via the command line, they will have the default
values 10, 0.19, output.txt and false respectively. Note that a
string default value is quoted. In this case, the columns in the file are
separated by tab characters. The following is the contents of the
parameter definition file param_defs.txt:
integer n 10
double precision alpha 0.19
character(len=1024) out 'output.txt'
logical verbose false
This parameter definition file can be created in a text editor such as the one used to write the Fortran program, or from a Microsoft Excel worksheet by saving the latter as a CSV file.
As mentioned above, logical values are also supported, however, the semantics is slightly different from other data types. The default value of a logical variable is always false, regardless of what is specified in the parameter definition file. As opposed to parameters of other types, a logical parameter acts like a flag, i.e., it is a command line options that doesn't take a value. Its absence is interpreted as false, its presence as true.
Generating code
Generating the code fragments is now very easy. If appropriate, load the module (thinking):
$ module load parameter-weaver
Next, we generate the code based on the parameter definition file:
$ weave -l Fortran -d param_defs.txt
A number of type declarations and functions are generated in the module
file cl_params.f90.
- data structure: a type
params_typeis defined as astructurewith the parameters as fields, e.g.,type :: params_type integer :: n double precision :: alpha character(len=1024) :: out logical :: verbose end type params_type - Initialization function: the default values of the command line
parameters are assigned to the fields of the
params_typevariable. - Parsing: the options passed to the program via the command line are
assigned to the appropriate fields of the
params_typevariable. Moreover, thenextvariable of typeintegerwill hold the index of the next command line parameter, i.e., the first of the remaining command line parameters that was not handled by the parsing function. - Dumper: a function is defined that takes three arguments: a unit number
for output, a prefix and the
params_typevariable. This function writes the values of the command line parameters to the output stream associated with the unit number, each on a separate line, preceeded by the specified prefix.
Using the code fragments
The module file is included by the use directive:
use cl_parser
A variable to hold the parameters has to be defined and its values initialized:
type(params_type) :: params
call init_cl(params)
Next, the command line parameters are parsed and their values assigned:
integer :: next
call parse_cl(params, next)
The dumper can be called whenever the user likes, e.g.,
call dump_cl(output_unit, "", params)
The code for the program is thus modified as follows:
program main
use cl_params
use iso_fortran_env
implicit none
type(params_type) :: params
integer :: unit_nr = 8, i, istat, next
call init_cl(params)
call parse_cl(params, next)
if (len(trim(params % out)) > 0) then
open(unit=unit_nr, file=trim(params % out), action="write")
else
unit_nr = output_unit
end if
if (params % verbose) then
call dump_cl(unit_nr, "# ", params)
end if
do i = 1, params % n
write (unit_nr, "(I3, F5.2)") i, i*params % alpha
end do
if (unit_nr /= output_unit) then
close(unit=unit_nr)
end if
stop
end program main
Note that in this example, additional command line parameters are simply
ignored. As mentioned before, they are available using the standard
get_command_argument function, starting from the value of the variable
next set by the call to parse_cl.
Using a configuration file
ParameterWeaver generates a function from the same parameter definition
file to parse a configuration file, in addition to command line parameters.
The format of the configuration file, e.g., config-03.txt is very
straightforward, as the example below illustrates.
alpha = 0.19
# comments can be added, as can blank lines
out = 'output-03.txt'
verbose = true
Comment lines start with a #, and are ignored, as are blank lines.
Parsing such a configuration file is now as simple as a single function call:
...
call parse_file_cl(params, 'config-03.txt')
...
Note that both command line parameters and configuration files can be used
in the same program, and that their priority is simply determined by the
order of calling parse_cl and file_parse_cl.