150
Introduction to Fortran Jon Johansson AICT HPC Workshop April 28, 2008

Introduction to Fortran Jon Johansson AICT HPC Workshop April 28, 2008

Embed Size (px)

Citation preview

Introduction to Fortran

Jon Johansson

AICT HPC Workshop

April 28, 2008

Downloads

• The talk and exercises are available from– http://sciviz.aict.ualberta.ca/Fortran/

Agenda

• Introduction, history

• Source format, gfortran

• Names, Program Structure, Variable Declaration

• Arrays

• Subprograms/Modules

Why Use Fortran?

• “The whole point of compilers, interpreters, layers of abstraction and what-not are to shorten the semantic distance between our intent and the way the computer thinks of things.”

• “… it often helps to have a language that makes expressing your intent very clear, concise, and above all, unambiguous.”– Scott Hansellman (computerzen.com)

Why Use Fortran?

• from the FORTRAN manual for the IBM 704 (1956), the goal of the FORTRAN creators was a language – “…closely resembling the ordinary language of

mathematics …”– “The result should be a considerable reduction

in the training required to program, as well as the time consumed in writing programs and eliminating their errors.”

Why Use Fortran?

• Fortran was designed from the outset (1954-1957) to do numerical computations– FORmula TRANslator

• again, from the IBM 704 (1956) FORTRAN manual:– “The FORTAN language is intended to be

capable of expressing any problem of numerical computation. In particular, it deals easily with problems containing large sets of formulae and many variables, …”

What is Fortran written in?

Compiler Maker Compiler name Source Code Language

GNU Compiler Collection g77, gfortran C

Portland Group pgf77, pgf90, pghpf C

Intel ifort C

SGI f77, f90 C

IBM f77, xlf, xlf90, xlf95 ?

Note: the point here is not that one language is “better” than the other. C is more suitable to doing operations that a compiler does, while Fortran is designed for numerical work – trying to write a compiler in Fortran would be hard. You can certainly do numerical work in C if you want to.

Fortran History

• Fortran is usually credited with being the first high-level programming language– the first language to use natural language

keywords•DO, REAL, INTEGER, …

– the first full language to be compiled• necessary because the computer can’t understand

the programming language

Fortran History

• John W. Backus and a group at IBM started to design the IBM Mathematical Formula Translating System, or Fortran0 in 1954

• the work was completed in 1957• the authors claimed that the

resulting code would be as efficient as handcrafted machine code– it was pretty close

Fortran History

• The IBM 704 Data Processing System was a large-scale computer designed for engineering and scientific calculations

• Fortran included many features that were specific to the IBM 704, the first computer on which it was implemented

http://www.fh-jena.de/~kleine/history/languages/FortranAutomaticCodingSystemForTheIBM704.pdf

Fortran History

• "The 704 is the first large-scale, commercially available computer to employ fully automatic floating point arithmetic commands. …”

• IBM 704 speed:– multiplies or divides in 240 microseconds

• approximately 4,000 operations per second

– floating point addition or subtraction operations require 84 microseconds

• approximately 12,000 operations per second

• 704 memory:– up to 32,768 36-bit words (32 kilo-words)

Fortran Standards

• Fortran was the first high level programming language to be standardized

• compiler vendors could create compilers that behaved in well defined and consistent ways

• programs are much more portable when they don’t depend on vendor specific features

Fortran Standards

Name Date Standard Definition

FORTRAN66 1966ANSI X3.9-1966 - the first standard for a

programming language

FORTRAN77 1977 ANSI X3.9-1978 and ISO 1539-1980

Fortran90 1991 ANSI X3.198-1992

Fortran95 Dec 1997 ISO/IEC 1539-1:1997

Fortran2003 Nov 2004 ISO/IEC 1539-1:2004

Fortran History

• Each new version of Fortran adds extensions to the language while retaining compatibility with previous versions

• For a long time Fortran was the dominant language of programming in scientific and engineering applications

• Now mostly used in High Performance Computing– lots of legacy codes being maintained and developed

Source Code Format

• originally Fortran source code was formatted according to rigid rules– different parts of statements had to fall in specific

column ranges• since Fortran 90/95 source code formatting is

free-form– allows arbitrary use of whitespace to format code

Free Form Source Code

• source file with one of the extensions:*.f90, *.f95, [*.hpf], [*.f03]

– files with extension in [] may be recognized by the compiler, but maybe not - it depends …

• a statement line can be up to 132 characters long

• ! indicates that the rest of the line is a comment – this can be anywhere

• & at the end of a line continues the line

Fixed Form Source Code

• source file with one of the extensions*.f, *.f77, [*.for]

• columns 1: ‘C’ or ‘*’ start a comment line• columns 1-5: reserved for statement labels• column 6: a character here is used to indicate

that a statement has been continued from the previous statement – can use any character except the number zero

• columns 7-72: Fortran statements go here• columns 73-80: characters past column 72 are

ignored

Fixed Form Source Code

• the fixed source format comes from the design of the 704 and the need to use 80 column punch cards

• the Hollerith card format:– cards have 12 rows and 80 columns – decimal digits are encoded in rows 0-9 – other characters are encoded using these rows plus rows 11-12 above

row 0

Fortran Alphabet

• Letters– A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

– upper and lower case letters are equivalent

• Digits– 0 1 2 3 4 5 6 7 8 9

• Special Characters– space ' " ( ) * + - / : = _ ! & $ ; < > % ? , . [ ] { } ~ ` | # ^ @

Fortran Features

• lots of built-in mathematical functions

• array operations– operations on array sections– use vector indices

• array indices can start and end on arbitrary values

• complex numbers as a fundamental data type– complex arithmetic as well, of course

The GNU Fortran Compiler

• part of the GNU compiler collection

• documentation online at– http://gcc.gnu.org/onlinedocs/gfortran/

• under development since 2000

• still a work in progress

• supports most of Fortran 77, 90, 95 and some of 2003

The GNU Fortran Compiler

• invoke the compiler with a command of the form

gfortran [options] input-file• many of the options are common to gcc with

some Fortran specific ones• for example, to compile a program contained in

a file named “MyCalc.f90”

gfortran –o MyCalc MyCalc.f90• the ‘–o’ option tells the compiler the name to

give the executable

The GNU Fortran Compiler

• some useful compiler options-O capital ‘Oh’– optimize the executable

-On n is an integer from 1 to 3– the compiler tries to reduce code size and execution time

-fbounds-check– check array subscripts against the declared minimum

and maximum values

-fopenmp– enable the OpenMP extensions

The GNU Fortran Compiler

• more useful compiler options

-Ldir– add directory dir to the list of directories to be searched

for libraries listed with -l

-llibrary-name– search the library named library when linking

-Idir– Add the directory dir to the head of the list of directories

to be searched for header files

Fortran Program Structure

• a basic Fortran program looks like this

• this is called the “main program unit”

• other program units start with the keywords: FUNCTION or SUBROUTINE

[program] MyProg

declarations

processing and I/O

end [program MyProg]

[ ] denote optional portions.

The program name can be included in the end statement only of the program statement is used.

Activity 1

• using a text editor, type the program into a file named “hello.f90”

• compile the programgfortran hello.f90

• run the program ./a.out

program HelloWorld

implicit none

! Declare variables

! Do work

print *, 'Hello World!'

end program HelloWorld

Input/Output

• to print something to the computer displayWrite(*, "(a)") ‘This is a string‘

• the ‘a’ is the format specifier for a string

• the format string must be inside'(…)' or "(…)"

Input/Output

• Fortran programs transfer data to and from external devices during their runs

• each device is associated with a Unit Number– the number is often in the range 1 to 99– the number cannot be negative

Input/Output

• to associate an external file with a unit use the OPEN() statement– OPEN(20, FILE=‘output.txt’)– OPEN(21, FILE=‘output.txt’, STATUS = 'NEW' )

– OPEN(22, FILE=‘output.txt’, STATUS = 'NEW‘, ERR = 100, IOSTAT = ErrNum)

Input/Output

Open(20, File='outfile.txt', &

Status='New')

Do i = 1, N

If ( i .NE. TestVal(i) ) Then

Write(20, "(I15)") i

End If

End Do

Close(20)

Input/Output

• Fortran has one function for data input and two for data output

• Input: – READ() - transfers input data from external

sequential, direct-access, or internal records

• Output– PRINT() - displays output on the screen

• on some systems TYPE is a synonym for PRINT

– WRITE() - transfers output data to external sequential, direct-access, or internal records

Input/Output

• The general format of READ and WRITE is– READ(clist) list ! clist == control list– WRITE(clist) list

• where the required parts of clist for both READ and WRITE are– [UNIT=] unit-number– [FMT=] format-spec

• and other arguments are optional.! note * refers to default settings READ(*, *) x, yWRITE(*, *) x, y

– the first asterisk refers to the default unit number and– the second is the list directed i/o format specifier

Format Specifier

• There are 3 ways to give a format specifier:

• 1) as an asterisk (*)– the is called list-directed i/o– the format is defined by the computer system

at the moment the statement is executed

Write(*,*) 'Product = ', x*y

Format Specifier

• 2) as a statement label referring to a FORMAT statement containing the specifier between parentheses– this is the Fortran 77 way to do it

Write(*, 100) x*y

100 Format('Product = ', f8.2)

Format Specifier

• 3) as a character expression whose value commences with a format specification in parentheses– this is what we do in the sample programs

Write(*,’(a,f8.2)’) &

'Product = ', x*y

Read(*,’(2f8.2)’) x, y

Edit Descriptors

• the format specification uses a set of descriptors – here are some common ones

• ‘A’ – character string– A20 – the field width is 20 characters

• ‘I’ – integers– I9 – integer field is 9 digits wide

• ‘F’ – floating point numbers– F9.3 – real field is 9 spaces wide with 3 digits to the right of the

decimal point

• ‘E’ – real values with exponents– E12.3E2 – real field is 12 spaces wide with 3 digits to the right

of the decimal point and 2 digits in the exponent field

Fortran Variable Types

• Fortran has five intrinsic variable types– INTEGER: a string of digits with an optional sign

• 0, 314, -4502

– REAL: decimal or exponential representation • 3.1416 or 3.1416E0• DOUBLE PRECISION gives a double length real

– COMPLEX: real and imaginary parts of type real• (1.23, -5.56)

– LOGICAL: 1 to 4 bytes but only 2 values• .FALSE. or .TRUE.

– CHARACTER: characters enclosed in “” or ‘’• ‘One string’ “Another string”

Variables

• variables can be declared using the appropriate data type statement:

INTEGER i, j, k

REAL radius(100), theta, phi

COMPLEX SphericalHarm

LOGICAL MoreData

CHARACTER(Len=80) TestString

Activity 2• using a text editor, type the program shown

in exercise 2 into a file named “io.f90”• compile the program

gfortran io.f90

• run the program./a.out

• modify the program to write the product of x and y (the multiplication operator is ‘*’)

Variables

• Fortran 90 defines a new syntax for declaring variables. The general form is:

TYPE [,attr] :: variable list

• where attr is a list of optional Fortran 90 attributes to further define the properties of variables

• variables can have attributes such as– PARAMETER, SAVE, ALLOCATABLE

Variables

• other attributes:– PARAMETER– PUBLIC– PRIVATE– TARGET– POINTER– INTENT– OPTIONAL

• the double colon (::) is optional unless ATTRIBUTES or an initialization expression are given

• a real 2-d array to allocate laterreal, allocatable :: x(:,:)

• an integer whose value is retained for the next function callint, save :: i

Error Conditions

• it is good practice to handle error conditions gracefully if possible

• if the program fails with a cryptic error message you’ll have to search to figure it out

Error Conditions

• some functions have the following specifiers:– IOSTAT– ERR

• for example, the OPEN statement• OPEN(22, FILE=‘output.txt’, STATUS = 'NEW‘, ERR = 100, IOSTAT = ErrNum)

Error Conditions

• IOSTAT is an integer variable:= 0 if no error occurs

> 0 (the number of the error message) if an error occurs

< 0 if an end-of-file record is encountered

• ERR is a label to transfer control to if an error condition occurs

• OPEN(22, FILE=‘output.txt’, STATUS = 'NEW‘, ERR = 100, IOSTAT = ErrNum)

Activity 3• using a text editor, make changes to your

program from activity 2 as shown in exercise 3 into a file named “io_test.f90”

• compile the programgfortran io_test.f90

• run the program./a.out

Variable Representation

• variables are basically pointers to some part of memory– the number of bytes is part of the declaration of the

variable ( default sizes are frequently 4 bytes)

Variables

• DOUBLE PRECISION values have precision greater than the real values on the machine

• to declare double precision real and complex variables use:

DOUBLE PRECISION theta, phi

DOUBLE COMPLEX SphericalHarm• note that DOUBLE COMPLEX isn’t in the standard• might have to use Kinds to get Double Complex

Integer Representation

• integers in Fortran are signed• INTEGER lengths can be 1, 2, 4, or 8 bytes• the default INTEGER length is 4 bytes

# of Bytes Min Value Max Value

1 -128 127

2 -32,768 32,767

4 -2,147,483,648 2,147,483,647

8 -9,223,372,036,854,775,808 9,223,372,036,854,775,807

Floating Point Representation

• there are ANSI/IEEE standards to define how floating point numbers are represented and behave in a computer

• IEEE Standard 754-1985– defines binary floating point arithmetic

• IEEE Standard 854-1987– defines decimal floating point arithmetic

Floating Point Representation

• given a certain number of bytes allocated to a floating point number, how do we use the bytes to represent the sign, fractional part and the exponent?

• for a 4-byte REAL– 8 bits are for the (signed) exponent– 24 bits are for the (signed) mantissa

Floating Point Representation

• Span and Precision of IEEE 754 Floating-Point Formats

Format # of Bytes

Approximate Absolute Nonzero

Minimum

Approximate Absolute

Maximum

Approximate Precision (decimal digits)

Single 4 1.2E-38 3.4E+38 6 – 9

Double 8 2.2D-308 1.8D+308 15 – 17

Extended Double

≥ 10 ≤ 3.4D-4932 ≥ 1.2D+4932 ≥ 18 – 21

Quadruple 16 3.4Q-4932 1.2Q+4932 33 – 36

Floating Point Representation

• processors generally support single and double precision operations in hardware

• quadruple precision can be implemented in software– quadruple precision is not required by the

Fortran standard but is an extension in many compilers

– this can be slow

Floating Point Representation

• want to run our program on different machines using the same number of significant digits

• if we declare the variables as REAL the length is not certain

• use KINDS

Machine/Data Type Real Double Precision

IBM (SP) 6 15

Cray (T90) 15 33

Cray (T3E) 15  15

Fortran Names

• a name (identifier) must obey the following rules in Fortran 90/95– it can have up to 31 characters– the first character is a letter– remaining characters can be letters, digits or

the underscore– case of letters does not matter

•range, Range, rAnGe all point to the same memory location

Implicit Typing

• Fortran permits real and integer variables to be typed and declared implicitly without their being defined by declaration statements

• by default the types are given by the first letter of the variable name– integer: [i-n]– real: [a-h] and [o-z]

• this has been found to be poor programming practice …

Implicit Typing

• Fortran 90 allows us to disable implicit typing with the statement

IMPLICIT NONE• at the start of the program, function and

subroutine

• this helps reduce errors due to simple spelling mistakes

User-Defined Types

• Fortran 90 introduced user-defined types with the TYPE statement

• these are derived from intrinsic data types• a TYPE definition is required to define

– the name of the type, and – the names and types of its components

• a derived type is resolved into components that are either of intrinsic type or are pointers

User Defined Types

• define a type point • define a point origin

• assign values to the components– to reference the values

inside a point, use the % operator

TYPE point

real :: x, y, z

END TYPE point

TYPE(point) :: origin

origin%x = 0.0

origin%y = 0.0

origin%z = 0.0

Arithmetic Operators

• the basic mathematical operators in Fortran are shown in the table

• precedence order is:()

**

*, /

+, -

Math Fortran + +

- -

x *

÷ /

exponentiation **

parentheses ()

a+x*5/y**2-3*sin(z)**3

= a + ((x*5)/(y**2)) - (3*(sin(z)**3))

Activity 4• using a text editor, create a file “circle.f90”

and write a program which prompts you to input a radius from the terminal and then calculates the circumference and area of the circle

• compile and run the programgfortran circle.f90./a.out

Fortran Program Structure

• every Fortran program must have one and only one main program– The keyword

PROGRAM is optional– it can be followed by

the program name– END is required as the

last statement of the program

PROGRAM [name][specification statements][executable statements]...

END [PROGRAM [name]]

Specification Statements

• specification statements define the environment for the executable statements

IMPLICIT NONEINTEGER :: i, j, k

• type declaration statements integerrealcomplexcharacterlogicaltype(type-name)

Executable Statements

• the executable statements specify the actions that are to be performed– assignment operator– arithmetic operators– relational operators– loops– conditional branching– array operations

Relational Operators

• Fortran 90 includes alternative forms for the relational operators defined in FORTRAN 77

FORTRAN 77 Fortran 90

.LT. <

.LE. <=

.EQ. ==

.NE. /=

.GT. >

.GE. >= if (x < y) then

r = sqrt(y**2 – x**2)

end if

Intrinsic Mathematical Functions

• Fortran provides many intrinsic mathematical functions

• all trigonometric functions take arguments in radians

• the functions are defined only for floating point arguments, not integers– sqrt(4) causes ‘4’ to be converted to

floating point and the return value is a REAL

Intrinsic Mathematical Functions

• the generic names of the mathematical functions are given below– COS, ACOS– SIN, ASIN– TAN, ATAN, ATAN2– EXP, LOG, LOG10– COSH, SINH, TANH– SQRT

Flow Control

• Fortran includes a number of constructs to control the program flow– DO: controls the repeated execution of a

block of statements or constructs – IF: conditionally executes one statement

based on the value of a logical expression – CASE: conditionally executes one block of

constructs or statements depending on the value of a scalar expression

DO Construct

• controls the repeated execution of a block of statements or constructs

• this construct is called a loop

DO i=1, nstep, stepsize

block

END DO• nstep is the maximum value that the loop

variable will take• stepsize is the increment for the loop variable

DO Construct

• print the odd integers starting from 1 and less than 100

DO i=1, 100, 2 WRITE (*, "(a,I4)") 'I = ',i END DO

• I = 1• I = 3• …• I = 99

Implied DO Loop

• the implied DO loop is a shorthand notation useful for the following:– specify iteration of part of an I/O list – initialize an array– transfer part of an array – transfer array items in a sequence different

from the order of subscript progression

• cuts back on the number of lines of code required

Implied DO Loop

• in a data transfer statement, an implied-DO list acts as though it were a part of an I/O statement within a DO loop. It takes the following form:

(list, do-var = expr1, expr2 [,expr3])• list

– a list of variables, expressions, or constants

• do-var– the name of a scalar integer or real variable

– the variable must not be one of the input items in list

• expr– scalar numeric expressions of type integer or real. They do not all have

to be the same type, or the same type as the DO variable.

Implied DO Loop

• print the odd integers starting from 1 and less than 100

WRITE (*, 100) (i, i=1, 100, 2)100 Format(‘I = ’, I4)

> I = 1> I = 3> …> I = 99

• the implied DO can be nested

WRITE (6,150) ((FORM(K,L), L=1,10), K=1,10,2)

DO WHILE Construct

• execute the range of a DO construct while a specified condition remains true

i = 99DO WHILE (i>0) WRITE (*, "(a,I4)") 'I = ',i i = i - 2END DO

• I = 99• I = 97• …• I = 1

IF Construct

• conditionally executes one block of statements depending on the evaluation of a logical expression

IF (expr) THEN block

[ELSE IF (expr) THENblock] ...

[ELSEblock]

END IF• expr is a logical expression

Logical Operators• construct logical expressions with these operators

if ( (x<y) .AND. (y<z)) then

r = sqrt(y**2 – x**2)

end if

Operator Example Meaning.AND. a .AND. b expression is true if both a and b are true

.OR. a . OR. b expression is true if either a, b, or both, are true

.EQV. a . EQV. b expression is true if both a and b are true, or both are false

.NEQV. a . NEQV. b expression is true if either a or b is true, but false if both are true

.NOT. .NOT. b expression is true if b is false and false if b is true

IF Construct

• test values of x and deal with special ranges

IF ( x > 15.0 ) THEN

Call DealWithBigX(x)

ELSE IF ( x <= 0.0 ) THEN

Call DealWithLittleX(x)

ELSE

Call DealWithMediumX(x)

END IF

IF Statement

• when there is a single expression to evaluate

IF ( x + y < 4.0 ) &

z = sqrt( x**2 + y**2 )• a single statement

• no need to use THEN and END IF

SELECT CASE Construct

• conditionally executes one block of constructs or statements depending on the value of a scalar expression in a SELECT CASE statement

SELECT CASE (expr)[CASE (case-value)

block] ...[CASE DEFAULT

block]END SELECT

• expr scalar expression of type integer, logical, or character (enclosed in parentheses).

SELECT CASE Construct

SELECT CASE (i)CASE(1:3) ! Values: 1, 2, 3 …CASE(4) ! Values: 4 …CASE(5, 7, 9) ! Values: 5, 7, 9 …CASE(10:) ! Values: ≥10 …CASE DEFAULT ! Values: all others …

END SELECT

Command Line Arguments

• the Fortran 2003 standard defines some functions for dealing with command line arguments:

• GET_COMMAND()– Retrieve the entire command line that was used to invoke the

program.

• COMMAND_ARGUMENT_COUNT()– Returns the number of arguments passed on the command line

when the containing program was invoked.

• GET_COMMAND_ARGUMENT() – Retrieve the Nth argument that was passed on the command

line when the containing program was invoked.

Command Line Arguments

• one way to process the command line:– get the whole command line into a text buffer

• you might want to test the status of the get_command() function

– get the number of command arguments• check that things are still reasonable

Activity 5• either start from your program from activity

4, “circle.f90” or download files to start with from my web server, and modify your program to use a command line parameter as a radius, if there is one

• compile and run the programgfortran cir_cmdline.f90./a.out

Arrays

• much of numerical work requires manipulation of arrays– so Fortran provides lots of tools for arrays

• arrays can be declared by using: – a type declaration statement– DIMENSION– ALLOCATABLE– TARGET– or, POINTER or COMMON

Arrays

• for exampleREAL MyArr(-1:29, 15:36)

• defines a 2 dimensional array whose– first index takes on values [-1, 29]– second index takes on values [15, 36]

• the above is equivalent to using:REAL MyArr

Dimension MyArr(-1:29, 15:36)

Array Terminology

• an array declared like this

REAL :: X( 2, 5, -1:8 )• has:

– rank of 3 ! # of dimensions– extents of 2, 5, and 10! # in each dim– a shape of (/ 2, 5, 10 /)! vector of extents– a size of 100 ! # of values in array

• the shape of matrix A is a vector with rank(A) elements

Array Terminology• arrays declared like this

REAL :: X( 4:5, -1:8 )

REAL :: Y( 2, 10 )• have the same shape

– same rank and same extent in each dim

• they are said to be conformable • since the shapes are the same we can do

X = Sqrt(Y + 1.0)

→ X(4,-1) = Sqrt(Y(1,1) + 1.0)

Activity• given arrays declared as follows

REAL :: X( 4:5, -1:8 )

REAL :: Y( 2, 10 ), Z(10)

• which of these expressions are valid?

X = Y; Z = Y(:,5) – 3.0

Y = Z + 1.0; Y(3,:) = Z

X(4,:) = Z;X(5,:) = Z+Y(2,:)

Arrays

• Fortran stores higher dimensional arrays as a contiguous sequence of elements

• it is important to know that 2-dimensional arrays are stored by column – referred to as column-

major order– C uses row-major order

Fortran: elements stored in order -

[a11 a21 a31 a21 a22 a32 a13 a23 a33 ]

C: elements stored in order -

[a11 a12 a13 a21 a22 a23 a31 a32 a33 ]

Arrays

• the fact that the array elements are stored contiguously is part of the Fortran standard:

• this is from ISO/IEC 1539 : 1991 (E) section 14.6.3.1, item (6)– A nonpointer array of intrinsic type or sequence

derived type occupies a sequence of contiguous storage sequences, one for each array element, in array element order (6.2.2.2)

• in ISO/IEC 1539-1:2004(E) this is found in section 16.4.3.1, item (7)

Arrays

• why do we care about the array elements being in contiguous memory locations?– this is what allows us to count on

optimizations which access array elements in column orderdo j = 1, ny do i = 1, nx y(i, j) = DoSomething( y(i,j) ) end doend do

Activity 6• do calculations using the planetary data

• note: you DO NOT need to use do loops for this exercise

• compile and run the programgfortran planets.f90./a.out

Allocatable Arrays

• the bounds (and shape) of an allocatable array are determined when it is allocated

• allocatable arrays are given storage on the heap– Fortran also has Automatic Arrays– automatic arrays are allocated upon entry to

the defining subprogram and deallocated on return

– automatic arrays are allocated on the stack

Allocatable Arrays

• it is useful to be able to allocate and deallocate arrays as the program runs

REAL, Allocatable :: MyArr(:,:)• this declares a 2 dimensional array but no

memory is actually allocated• to allocate use

Allocate( MyArr(12,5:15) )– first dimension goes from 1 to 12– second dimension goes from 5 to 15

• release the memory with Deallocate( MyArr )

Allocatable Arrays

• the intrinsic function ALLOCATED() can be used to determine whether an allocatable array is currently allocated:

REAL, ALLOCATABLE :: E(:,:)

...

IF(.NOT.ALLOCATED(E)) ALLOCATE(E(2:4,7))

Allocatable Arrays

• recall that the Fortran standard specifies that arrays be allocated in a contiguous block of memory

• what happens if the memory is fragmented?

• want to allocate a 2 GB array• Fortran can’t do it!• test the allocation for an error

Allocatable Arrays

! Try to allocate 2.0 GB

real, allocatable :: x(:)

integer :: err

allocate(x(2.0GB),STAT=err)

if(err /= 0) stop

deallocate(x)

Array Expressions

• can write expressions containing arrays without explicitly writing do loops

Real x(10,10), y(10,10), z(10,10)

z = -x + 1.0 ! z(i,j) = - x(i,j) + 1.0

z = x * y ! z(i,j) = x(i,j) * y(i,j)

z = x / y ! z(i,j) = x(i,j) / y(i,j)

z = Sin( x ) ! z(i,j) = Sin( x(i,j) )

• the above requires arrays of the same shape

Array Functions

• many of Fortran’s intrinsic functions take arrays as arguments

• classify the functions as– elemental – operate on array elements

• get an array back of the same dimensions•y = SIN(x) ! sine of each element of x

– transformational• get a number or array of a different shape back•z = SUM(A) ! sums elements of A

Vector Multiplication

• vector multiplication:

DOT_PRODUCT(vector_a, vector_b)

• makes a scalar product of two vectors– must have the same length (same number of

elements)

• note that if VECTOR_A is of type COMPLEX the result is

SUM(CONJG(vector_a)*vector_b)

Matrix Multiplication

• matrix multiplication:

MATMUL(MATRIX_A, MATRIX_B)

• makes the matrix product of two matrices– must be consistent, i.e. have dimensions like

(M, K) and (K, N) – at least one of the matrices must be of rank 2

Array Sections

• an array section is a portion of the array

• we can address subsections of arrays using:– a subscript triplet

• [first-bound] : [last-bound] [:stride]

– a vector subscript• a one-dimensional array of integer values (within

the declared bounds for the dimension) that selects a section of a parent array

Array Sections

• define an array with 4 rows and 5 columns

Real x(1:4,1:5)

• x(1,1) is in the upper left corner

Array Sections

• the subscript triplet is used as followsReal x(10,10), y(10,10), z(3,5)

z = x(2:4,2:10:2) + y(1:5:2,1:9:2)

• the array sections of x and y are both the same size as z

• note that the correspondence is by position in the extent, not by subscript value– the order of scalar operations isn’t specified in the

Fortran standard to the compiler can arrange optimizations

Array Constructor

• an array constructor can be used to create and assign values to rank-one arrays (and array constants)

• the array constructor is denoted by:

(/ ... /) • the ellipsis is a list of values assigned to

the array elements and is created by expressions or implied do loops

Array Constructor

• use a list of numbers to give values to an array

Integer i ! Loop variableReal :: x(4)x = (/ 3, 6, 9, 12 /)write(*,"(4F6.1)") x

• gives the output 3.0 6.0 9.0 12.0

Array Constructor

• use an implied DO loop to give values to an array

Integer i ! Loop variableReal :: x(4)x = (/ (i, i=1, 4) /)write(*,"(4F6.1)") x

• gives the output 1.0 2.0 3.0 4.0

Array Constructor

• use the RESHAPE intrinsic function to change the shape of the array

• the second argument is the shape of the new array

• INTEGER :: :: list(2,3)• INTEGER :: x(6)• x = (/ 11,12,21,22,31,32 /)• list(2,3) = RESHAPE(x, (/2,3/))

Activity 7• use the RESHAPE() function

• compile and run the programgfortran shape.f90./a.out

• use at least one allocatable array to hold the results in this exercise

Masked Array Assignments

• Fortran includes two constructs for masked array assignments– WHERE : applies a logical test to an array on

an element-by-element basis • this is in Fortran 90

– FORALL : a generalization of WHERE• it allows more general array shapes to be assigned• this is in Fortran 95

Masked Array Assignments• a WHERE statement• initialize arrays A, B

and C• note that all elements

of C = -1 to start• for only the elements

of A that are not 0, do the calculation

• get the elements of C: -1, 11, 12, 13, -1

INTEGER A, B, C

DIMENSION A(5), & B(5), C(5)

DATA A /0,1,1,1,0/

DATA B & /10,11,12,13,14/

C = -1

WHERE(A .NE. 0) &

C = B / A

Masked Array Assignments• a WHERE construct• find the indices in the pressure array where the expression is true– do things to arrays with

those indices

• use the indices for which the condition is false to do other things

DIMENSION pressure(1000), temp(1000), precipitation(1000)

WHERE(pressure .GE. 1.0)

pressure = pressure+1.0

temp = temp - 10.0

ELSEWHERE

precipitation = .true.

ENDWHERE

Array Inquiry Functions

• we would like to be able to query an array to find out:– is it allocated?– how many elements are in the array?– the shape of the array– the lower and upper bounds

• Fortran 90 includes intrinsic functions for this

• useful when passing arrays to functions

Array Inquiry Functions

• ALLOCATED(ARR) – a logical function which indicates if the array is

allocated

• SIZE(ARR, dim)– returns the number of elements in ARR, if DIM is

not given, and the number of elements in the relevant dimension if DIM is included

• SHAPE(ARR)– returns the shape of an array ARR as an integer

vector

Array Inquiry Functions

• LBOUND(ARR, dim) – returns the lower dimension limit for ARR– if DIM (the dimension) is not given as an

argument, you get an integer vector, if DIM is included, you get the integer value with exactly that lower dimension limit, for which you asked

• UBOUND(ARR, dim) – similar to LBOUND which returns the upper

dimensional limits

Subprograms

• subprograms make programs more modular

• a subprogram solves a specific problem

• a subprogram is available for use anywhere in the program

• Fortran has two subprogram types–SUBROUTINES–FUNCTIONS

Subroutines

• a subroutine does not return any value and is the same as a void function in C/C++

• in Fortran all arguments are passed as the address of the variable in the calling program– referred to as call by reference in C/C++

• subroutines allow us to return any number of values through the arguments

Subroutines

! Calculate the spherical-polar radius! from 3 Cartesian coordinates and! return the radiusSUBROUTINE radius(x, y, z, r) Real, INTENT(IN) :: x, y, z Real, INTENT(OUT) :: r r = sqrt( x**2 + y**2 + z**2 )END SUBROUTINE radius

• INTENT(IN) and INTENT(OUT) prevent accidental changes of the variables in the calling program by generating an error at compile time

Functions

• a Fortran function takes a set of arguments

• it returns a value of some type

• the function type must be declared in the calling program

• functions end by using the end or return statements

Functions

• a Fortran function always return a value just like corresponding functions in C/C++! Calculate the spherical-polar radius! from 3 Cartesian coordinates and! return the radiusFUNCTION radius(x,y,z) RESULT(r) Real, INTENT(IN) :: x, y, z Real :: r r = Sqrt( x**2 + y**2 + z**2 )END FUNCTION radius

• note that the type of the variable in the RESULT statement is the type of the function

Arrays as Arguments

• the simple thing to do is make sure that the arrays have the same type and dimensions in the calling program and the subprogram

• get fancy with– explicit-shape arrays (Fortran 77)

A(3,4) and B(0:*)

– deferred-shape arrays (Fortran 90)C(:.:)

Modules

• a container, inside of which, different variables and subprogram units can be defined

• the variables and subprograms can then be made available to different program units through the USE statement– USE gives a program unit accessibility to public

entities in a module

• essentially a place to clump global data– an alternative to COMMON blocks– can do object oriented programming with modules

Modules

• use modules to package specifications and definitions

• a module can contain internal subprograms

• modules don’t contain executable code above the CONTAINS statement– modules are not

executable

MODULE name

[specification-part]

CONTAINS

module-subprogram

[module-subprogram] ...]

END [MODULE [name]]

Activity 8• working with a module which contains

data, the Pauli spin matrices

• compile and run the program as in the handout

Timing Code

• you can manually add functions to your program to time sections as it runs

• CPU Time – amount of time it takes for the CPU to execute a set of instructions – the system keeps track of how much time the

CPU is working on your program

• Wall Time – amount of time, according to a clock on the wall, that it takes the cpu to execute the instructions

CPU Time

• Fortran 95 added a functioncpu_time()

• which returns a processor-dependent approximation of the processor time in seconds real :: start_time, finish_timecall cpu_time(start_time) … stuff to time …call cpu_time(finish_time)write(*, "(a,f8.1,a)") & ' Stuff completed in ', & finish_time - start_time, ' cpu seconds'

Wall Time• Fortran 90 added a function

system_clock()• this function returns integer data from a real-time clock

integer :: start_wall_time, finish_wall_timeinteger :: ticks_per_seccall system_clock(start_wall_time, ticks_per_sec) … stuff to time …call system_clock(finish_wall_time)write(*, "(a,f8.1,a)") ‘Stuff completed in ', & real(finish_wall_time - start_wall_time) & & / real(ticks_per_sec), & ' wall seconds‘

• Beware: the returned value can be reset to 0 if the count passes through the maximum integer on the system

Profiling

• given that your program works correctly you may want to make it run faster/more efficiently

• a profiler allows you to find the places where your program spends its time so you reduce that time– focus your efforts where it will do the most

good

• GNU provides ‘gprof’ for profiling

Profiling

• ‘gprof’ produces an execution profile of your program

• the file ‘gmon.out’ contains the call graph profile

• ‘gprof’ outputs:– flat profile: shows how much time your program spent

in each function and how many times that function was called

– call graph: shows, for each function, which functions called it, which other functions it called, and how many times

Profiling

• add the option ‘–pg’ to the compile line• execute the program normally

– get a file named ‘gmon.out’

• run the command ‘gprof’• for example:

gfortran -pg –o MyCalc MyCalc.f90

./MyCalc

gprof -l -b MyCalc gmon.prof

OpenMP

• OpenMP• introduce statements into your code

– in FORTRAN: !$OMP– in C: #pragma

• can compile serial and parallel executables from the same source code

• restricted to shared memory machines– not clusters!

• www.openmp.org

OpenMP

• make the program parallel incrementally– one loop at a time if that works for you

• the pi calculation example contains 4 lines around the main loop to make it parallel

• before the loop:!$ Call OMP_SET_NUM_THREADS(3) !$OMP Parallel!$OMP Do Reduction(+:sum) Private(x, f)

• after the loop!$OMP End Parallel

OpenMP

• the number of threads that OpenMP uses can be controlled by:– using the OpenMP function from the serial

part of the program

!$ Call OMP_SET_NUM_THREADS(3) – setting the environment variable (in BASH)

export OMP_NUM_THREADS=3– using the NUM_THREADS clause

Calculation - OpenMP

• speedup graph for 1 to 4 processors

• quad precision• Opteron 285

procs• runs for 107

steps and 109 steps

Some Online Resources

• The gfortran Wiki– http://gcc.gnu.org/wiki/GFortran

• Michael Metcalf's article on Fortran language features in Wikipedia– http://en.wikipedia.org/wiki/

Fortran_language_features

• King’s College Fortran pages– http://www.kcl.ac.uk/kis/support/cit/fortran/

Fortran

• there’s lots left to learn

• see your favourite compiler manual

• contact [email protected] for numerical help

Appendix 1 - KINDs

• rather than declaring variables of a specific length with constructs like

DOUBLE PRECISIONREAL*n

• Fortran now use KINDS• this is intended to provide true portability

for code• tell the compiler what range and precision

of values you need for the variable

Appendix 1 - KINDs

• the ‘KIND number’ is an integer that specifies the length of the variable

• one common practice is to use the length of the variable in bytes as the KIND number

• the NAG Fortran compiler uses the digits 1, 2, and 3 for the KIND numbers

• G77 3.4.6 uses prime numbers for KINDs

Appendix 1 - KINDs

KIND(X) • returns the kind of the actual argument

– X can be of type INTEGER, REAL, COMPLEX, LOGICAL or CHARACTER

• the argument X does not have to be assigned any value

KIND(3) ! IntegerKIND(12.0) ! RealKIND(1.6D6) ! Double

Appendix 1 - KINDs

SELECTED_INT_KIND(R) – returns an integer kind with the requested number of

digits – R must be scalar integer

• the result of SELECTED_INT_KIND is an integer from zero and upward– if the desired kind is not available you will get -1– if several implemented types satisfy the condition, the

one with the least decimal range is used– if there still are several types or kinds that satisfy the

condition, the one with the smallest kind number will be used

Appendix 1 - KINDs

• SELECTED_REAL_KIND(p, r) • returns the kind for floating-point numbers

with numerical precision at least P digits and one decimal exponent range between -R and +R– the parameters P and R must be scalar

integers– at least one of P and R must be given.

Appendix 1 - KINDs• the result of SELECTED_REAL_KIND is

also an integer from zero and upward– if the desired kind is not available,

• -1 is returned if the precision is not available• -2 if the exponent range is not available• -3 if no one of the requirements are available

– if several implemented types satisfy the condition, the one with the least decimal precision is returned, and if there are several of them, the one with the least kind number is returned

Activity

• The exercises are available from– http://sciviz.aict.ualberta.ca/Fortran/src/

• or– http://www.ualberta.ca/AICT/RESEARCH/

Courses/2007/Workshop/_05_IntroToFortran/src/

• KIND values

• Download the program TestKinds.f90

Fortran Program Structure

• a Fortran program consists of one or more program units.

• a program unit is usually a sequence of statements that define the data environment and the steps necessary to perform calculations– it is terminated by an END statement

• a program unit can be either a main program, an external subprogram, a module, or a block data program unit

• an executable program contains one main program, and, optionally, any number of the other kinds of program units

Fortran Program Structure

• every Fortran program must have one and only one main program– The keyword

PROGRAM is optional– it can be followed by

the program name– END is required as the

last statement of the program

PROGRAM [name][specification statements][executable statements]...

END [PROGRAM [name]]

Fortran Program Structure

• Fortran programs, functions and subroutines have the same basic structure

• functions and subroutines can be– External - self contained (not necessarily

Fortran)– Internal - inside a program unit– Module - member of a module

• Fortran 77 has only external procedures

Fortran Program Structure

• functions and subroutines have the form

FUNCTION [name] (Arg-list) [specification statements]

[executable statements]...

END [FUNCTION [name]]

SUBROUTINE [name] (Arg-list) [specification statements]

[executable statements]...

END [SUBROUTINE [name]]

Fortran Program Structure

• the ordering rules for statements

• these apply to all program units and subprograms

• vertical lines delineate varieties of statements that may be interspersed

• horizontal lines delineate varieties of statements that must not be interspersed.

• USE statements, if any, must appear immediately after the program unit heading

Fortran Program Structure

• internal or module subprograms must follow a CONTAINS statement

• between USE and CONTAINS statements in a subprogram, non-executable statements generally precede executable statements– the FORMAT statement,

DATA statement, and ENTRY statement may appear among the executable statements

• this session considers programs structured as shown in pink

GOTO

• Fortran has a GOTO statement

• when coupled with line labels it’s possible to transfer control to any point in a program in a completely unreadable way

• it is generally considered bad practice to make use of the GOTO statement– there are always alternatives

Exercise

• download the file

ColVsRowOrder.f90• this program creates a large array and then

accesses the elements in column and row order• read the program to and see the difference in

the way the array elements are accessed• compile and run the program• how different are the times for access?