As a serial compiler for the SPMD programs in our distributed applications
I use the lf95 compiler, placed in
~hpf/LF95. Documentation in PDF format
is in the subdirectory docs. A few
must-know things are given below.
First of all, FORTRAN 77 files should have the extension .f,
Fortran 90/95 files .f90. They can
both be in fixed form, but the Fortran 90 can be free form. The important
compilation switches are:
| Switch |
Purpose |
| -c |
Compile only-for modules and subroutines |
| --dbl, --long, --quad |
Extend reals to double (*8) or quad (*16) precision and
integers to long (*8) |
| --[n]f95, --[n]fix |
Fortran 95 conformance and fixed/free input source form |
| -I<dir>, -L<dir>,
-M<dir> |
Path for include (modules and source) files, for libraries
(.a and shared .so)
libraries, and the directory for placing modules .mod
in. |
| -l, -o |
Specify library to include and specify output file |
| -O0, -O |
No optimization or full optimization |
| --n[info], --[n]warn,
--[n]wo |
Do/don't give infos, warnings and obsolescent features
messages. |
| --shared, --staticlink |
Make a shared library (no -c) or statically link the
file (along with the Lahey runtime library). |
| --tp, --tpp |
Optimize code for Pentium (MMX) or Pentium Pro (II, III,
Celeron...) architectures. |
The commonly used options suitable for gauss are placed in the environmental
variable RM346 (for compilation of
the final codes), or rm346 for
compiling the testing intermediates. Both are defined in ~/.HPF.
Thus a typical invocation would be,
lf95
$rm346 other_options -o $HPF_exe/executable.exe objects.o -l<library>
when compiling during development stages, and
lf95
$RM346 other_options -o $HPF_EXE/executable.exe objects.o -l<library>
for final compilation of working codes.
Another important thing is using modules and shared libraries.
The compiler creates a module file with the extension .mod for each
module it encounters. These should be placed in the $HPF_MODULES
or $HPF_modules directories. These
files should then be in the include path whenever compiling a program that
USE's the modules. The compiler also makes an object file for the module
containing the module procedures and such. This file must be linked
when compiling programs that use the module. For example,
lf95
$rm346 -c module.f -o $HPF_link/module.o
and then
lf95
$rm346 program.f $HPF_link/module.o
Shared libraries are also easy to use and should always be used if
the executable is to remain on gauss.
To make portable objects, use the --nshared
and --staticlink switches. Shared libraries
are linked just like regular libraries. For example, if you have a library
module you want to compile, use (note: there is no -c):
lf95
$rm346 --shared module.f -o $HPF_lib/libmodule.so
and then:
lf95
$rm346 program.f -L$HPF_lib -lmodule
Note that libraries start with lib
and have a suffix .a for static and
.so for shared (dynamic) libraries.
Debugging is an important thing for many people, but I usually write programs
from scratch and debug them step by step. I will look into some debugging
tools when time allows.
Fortran 90 CGI script module
Since we use CGI
(Common Gateway Interface) programs in our computational
physics education, I downloaded a very nice CGI_UTILS
Fortran 90 module, which is based on the ISO_VARYING_STRING
module. Both modules are compiled and ready to use. Here is an example
Fortran 90 program
using these modules, and a webpage
that invokes it.
Compilation is done with the command:
lf95
$RM346 $HPF_CGI -o $HPF_EXE/cgi_example.exe cgi_example.f90
where,
HPF_CGI
= "--staticlink -I$HPF_MODULES $HPF_LINK/iso_vst.o $HPF_LINK/cgi.o"
and the other environmental variables/shortcuts are discussed elsewhere.
Note that --staticlink is neccessary
because the web-server serves the cgi-script on linux106
and not on gauss (where the shared
libraries are). There is a corresponding lower-case variable HPF_cgi
that uses all shared objects when linking, but until we have a web-server
on gauss this will not be useful.
DISLIN
high-level graphics library
Take a look at the documentation
for the DISLIN library for more information on its capabilities. For the
purpose of this webpage, it is enough to say that this is a high-level
scientific plotting library that is very widely used and free for Linux
Fortran systems. I have not installed a low-level Fortran graphics library,
like the very popular OpenGL library,
but if we need it, that can be arranged.
I have made my own set of routines for scientific 2D and 3D line, surface
and color plotting, based on the familiar MATLAB plotting commands. Take
a look at the source
file with the Fortran 90 module to see exactly what I did. The module
provides several routines:
-
InitGraphics(file,file_type,plot_title,x_label,y_label,z_label,my_func)
which must be called to initialize the graphical routines.
It takes all optional arguments with the file name, the file type (most
often one of "POST" or "PSCL"
for PostScript, "TIFF" for tiff images,
and "CONS" or "XWIN"
for the whole screen or an X window), the plot title and axis labels, and
an external function my_func which
accepts an integer from -1 to 3 and performs operations of level 0-3 that
are not provided by my module. The plot title should be a string of characters
(one string for each line that you need), while the other names are simple
strings. Note that this is most easly done using array constructors, as
in plot_title=(/"Line 1","Line 2"/).
-
EndGraphics(my_func)
which closes the graphics routines and accepts the user-defined
external function. don't forget to call this routine at the end. NOTE:
To close the DISLIN X window with the plot, click the left or middle
mouse button.
-
AddLegend(legends,pos)
which adds a legend to the plot. It takes the array of
strings legends and optionally the
position of the legend (3 and 7 are most used--upper right corner of page
and plot) as argumens.
-
Plot2D(x1,y1,spec1,...,my_func,axis_limits)
which accepts up to 10 sets of x
and y data points as vectors,
an optional three-character specification string which determines the curve
attributes, the external user-defined function, and an optional vector
axis_limits with four entries that
defines the axis limits. The specification string has the following interpretation:
-
The first character should be one of 'S'
(plot data points as symbols), or 'L'
(plot data points connected with a line-no symbols).
-
The second character for symbol ('S')
plots should be on of 'S' (use squares
as symbols), 'C' (circles), 'T'
(triangles), 'D' (diamonds), or lower-case
letters ('s' 'c' 't' 'd') for the corresponding
filled symbols. For line ('L') plots,
this character should be one of '-'
(solid line), '.' (dotted), ':'
(dashed) or '|' (dashed-dotted).
-
The third character determines the color of the curve and
should be one of 'R' (red), 'B'
(blue), 'G' (green) or 'Y'
(yellow).
-
Plot3D(x1,y1,z1,spec1,...,my_func,axis_limits)
with the same syntax as Plot2D,
but for plotting curves in 3D.
-
Plot2DMatrix(x,y,type_spec,line_spec,color_spec,my_func,axis_limits)
Plots several 2D curves contained as columns in
the matrices x and y.
There are three optional specification strings that specify whether the
corresponding column should be plotted as a line or as symbols, the type
of the symbol/line, and the color respectively. The length of these strings
should be equal to the number of columns to plot and the interpretation
of the symbols is the same as in Plot2D.
This function is added to overcome the limitation of 10 curves in Plot2D
(which is there because Fortran 90 does not support variable argument lists)
and to enable faster and more flexible plotting of similar data curves.
-
Plot3DMatrix(x,y,z,type_spec,line_spec,color_spec,my_func,axis_limits,view)
with the same syntax as Plot2DMatrix,
but for plotting curves in 3D.
-
SurfPlot(x,y,z,spec,my_func,color_range,axis,view)
which accepts a set of points as vectors, an optional
three-character string specification, a user-defined external function,
and optional 2/3 element arrays specifying the axis ranges / view angle.
The specification string has the following interpretation:
-
The first character should be one of '2'
(plot data points as a 2D color plot), or '3'
(plot data points as a 3D surface).
-
The second character for color ('2')
plots should be a digit from 1-9 and specify the increase in the resolution
(number of linear-interpolation interior-points). For surface ('3')
plots, this character should be one of 'M'
(mesh line surface), 'C' (color-shaded
surface) or 'S' (both mesh and color
shading).
-
The third character determines the color palette and should
be one of 'R' or 'r'
(rainbow palette in two different directions of hot-cold), 'G'
or 'g' (gray palette in two different
directions) or 'V' (VGA 16 color palette).
For examples on how to use these routines, take a look at the curve-plotting
sample file, which also plots a legend using the external function
argument my_func. Or, even better,
the same example but with the matrix
plotting routines and with the AddLegend
routine (for the output, see the 2D
and 3D
line plots). Also take a look at the surface-plotting
sample file (for the output, see the 2D
color or 3D
surface plots). The programs are compiled with, for example,
lf95
$RM346 -o $HPF_EXE/test.exe test.f90 $HPF_DISLIN
where
HPF_DISLIN
= "-I$HPF_MODULES $HPF_LINK/graphics.so $HPF_LINK/dislin.so -lDISLIN"
is, as usuall, defined in .HPF.
Please copy all your graphics images to $HPF_GRAPHS.
If you want to make readily portable executables, you need to link the
static libraries, which is done by simply replacing the shortcut HPF_DISLIN
with the lowercase lettered:
HPF_dislin
= "--staticlink -I$HPF_MODULES $HPF_LINK/graphics.o $HPF_LINK/dislin.o
-ldislin -L/usr/X11R6/lib -lX11"
NOTE: The executables made this way will be huge, so use this option
only if needed.
The Basic Linear Algebra Subprograms
are extremely efficient routines for doing things like matrix multiplication
or triangular linear equation solving. I have downloaded both a shared
(libBLAS.so) and statically linked
(libblas.a) Pentium II library, and
compiled a Fortran
95 module-binding for the BLAS. The documentation
for this binding and the BLAS
in general is available at Netlib in various forms and documents.
For examples on how these are used, take a look at a simple file that
times matrix
multiplication for several different approaches. The results are as
expected. A naive Fortran 77 approach of nested DO loops with most compilers
takes about 7 seconds for 500 by 500 double precision matrices, the intrinsic
MATMUL takes less (about 3-5 seconds), but the BLAS routine gemm
takes only a second or so. Using the BLAS for local computations can often
save you orders of magnitude in time!
Physicists often use sparse matrices, and this BLAS supports only banded
sparse matrices (the sparse BLAS is not yet finalized even as a proposal).
Here is an example
program that calculates the lowest energy eigenvector and eigenvalue
for a simple harmonic quantum oscillator and plots
the eigenvector (it should be a gaussian). The Hamiltonian matrix is
banded (tri-diagonal), and the power method that uses BLAS's sbmv
is used. The compilation is done via:
lf95
$RM346 --info -o $HPF_EXE/mmul.exe mmul_timing.f90 $HPF_DISLIN $HPF_BLAS
where
HPF_BLAS = "-I$HPF_MODULES/BLAS
$HPF_LINK/blas.so -lBLAS"
There is, of course, a static library lower-case variation:
HPF_blas = "--staticlink
-I$HPF_MODULES/BLAS $HPF_LINK/blas.o -lblas"
but this makes huge executables, of the order of 3MB.
LAPACK 90 Library
LAPACK (Linear Algebra Package) is a very well-known and developed linear
algebra package developed at the very productive group at the University
of Tennessee. I have installed the latest version, 3.0, along with its
Fortran 90 binding. A description
of the routines can be found at netlib.
For an example of how to use the library, here is the same example
described in the BLAS section, which finds the lowest
few energy eigenstates of an anharmonic QHO. I had some trouble with accuracy
in my "hand" implementation which uses the BLAS and a simple power method,
but LAPACK does not have such problems and gives very nice results with
about the same speed. The text
output of the file shows this well, and here is a graphical
result showing how the lowest energy of the QHO depends on the anharmonic
perturbation.
The compilation is done via the shortcut $HPF_LAPACK,
which links shared LAPACK and BLAS with static LAPACK90 libraries (I had
lot's of trouble making a shared LAPACK90 library...) and thus makes small
executables (the corresponding lower-case static analog should not be used
as the executables are more than 10 MB):
lf95
$RM346 -o $HPF_EXE/b_QHO.exe b_QHO.f90 $HPF_DISLIN $HPF_LAPACK
where
HPF_LAPACK
= "-I$HPF_MODULES -lBLAS -lLAPACK -llapack90"
The distributed-memory implementation ScaLAPACK will be installed
too, along with many other similar MPI-based packages.
NOTE: More serial libraries are coming soon, and now you get
the gist of how I set up the system. For now though, I am turning my attention
to MPI and Adaptor.