Notes on learning FORTRAN
I’ve been trying to understand the distributed block LU code written in ScaLAPACK, which is written in FORTRAN. In order to understand the algorithms properly I took a 30 min crash course in FORTRAN. In this blog post I’ll write some details about the language that are relevant to understanding the ScaLAPACK code.
Table of Contents
Learning resources
- Fortran tutorial on tutorialspoint.
- Fortran tutorial website.
- Functions and subroutines.
- Presentation on F90 basics.
- Fortran Arrays.
- Logical and comparison expressions.
Salient FORTRAN features
Here’s a simple addition program:
program addNumbers
! This simple program adds two numbers. This is a comment.
implicit none
! Type declarations
real :: a, b, result
! Executable statements
a = 12.0
b = 15.0
result = a + b
print *, 'The total is ', result
end program addNumbers
Each program begins with keyword program <prog_name>
and ends with end program <prog_name>
.
A statement implicit none
allows the compiler to check whether all variable types are declared correctly. This statement must be there to check if types have been declared correctly.
Program structure
A full program should be kept inside a program
statement. A simple ‘hello world!’ program
looks like so:
program hello
implicit none
print*,"Hello"
print*,"World!"
end program
Printing
Write to standard output using the print
statement.
Link: https://en.wikibooks.org/wiki/Fortran/Fortran_simple_input_and_output
Printing multi-dimensional arrays can be tricky since the print
statement by
default outputs newlines after each printing. Here’s a link that explains how
to print 2d arrays in fortran using write
:
Link: https://jblevins.org/log/array-write
If you want to use format specifiers with floating point numbers, read below link:
Link: https://pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap05/format.html
FORTRAN w.r.t ScaLAPACK
Subroutines and functions
I will now explain the pdgetrf
routine from ScaLAPACK.
The SUBROUTINE
keyword is used for defining subroutines. For example:
SUBROUTINE PDGETRF( M, N, A, IA, JA, DESCA, IPIV, INFO )
Types of arguments to subroutines are defined in the subroutine definition itself. For example, in scalapack:
* .. Scalar Arguments ..
INTEGER IA, INFO, JA, M, N
* ..
* .. Array Arguments ..
INTEGER DESCA( * ), IPIV( * )
DOUBLE PRECISION A( * )
Unlike in C, the argument types are not declared alongwith the name and argument list.
Functions and subroutines are different in FORTRAN. The main difference lies in the fact that functions can be used in an expression and can return only one value (exactly like functions in C or Java). A subroutine on the other hand, cannot be used in expressions, but has the advantage that it can be used for returning multiple values. In the respect of returning multiple values it is somewhat similar to MATLAB functions.
A subroutine ends with the RETURN
and END
statement. The arguements passed to a subroutine are similar to call by reference in the case of C. If you modify any value inside the subroutine, the value will be modified in the calling function too.
In order to tell the compiler the return value of a function, you must use the name of the function in an assignment statement that will tell the compiler the value to be returned. For example:
REAL FUNCTION AVRAGE(X,Y,Z)
REAL X,Y,Z,SUM
SUM = X + Y + Z
AVRAGE = SUM /3.0
RETURN
END
Arrays
Arrays are used/declared in a similar manner to C. For example, to declare an array:
INTEGER IDUM1( 1 ), IDUM2( 1 )
Array elements can be accessed using round brackets:
ICTXT = DESCA( 7 )
By default, arrays in fortran begin from index 1
.
One can also specify the kind
parameter in the array to tell the compiler which of its suppported
kinds it should use.
Multi-dimensional arrays are referenced in their indexing the same way as C arrays (row, col)
but
the internal storage is of course column major. See the second link below.
Link:
- https://stackoverflow.com/questions/838310/fortran-90-kind-parameter
- https://www.obliquity.com/computer/fortran/array.html
Logical and comparison expressions
Logical and comparison operators are written enclosed in dots. So &&
in C is
.AND.
in fortran. Similarly, !=
is .NE.
.
Loops
Fortran has a curious way of writing loops, given that I’m coming from the C world.
Loops are written using the do-continue
syntax. Each loop statement in a program
requires a statement label. Any label number can be used but the do
and continue
of a single block must have the same label.
The variable that is defined in the line of the do
block is the counter variable.
Its default step is 1
but you can change that as you want.
The general form is:
do label var = expr1, expr2, expr3
! statements
label continue
In the above loop, var
is the loop variable (this must be an integer). expr1
specifies the initial value of var
, expr2
is the terminating bound, and
expr3
is the increment (step).
Many Fortran 77 compilers allow do
-loops to be closed by the enddo
statement. The advantage of this is that the statement label can then be omitted
since it is assumed that an enddo
closes the nearest previous do statement.
The enddo
construct is widely used, but it is not a part of ANSI Fortran 77.