I would like to run a fortran 77 program multiple times with different set of input parameters; I already made sure that output file names change for different input parameters I use, but I am not sure how I can run a program with different set of input parameters without having to go to the code each time to change the parameters.
To illustrate my question, here is a simple code.
PROGRAM CODE
IMPLICIT DOUBLE PRECISION (A-H, J-Z)
COMMON / param / radius
radius = 2
write(*,*) 'radius = ', radius
write(*,*) 'the area is = ', 3.14*radius*radius
END
Say I want to run this code with different radiuses, and instead of having to go into the code and manually change the value, I want to have a file with different parameter choices and have it run multiple times.
Of course, there is a solution to this by creating an array of different parameter choices and looping. However, I do not want to do this, since I actually have multiple parameters I want to change for each run.
In response to one of the comments below, if I have a file with different input choices for each run, how do I have the program grab different rows for different parameter choices for each run?
In the cases I've had to run a parametric analysis on codes which expect to operate on a single set of parameters, I've written a small script in Python using the Jinja2 template library to generate a large number of input files. I choose a naming convention that allows me to easily determine which input file corresponds to which input permutation to assist in post-processing the results. The specific use of Python & Jinja2 isn't as important as having a text template outside the input generation script so you can make adjustments to the generated files without editing the input generator. There are plenty of mature, simple web templating systems which can efficiently generate input text files.
The cross-reference between input parameters and file name may be as simple as an index into an array of data structures (i.e. a hash or dict). I try to use something more meaningful and to add descriptive comments to the generated input (assuming the input format allows comments...)
In my case, I may be using code that I can't recompile without going though a month-long QA cycle so it's much cheaper for me to write the parametric variation code as a separate script than to integrate it into my Fortran code.
The other reason I tend to write the parametric analysis code in Python is because it's much easier than writing complex input processing in Fortran. Being able to use
numpy
to generate linear, logarithmic, or other variation patterns (e.g. Chebyshev nodes) is so much easier than trying to do it in Fortran.Standard disclaimer: my operating environment and use cases are probably very different than yours so this technique may not be appropriate. I'm just pointing out that it is an option with several advantages, depending on your environment.
If you change to code, you need to recompile.
I don't know how complex your program is, usually it's best to write the program in such a way that it reads the values in, either from the user interface or from a file.
Check CHECK_COMMAND_ARGUMENT or Namelists for ideas how to do that.
But if you want to go down the path to recompile it every time, you can use the preprocessor to set certain parts of the code.
See this example code:
To use the preprocessor, you either have to explicitly tell your compiler to do it (
gfortran -cpp
orifort -fpp
for example), or you can change the extension to capital.F
(or.F90
for modern Fortran) which enables the preprocessor by default.There is a "pedestrian"-type approach that I have used many times.
To avoid recompilation, a solution is to hardcode the name of the parameter file and to read the data from this file. Every run of the code must have its own copy of the parameters and so its own directory.
I give below an example for a single parameter but you can generalize it if needed. It relies on a driver script in bash.
Fortran program:
bash program:
Compile the Fortran code:
and execute the parametric run as:
What the Fortran code does: Open the file named
parameters.txt
and read the first entry for the value of radius.What the bash script does: For a number of values of the parameter, create a new directory, create a file named
parameters.txt
in that directory then execute the Fortran programcode
in that directory.Comments:
This can be extended to several variables, either one per line or several per line in
parameters.txt
, using a second loop in the bash program.If you can use a more modern version of Fortran, please mention it. There are more options there.
Other languages (Python, as arclight suggests, or others) can be used for scripting. Many computing clusters use bash to run jobs, so that might be used for parametric runs (the value of radius could be passed via the job queuing system then).
I used 11 arbitrarily for the file unit number. Your actual situation requires to use an available unit number for your program indeed.
the command line argument approach
note for ancient compilers you should used
iargc
andgetarg
instead. The purists will note these are non standard f77, however they are commonly available in many compilers.typical python script to loop over a list of arguments:
of course you should use whatever script language you are comfortable with. I like a "high level" language since I inevitably seem to end up doing calculations in the script.