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
- Salient FORTRAN features
- FORTRAN w.r.t ScaLAPACK
- 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>.
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.
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
Write to standard output using the
Printing multi-dimensional arrays can be tricky since the
If you want to use format specifiers with floating point numbers, read below link:
FORTRAN w.r.t ScaLAPACK
Subroutines and functions
I will now explain the
pdgetrf routine from ScaLAPACK.
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
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 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
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.
Logical and comparison expressions
Logical and comparison operators are written enclosed in dots. So
&& in C is
.AND. in fortran. Similarly,
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
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).
specifies the initial value of
expr2 is the terminating bound, and
expr3 is the increment (step).
Many Fortran 77 compilers allow
do-loops to be closed by the
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.
enddo construct is widely used, but it is not a part of ANSI Fortran 77.