Fortran 90 documentation

Data types

For Fortran 90, ParameterWeaver supports the following data types:

  • integer
  • real
  • double precision
  • logical
  • character(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_type is defined as a structure with 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_type variable.
  • Parsing: the options passed to the program via the command line are assigned to the appropriate fields of the params_type variable. Moreover, the next variable of type integer will 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_type variable. 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.