Вы находитесь на странице: 1из 38

Outline

History of Fortran
Variables and their assignment
Control structures

Getting started with Fortran

1 2

Why to learn Fortran? Short history of Fortran

Well suited for numerical computations John W. Backus et al (1954): The IBM Mathematical
Likely over 50% of scientific applications are written in Formula Translating System
Fortran Early years development: Fortran II (1958), Fortran IV
Fast code (compilers can optimize well) (1961), Fortran 66 & Basic Fortran (1966)
Handy array data types Fortran 77 (1978)
Fortran 90 (1991) a major revision and Fortran 95 (1997)
Clarity of code
a minor revision to it
Portability of code
Optimized numerical libraries available

3 4
Short history of Fortran cont. Look and feel
PROGRAM square_root_example
Fortran 2003 (2004): a major revision, adding e.g. object- ! Comments start with an exclamation point.
oriented features, C-bindings ! You will find data type declarations, couple arithmetic operations
! and an interface that will ask a value for these computations.
Fortran 95/2003 is the current de facto standard IMPLICIT NONE
REAL :: x, y
The latest standard is Fortran 2008 (2010): a more minor INTRINSIC SQRT ! Fortran standard provides many commonly used functions

upgrade compared to F03 ! Command line interface. Ask a number and read it in
WRITE (*,*) 'Give a value (number) for x:'
Most notable addition: Fortran coarray (CAF) syntax READ (*,*) x

Compiler support nearly complete y = x**2+1 ! Power function and addition arithmetic

Cray: feature complete WRITE (*,*) 'given value for x:', x


WRITE (*,*) 'computed value of x**2 + 1:', y
Intel and GNU: most important features (except CAF) ! Print the square root of the argument y to screen
WRITE (*,*) 'computed value of SQRT(x**2 + 1):', SQRT(y)
END PROGRAM square_root_example

5 6

Compiling and linking Variables


Variables must be declared at the
source code IMPLICIT NONE
beginning of the program or
(.f, .F, .f90, .F90) procedure
INTEGER :: n0
INCLUDE The intrinsic data types in Fortran are
files compiler output REAL :: a, b INTEGER, REAL, COMPLEX,
compiler REAL :: r1=0.0
(optional) CHARACTER and LOGICAL
modules
object code COMPLEX :: c
They can also be given a value at
COMPLEX :: imag_number=(0.1, 1.0)
(.o, .so) declaration (not recommended)
CHARACTER(LEN=80) :: place
libraries linker output CHARACTER(LEN=80) :: name='James Bond' Constants defined with the
linker
(.a, .so) (optional) PARAMETER clause they cannot be
LOGICAL :: test0 = .TRUE. altered after their declaration
LOGICAL :: test1 = .FALSE.
executable
REAL, PARAMETER :: pi=3.14159
7 8
Assignment statements Operators
Arithmetic operators
PROGRAM numbers REAL :: x,y
IMPLICIT NONE Automatic change of representation, INTEGER :: i = 10
INTEGER :: i works between all numeric intrinsic x = 2.0**(-i) !power function and negation precedence: first
REAL :: r data types x = x*REAL(i) !multiplication and type change precedence: second
COMPLEX :: c, cc x = x/2.0 !division precedence: second
i = 7 i = i+1 !addition precedence: third
i = i-1 !subtraction precedence: third
r = 1.618034
c = 2.7182818 !same as c = CMPLX(2.7182818) Relational operators
< or .LT. !less than
cc = r*(1,1)
<= or .LE. !less than or equal to
CMPLX(r) == or .EQ. !equal to
How can I convert numbers to
WRITE (*,*) i, r, c, cc /= or .NE. !not equal to
character strings and vice versa? See
END PROGRAM > or .GT. !greater than
INTERNAL I/O in the File I/O lecture.
>= or .GE. !greater than or equal to
Logical operators
Output (one integer, real and two complex values) : .NOT. !logical negation precedence: first
7 1.618034 (2.718282, 0.000000) (1.618034, 1.618034) .AND. !logical conjunction precedence: second
.OR. !logical inclusive disjunction precedence: third

9 10

Arrays Control structures: IF conditionals


PROGRAM test_if
INTEGER, PARAMETER :: M = 100, N = 500
IMPLICIT NONE
INTEGER :: idx(M)
By default, indexing starts from 1 REAL :: x, y, eps, t
REAL :: vector(0:N-1)
REAL :: matrix(M, N)
WRITE(*,*) Give x and y :
CHARACTER (len = 80) :: screen ( 24)
READ(*,*) x, y
eps = EPSILON(x)
! or
IF (ABS(x) > eps) THEN
t = y/x
INTEGER, DIMENSION(1:M) :: idx
ELSE
REAL, DIMENSION(0:N-1) :: vector
WRITE(*,*)division by zero
REAL, DIMENSION(M, N) :: matrix
t = 0.0
CHARACTER(len=80), dimension(24) :: screen
END IF
WRITE(*,*) y/x = , t
END PROGRAM

11 12
Control structures: DO loops Control structures: DO loops
INTEGER :: i, stepsize, NumberOfPoints REAL :: x, totalsum, eps
INTEGER, PARAMETER :: max_points=100000 totalsum = 0.0
REAL :: x_coodinate(max_points), x, totalsum
! DO loop without loop control
! DO loop with an integer counter (count controlled) DO
stepsize = 2 READ(*,*) x
DO i = 1, NumberOfPoints, stepsize IF (x < 0) THEN
x_coordinate(i) = i*stepsize*0.05
END DO EXIT ! exit the loop
! Condition controlled loop (DO WHILE) ELSE IF (x > upperlimit) THEN
totalsum = 0.0 CYCLE ! do not execute any further statements but
READ(*,*) x ! cycle back to the beginning of the loop
DO WHILE (x > 0) END IF
totalsum = totalsum + x totalsum = totalsum + x
READ(*,*) x END DO
END DO

13 14

Control structures: SELECT CASE Control structures: example 1


PROGRAM gcd
... SELECT CASE statements ! Computes the greatest common divisor, Euclidean algorithm
INTEGER :: i
IMPLICIT NONE
LOGICAL :: is_prime, matches the entries of a INTEGER :: m, n, t
test_prime_number list against the case index WRITE(*,*) Give positive integers m and n :
...
READ(*,*) m, n
SELECT CASE (i) Only one found match is WRITE(*,*)m:, m, n:, n
CASE (2,3,5,7) Labels can be given to
allowed positive_check: IF (m > 0 .AND. n > 0) THEN
is_prime = .TRUE.
main_algorithm: DO WHILE (n /= 0) control structures and used
CASE (1,4,6,8:10) Usually arguments are t = MOD(m,n) in conjunction with e.g. exit
is_prime = .FALSE.
CASE DEFAULT
character strings or m = n and cycle statements
n = t
is_prime=test_prime_number(i) integers
END DO main_algorithm
END SELECT
...
DEFAULT branch if no WRITE(*,*) Greatest common divisor: ,m
ELSE
match found WRITE(*,*) Negative value entered
END IF positive_check
END PROGRAM gcd
15 16
Control structures: example 2 Source code remarks
2
PROGRAM placetest
IMPLICIT NONE A variable name can be no longer than 31 characters
1
LOGICAL :: in_square1, in_square2 (containing only letters, digits or underscore, must start with a
REAL :: x, y
WRITE(*,*) Give point coordinates x and y letter)
READ (*,*) x, y
in_square1 = (x >= 0. .AND. x <= 2. .AND. y >= 0. .AND. y <= 2.)
Maximum row length is 132 characters
in_square2 = (x >= 1. .AND. x <= 3. .AND. y >= 1. .AND. y <= 3.) There can be max 39 continuation lines
IF (in_square1 .AND. in_square2) THEN ! inside both
WRITE(*,*) Point within both squares if a line is ended with ampersand (&), the line continues onto the next
ELSE IF (in_square1) THEN ! inside square 1 only line.
WRITE(*,*) Point inside square 1
ELSE IF (in_square2) THEN ! inside square 2 only No distinction between lower and uppercase characters
WRITE(*,*) Point inside square 2 Character strings are case sensitive
ELSE ! both are .FALSE.
WRITE(*,*) Point outside both squares Semicolon (;) as a separator between statements on a single
END IF
END PROGRAM placetest
line
17 18

Summary

Fortran 95/2003 despite its long history is a modern


programming language targeting especially scientific
computing
Versatile, quite easy to learn, powerful
In our first encounter, we discussed
Variables & data types
Control structures: loops and conditionals
Operators

19
Outline

Structured programming
Modules
Procedures: functions and subroutines
Interfaces
Procedure arguments

Procedures and modules

20 21

Structured programming Modular programming

Structured programming based on program sub-units Modularity means dividing a program into minimally
(functions, subroutines and modules) enables dependent modules
Testing and debugging separately Enables division of the program into smaller self-contained
Re-use of code units
Improved readability Fortran modules enable
Re-occurring tasks Global definitions of procedures, variables and constants
Compilation-time error checking
The key to success is in well defined data structures and
scoping, which lead to clean procedure interfaces Hiding implementation details
Grouping routines and data structures
Defining generic procedures and custom operators
22 23
What are procedures? Procedure declarations

With procedures we mean subroutines and functions Subroutine Function


Subroutines exchange data through its argument lists Declaration: Declaration:
CALL mySubroutine(arg1, arg2, arg3)
SUBROUTINE sub(arg1, arg2,...) [TYPE] FUNCTION func(arg1,
Functions return a value arg2,...) [RESULT(val)]
[declarations]
value = myFunction(arg1, arg2) [statements] [declarations]
[statements]
Both can also interact with the rest of the program END SUBROUTINE sub
through module (global) variables END FUNCTION func

Call convention: Call convention:


CALL sub(arg1, arg2,...) res = func(arg1, arg2,...)

24 25

Procedure declarations: example Procedure arguments


SUBROUTINE dist(x, y, d) REAL FUNCTION dist(x, y) Fortran passes call arguments by reference:
IMPLICIT NONE IMPLICIT NONE
REAL :: x, y, d REAL :: x, y Means that only the memory addresses of the arguments
d = SQRT(x**2 + y**2) dist = SQRT(x**2 + y**2)
END SUBROUTINE dist END FUNCTION dist
are passed to the called procedure
Any change to argument changes the actual argument
PROGRAM do_something PROGRAM do_something
... ... Compiler can check the argument types only if the
call dist(x, y, r) r = dist(x, y)
... ...
interface is explicit, i.e. compiler has information about the
called procedure at compile time.
The INTENT keyword increases readability and enables
better compile-time error checking

26 27
INTENT keyword Procedure types
SUBROUTINE foo(x, y, z) Declares how formal argument There are four procedure types in Fortran 90: intrinsic,
IMPLICIT NONE
is intended to be used for external, internal and module procedures
REAL, INTENT(IN) :: x
REAL, INTENT(INOUT) :: y transferring a value
REAL, INTENT(OUT) :: z IN: the value of the Procedure types differ in
x = 10 ! Compilation error
argument is read/only ie. Scoping, i.e. what data and other procedures a procedure
y = 10 ! Correct cannot be changed can access
z = y * x ! Correct OUT: the value of the
END SUBROUTINE foo
argument must be provided
Interface type, explicit or implicit
INOUT (the default) Compiler can check the argument types of the at compile
Compiler uses INTENT for error time only if the interface is explicit
checking and optimization

28 29

Procedure types Module procedures and variables


Procedures defined in
modules can be referred
The interfaces of the intrinsic, internal and module Declaration Usage to in any other program
procedures are explicit MODULE check PROGRAM testprog
unit with the USE clause
IMPLICIT NONE USE check
The interfaces of the external procedures, such as many INTEGER, PARAMETER :: & IMPLICIT NONE
library subroutines, are implicit. You can write an explicit longint = SELECTED_INT_KIND(8) INTEGER(KIND=longint) :: x,test
CONTAINS test = check_this(x)
interface to those, though. FUNCTION check_this(x) RESULT(z) END PROGRAM testprog
INTEGER(longint):: x, z
Intrinsic procedures are the procedures defined by the ... A good habit
USE check, ONLY: longint
programming language itself, such as INTRINSIC SIN END FUNCTION
END MODULE check

Module procedures are


declared after the CONTAINS
statement

30 31
Visibility of module objects Internal procedures

Variables and procedures in modules can be PRIVATE or Each program unit (program/subroutine/function) may
PUBLIC contain internal procedures
PUBLIC = visible for all program units using the module
(the default) SUBROUTINE mySubroutine
...
PRIVATE will hide the objects from other program units CALL myInternalSubroutine
...
REAL :: x, y CONTAINS
PRIVATE :: x SUBROUTINE myInternalSubroutine
PUBLIC :: y ...
! Or END SUBROUTINE myInternalSubroutine
REAL, PRIVATE :: x END SUBROUTINE mySubroutine
REAL, PUBLIC :: y

32 33

Internal procedures Internal procedures: example


SUBROUTINE parent()
Declared at the end of a program unit after the IMPLICIT NONE
CONTAINS statement INTEGER :: i,j
i = 1; j = 1
Nested CONTAINS statements are not allowed CALL child()
! After subroutine call i = 2 and j = 1
Variable scoping:
CONTAINS
Parent units variables and objects are accessible
Parent units variables are overlapped by local variables SUBROUTINE child()
IMPLICIT NONE
with the same name INTEGER :: j
i = i + 1 ! Variable i is from the scope of parent
Often used for small and local, convenience j = 0 ! Variable j has local scope
END SUBROUTINE child
subroutines within a program unit
END SUBROUTINE parent

34 35
External procedures Interfaces

Declared in a separate program unit INTERFACE Wrong calling arguments


SUBROUTINE not_dangerous(a, b, c)
Referred to with the EXTERNAL keyword INTEGER :: a, b, c to EXTERNAL procedures
END SUBROUTINE not_dangerous may lead to errors during
Compiled separately and linked to the final executable END INTERFACE
the executable linking
Avoid using them within a program, module procedures INTEGER :: x, y, z phase or even when the
provide much better compile time error checking x=1; y=1; z=1
! Call external subroutine without executable is being run
External procedures are often needed when using ! an interface
It is highly recommended
call dangerous(x,y,z)
procedures written with different programming language ! Call external subroutine with to construct INTERFACE
! an interface
library routines (e.g. BLAS and MPI libraries) call not_dangerous(x,y,z) blocks for any external
old F77 subroutines procedures used

36 37

Interfaces Interfaces: example


! LU decomposition from LAPACK
For external procedures, interfaces determine the type INTERFACE
and properties of arguments and return values SUBROUTINE DGETRF(M, N, A, LDA, IPIV, INFO)
INTEGER :: INFO, LDA, M, N
Defined by an INTERFACE block: INTEGER:: IPIV(*)
DOUBLE PRECISION :: A(LDA,*)
interface END SUBROUTINE DGETRF
interface-body END INTERFACE
! Euclidean norm from BLAS
end interface INTERFACE
FUNCTION DNRM2(N, X, INCX)
The interface-body matches the subprogram header INTEGER :: N, INCX
DOUBLE PRECISION :: X(*)
position, rank and type of arguments DOUBLE PRECISION :: DNRM2
return value type and rank (for functions) END FUNCTION DNRM2
END INTERFACE

38 39
Global data and global variables Program units

Global variables can be accessed from any program unit Main program Modules
F90 module variables provide controllable way to define USE, explicit interface
and use global variables
MODULE commons
INTEGER, PARAMETER :: r = 0.42
INTEGER, SAVE :: n, ntot External
REAL, SAVE :: abstol, reltol External, implicit interface
procedures
END MODULE commons

Explicit interface: type checking, limited scope External, implicit interface


Implemented as common blocks in old F77 codes
COMMON/EQ/N,NTOT
COMMON/TOL/ABSTOL,RELTOL
Module procedures Internal procedures
Extremely error prone
40 41

Summary

Procedural programming makes the code more readable


and easier to develop
Procedures encapsulate some piece of work that makes
sense and may be worth re-using elsewhere
Fortran uses functions and subroutines
Values of procedure arguments may be changed upon
calling the procedure
Fortran modules are used for modular programming and
data encapsulation

42
Outline

Introduction to Fortran arrays


Array declaration and syntax
Array initialization
Array sections

Fortran arrays

43 44

Introduction to Fortran arrays Array declaration


INTEGER, PARAMETER :: M = 100, N = 500
Fortran language is a very versatile in handling especially INTEGER :: idx(M)
multi-dimensional arrays REAL :: vector(0:N-1)
REAL :: matrix(M,N)
Arrays refer to a particular built-in (or derived) data type, CHARACTER(len=80) :: screen(24)
TYPE(my_own_type) :: object(10)
but they all have one or more dimensions specified in the
variable declaration ! Or equivalently

Fortran supports up to 15 dimensions INTEGER, DIMENSION(M) :: idx


REAL, DIMENSION(0:N-1) :: vector
REAL, DIMENSION(1:M,N) :: matrix
CHARACTER(len=80), DIMENSION(24) :: screen
TYPE(my_own_type), DIMENSION(1:10) :: object

45 46
Arrays in modern Fortran Data layout in multi-dimensional arrays
INTEGER :: m = 3, n = 4, i, j Array syntax in modern Always increment the left-most index of multi-
REAL :: A(m,n), x(n), y(m)
Fortran enables a neat dimensional arrays in the innermost loop (i.e. fastest)
! Array syntax way to express
y=0.0 Column major ordering in Fortran vs. Row major
do j = 1, n mathematical operations ordering in C
y(:) = y(:) + A(:,j)*x(j)
end do A compiler (with sufficient optimization flags) may re-
= =
! Or, equivalently with explicit order loops automatically
=1
! loops 1
y=0.0 1 11 12 13 14
2 do i=1,N do j=1,M
do j = 1, n 2 = 21 22 23 24
3 do j=1,M do i=1,N
do i = 1, m 3 31 32 33 34
4 y(i) = y(i)+ a(i,j)*x(j) y(i) = y(i)+ a(i,j)*x(j)
y(i) = y(i) + A(i,j)*x(j)
end do end do
end do
end do end do
end do

47 48

Array initialization Array initialization


! Element-by-element initialization
Arrays can be initialized
do j = 1, n
element-by-element basis idx(j)=j
vector(j)=0
copied from another array end do
using single line data initialization statements
! Initialization by copying from another array
using the FORALL and WHERE statements REAL :: to1(100,100), from1(100,100)
REAL :: to2(100,100), from2(0:199,0:199)
...
to1 = from1
to2(1:100, 1:100) = from2(0:199:2,0:199:2)

Every 2nd element

49 50
Array initialization with array constructors Arrays sections
! Set elements from 3 to N+8 to 0 Fortran array syntax
INTEGER :: idx(0:10) Sub_Vector(3:N+8)=0
enables accessing a part
! using the array constructor (//) ! Access a subblock of a matrix of an array in an intuitive
idx(0:10) = (/ 0, (i, i = 1, 3), (0, j = 4, 10) /) A(2:500,3:300:3) = 4.0
way: array sections
! or equivalently (F03) ! Set every third element from 1 to
idx(0:10) = [0, (i, i = 1, 3), (0, j = 4, 10)] ! 3*N+1 to 1
Every_Third(1:3*N+1:3) = 1

! The F77 way (just for a reference) ! Set block [i-1:i+1,j-2:j+2] to k


DATA idx / 0, 1, 2, 3, 7 * 0 / Diag_Block(i1:i+1,j2:j+2) = k

! these can be used in setting variable values upon declaration ! Access subcube of a 3D array
INTEGER :: values(3) = [11, 22, 33] pixel_3D(128:150,56:80,1:256:8)=32000

51 52

Array sections Arrays sections


! Conforming size of 3-by-10 When copying array INTEGER :: Array(10, 20) Array sections can be
LHS(1:3, 0:9)=RHS(-2:0, 20:29)
sections, both left -and ! Pass a full array passed into a procedure
! Error: LHS 2-by-10, RHS 3-by-10 right hand sides of the CALL SUB(Array)
LHS(1:2, 0:9) = RHS(-2:0, 20:29) An array section is usually
assignment statement ! Pass a subblock copied into a hidden
must have conforming CALL SUB(Array(5:10,10:20))
temporary array upon
dimensions ! Pass a non-contiguous subblock calling a procedure and
CALL SUB(Array(1:10:2,1:1))
copied back to the array
! Pass an array slice section upon return
CALL SUB(Array(1:4,1:))
CALL SUB(Array(:10,:))

53 54
Summary

Use of arrays makes Fortran language a very versatile


vehicle for computationally intensive program
development
Using array syntax, vectors and matrices can be initialized
and used in a very intuitive way and thus suitability for
scientific computing applications is well justified
Use of array sections increase code readability and
usually reduce chances of mistakes

55
Outline

Array intrinsic functions


Dynamic memory allocation
Fortran POINTER attribute

More about Fortran arrays

56 57

Array intrinsic functions Array intrinsic functions

Array intrinsic functions are built-in functions which can The most commonly used array intrinsic functions are:
apply various operations on the whole array at once, i.e., SIZE, SHAPE, COUNT, SUM
not just individual array elements ANY, ALL
As a result another array or just a scalar value is returned MINVAL, MAXVAL , MINLOC, MAXLOC
A subset selection through masking is also possible RESHAPE
Masking and use of array (intrinsic) functions is often DOT_PRODUCT, MATMUL, TRANSPOSE
accompanied with use of FORALL and WHERE array PACK, UNPACK, SPREAD
statements
Operations are performed for those elements where
corresponding elements of the mask are .TRUE.
58 59
Array intrinsic functions:
Array intrinsic functions: ANY, ALL
SIZE, SHAPE, COUNT, SUM
SIZE(array [, dim]) returns # of elements in the ANY(L_array [, dim]) returns a scalar value of
array [, along the specified dimension] .TRUE. if any value in L_array is .TRUE.
SHAPE(array) returns an INTEGER vector containing the
size of array in each dimension ALL(L_array [, dim]) returns a scalar value of
COUNT(L_array [,dim]) returns count of elements .TRUE. if all values in L_array are .TRUE.
which are .TRUE. in L_array
SUM(array[, dim][, mask]) sum of the elements of
array [, along dimension] [, under mask]

60 61

Array intrinsic functions:


Array intrinsic functions: example
MINVAL, MAXVAL, MINLOC, MAXLOC
integer :: j
MINVAL(array [,dim] [, mask]) returns the integer, parameter :: m = 10, n = 20
minimum value of a given array real :: x(m,n), v(n)

[, along the specified dimension] and [, under mask] call random_number(x)

MAXVAL is the same as MINVAL, but returns the maximum print *, size(x), size(v) ! prints m * n, n
print *, shape(x) ! prints m, n
value of a given array print *, size(shape(x)) ! prints 2
print *, count(x >= 0)
MINLOC(array [, mask]) returns a vector of location(s) print *, sum(x, dim=2, mask=x < 0.5) ! the result is a vector !!
[, under mask], where the minimum value(s) is/are
v(1:n) = [ (j, j=1,n) ]
found print *, any(v > -1 .and. v < 1)
print *, all(x >= 0, dim=1)
MAXLOC similar to MINLOC, but for maximums print *, minval(v), maxval(v)
print *, minloc(v), maxloc(v)

62 63
Array intrinsic functions: RESHAPE Array intrinsic functions:
DOT_PRODUCT, MATMUL, TRANSPOSE
RESHAPE(array, shape) returns a reconstructed (=a DOT_PRODUCT(a_vec, b_vec) returns a scalar dot
copy of an) array with different shape than in the product of two vectors
input array MATMUL(a_mat, b_mat) returns a matrix containing
Can be used as a single line statement to initialize an array matrix multiply of two matrices
(sometimes at the expense of readability) TRANSPOSE(a_mat) returns a transposed matrix of the
input matrix
integer :: a(6), b(3,2), i
a = [(i, i=1,6)]
b = reshape(a, [3,2])

64 65

Array intrinsic functions: example Array intrinsic functions


integer :: l, m, n Array control statements FORALL and WHERE are
real :: a(l,m), b(m,n), c(l,n)
real :: a_tr(m,l) commonly used in the context of manipulating arrays
real :: v1(n), v2(n), dotp Technically they are not array intrinsic functions, but very
! transpose a matrix
closely related to array manipulations
a_tr = transpose(a) FORALL and WHERE can provide masked assignment of
! compute matrix-matrix product c=a*b
c = matmul(a, b) values using efficient vector operations
! compute dot product (v1,v2)=v2^t*v1
dotp = dot_product(v1, v2)

66 67
Array intrinsic functions: example Dynamic memory allocation
integer :: j, ix(5) integer :: j Fortran provides two different mechanisms to
ix(:) = (/ (j, j=1, size(ix)) /) real :: a(100,100), b(100), c(100)
dynamically allocate memory for arrays:
where (ix == 0) ix = -9999 ! fill in diagonal matrix 1. Array variable declaration has an ALLOCATABLE (or a
forall (j=1:100) a(j,j) = b(j) POINTER) attribute, and memory is allocated through
where (ix < 0)
ix = -ix ! fill in lower bi-diagonal matrix
ALLOCATE statement
elsewhere forall (j=2:100) a(j,j-1) = c(j) 2. Array variable, which is declared in the procedure with
ix = 0 (runtime) size information coming from the procedures
end where
argument list or from a Fortran MODULE, is called an
automatic array: no ALLOCATE is needed

68 69

Dynamic memory allocation: example Dynamic memory allocation: example


integer :: m, n, alloc_stat subroutine sub (m)
integer, allocatable :: idx(:) use some_module, only : n
When automatic arrays
real, allocatable :: mat(:,:) integer, intent(in) :: m are being used, no explicit
m = 100 ; n = 200 integer :: idx(0:m1)
ALLOCATE or
real :: mat(m , n) DEALLOCATE is needed
allocate( idx(0:m1) , stat = alloc_stat ) ! implementation omitted
if (alloc_stat /= 0) stop ! an error end subroutine sub

allocate( mat(m, n) , stat = alloc_stat )


if (alloc_stat /= 0) stop ! an error

deallocate(idx , mat)

70 71
Pointers to arrays Pointers to arrays

The POINTER attribute enables to create array (or scalar) A POINTER can refer to an already allocated memory
aliasing variables region
Initialized to point to nothing
Pointer variables are usually employed to refer to
integer, pointer :: p_x(:) => null()
another array or array section integer, target :: x(1000)
...
A pointer variable can also be a sole variable itself, but p_x => x Pointers provide a neat way for array
sections
requires ALLOCATE p_x => x(2 : 300)
p_x => x(1 : 1000 : 5)
Not recommended; the ALLOCATABLE attribute and ...
p_x(1) = 0
employ POINTER variables for aliasing only in stead nullify(p_x) This would also change x(1) to 0
Note for C programmers: a "pointer" has a slightly
different meaning in C and Fortran Disconnects p_x from x

72 73

Pointers to arrays Summary


real, pointer :: p_mat(: ,:) => null() ASSOCIATED function Array intrinsic functions further simplify coding efforts
real, target :: mat(100,200)
can be used to check and improve program code readability when using
p_mat => mat whether a POINTER is Fortran arrays
if ( associated (p_mat) ) &
print *, 'points to something' associated with a target Dynamic memory allocation enables sizing of arrays
nullify(p_mat)
Returns .TRUE. if according to particular needs
if (.not. associated (p_mat) ) & associated with a target,
print *, 'points to nothing' .FALSE. if not Pointers offer a versatile alias mechanism to refer into
For an uninitialized the existing arrays or array sections
POINTER variables, the
return value is undefined

74 75
Outline

Input/output (I/O) formatting


Internal I/O
File I/O
File opening and closing
Writing and reading to/from a file
Formatted and unformatted (binary) files
Input/Output Stream I/O

76 77

Input/Output formatting Output formatting


data type format descriptors examples
To prettify output and to make it human readable, use
integer iw, iw.m write(*,'(i5)') j
format descriptors in connection with the write write(*,'(i5.3)') j
statement write(*,'(i0)') j
real (decimal and fw.d write(*,'(f7.4)') r
Although less often used nowadays, it can also be used exponential forms, ew.d write(*,'(e12.3)') r
with read to input data at fixed line positions and using auto-scaling) gw.d write(*,'(g20.13)') r

predefined field lengths character a, aw write(*,'(a)') c

Used through format statements, character variable logical lw write(*,'(l2)') l


or embedded in read/write fmt keyword
w=width of the output field, d=number of digits to the right of decimal
point, m=minimum number of characters to be used.
Variables: Integer :: J, Real :: R, Character :: C, Logical :: L

78 79
Output formatting: miscellaneous The I0 and G0 format descriptors

With complex numbers provide format for both real and Dynamic sizing of REAL and INTEGER valued output
imaginary parts: I0 appeared in F03 and G0 was introduced in F08
complex :: z
write (*,'(f6.3,2x,f6.3)') z ! real & imaginary parts
Output fields are left justified with all the unnecessary
leading blanks (and precision for REAL valued variables)
Line break, whitespace, tabbing:
removed
write (*,'(f6.3,/,f6.3)') x, y ! linebreak between x,y
integer :: i = 12345
write (*,'(i3,2x,f6.3)') i, x ! 2 spaces between i & x real (kind=4) :: sp = 1.23e0
write (*,'(i5,t2,i5)') i, j ! 2 tabs between i & j real (kind=8) :: dp = 1.234567890d0
It is possible that an edit descriptor will be repeated a write(*,fmt='("<i=",i0,", reals=",2(g0,1x),">")') i,sp,dp

specified number of times Output is <i=12345, reals=1.230000 1.234567890000000 >


write (*,'(5i8)') ivec(1:5)
write (*,'(4(i5,2x,f8.3))') (ivec(j),zvec(j),j=1,4)

80 81

Handling character strings Internal I/O

Fortran provides several intrinsic functions for handling Often it is necessary to filter out data from a given
character strings, such as character string
trim(string) - removes blank spaces from the end of Or to pack values into a character string
string Fortran internal I/O with READ & WRITE becomes
adjustl(string)/adjustr(string) - moves blank now handy
spaces from the beginning/end of the string to the
Actual files are not involved at all
end/beginning of it
len(string) - length of a string
index(string, substring) - returns the starting
position of a substring within a string

82 83
Internal I/O: examples Opening and closing files: basic concepts
character(len=13) :: cl1
character(len=60) :: cl2
Writing to or reading from a file is similar to writing onto
integer :: njobs, istep a terminal screen or reading from a keyboard
! extract a number from character string Differences
cl1 = 'time step# 10'
read(cl1,fmt='(10x,i3)') istep File must be opened with an OPEN statement, in which the
unit number and (optionally) the file name are given
! write data to a character string
njobs = 2014 Subsequent writes (or reads) must to refer to the given
write(cl2,'(a,i0)') 'the number of jobs completed = ', njobs unit number
File should be closed at the end

84 85

Opening and closing a file Opening and closing a file

The syntax is (the brackets [ ] indicate optional keywords The first parameter is the unit number
or arguments) The keyword unit= can be omitted
open([unit=]iu, file='name' [, options]) The unit numbers 0, 5 and 6 are predefined
close([unit=]iu [, options])
0 is output for standard (system) error messages
For example
5 is for standard (user) input
open(10, file= 'output.dat', status='new')
close(unit=10, status='keep') 6 is for standard (user) output
These units are opened by default and should not be re-
opened nor closed by the user

86 87
Opening and closing a file File opening options

The default input/output unit can be referred with a star: status: existence of a file
write(*, ...) 'old', 'new', 'replace', 'scratch', 'unknown'
read(*, ...)
position: offset, where to start writing
Note that these are not necessarily the same as the stdout
and stdin unit numbers 6 and 5 'append'
If the file name is omitted in the OPEN, the file name will action: file operation mode
based on unit number being opened, e.g. for unit=12 'write', 'read', 'readwrite'
this usually means the filename fort.12 (on UNIX- form: text or binary file
systems) 'formatted', 'unformatted'

88 89

File opening options File opening: file properties

access: direct or sequential file access Use inquire statement to find out information about
'direct', 'sequential', 'stream', file existence
iostat: error indicator, (output) integer file unit open status
non-zero only upon an error various file attributes
err: the fortran label number to jump upon an error The syntax has two forms, one based on file name, the
recl: record length, (input) integer other for unit number
inquire(file='name', options ...)
for direct access files only
inquire(unit=iu, options ...)
warning (check): may be in bytes or words

90 91
File opening: file properties File opening: file properties example
! check the existence of a file
exist does file exist ? (logical)
logical :: file_exist
opened is file / unit opened ? (logical) inquire (file='foo.dat', exist=file_exist)
if (.not. file_exist) then
form 'formatted' or 'unformatted' (char) write(*,*) 'the file does not exist'
access 'sequential' or 'direct' or 'stream' (char) else
! do something with the file foo.dat
action 'read', 'write', 'readwrite' (char) endif

recl record length (integer)


size file size in bytes (integer)

92 93

File writing and reading Formatted vs. unformatted files


Writing to and reading from a file is done by giving the Text or formatted files are
corresponding unit number (iu) as a parameter : Human readable
write(iu,*) str The star format (*) indicates list- Portable i.e. machine independent
write(unit=iu, fmt=*) str directed output (i.e. programmer does
read(iu,*) str not choose the input/output styles)
Binary or unformatted files are
read(unit=iu, fmt=*) str Machine readable only, generally not portable
Formats and other options can be used as needed Much faster to access than formatted files
If keyword 'unit' is used, also the keyword 'fmt' must be Suitable for large amount of data due to reduced file sizes
used Internal data representation used for numbers, thus no number
Note: 'fmt' is applicable to formatted, text files only conversion, no rounding of errors compared to formatted data

94 95
Unformatted I/O Stream I/O
A binary file write adds extra record delimiters (hidden
Write to a sequential binary file from programmer) to the beginning and end of records
real :: rval
character(len=60) :: string In Fortran 2003 using access method 'stream' avoids this
open(10, file='foo.dat', form='unformatted') and implements a C-like approach
write(10) rval
write(10) string It is recommended to use stream I/O
close(10)
Create a stream (binary) file
No format descriptors allowed real :: dbheader(20), dbdata(300)
Reading similarly open(10,file='my_database.dat', access='stream')
write(10) dbheader
read(10) rval write(10) dbdata
read(10) string close(10)

Reading similarly
96 97

Summary

Input/Output formatting
Internal I/O
Files: communication between a program and the
outside world
Opening and closing a file
Data reading & writing
Use unformatted (stream) I/O for all except text files

98
Outline

A few more words about Fortran built-in data types


Rationale behind derived data types
Data type declaration and visibility with examples

Derived data types

99 100

Fortran built-in types A few words about numerical precision

Standard Fortran already supports a wide variety of The variable representation method (precision) may be
fundamental data types to represent integers, floating declared using the KIND statement
point numbers ("real"), truth values ("logical") and ! SELECTED_INT_KIND(r) Integer between -10r < n < 10r
variable length character strings ! SELECTED_REAL_KIND(p)
! SELECTED_REAL_KIND(p,r) Real number accurate up to p decimals
In addition each of these built-in types can be declared INTEGER, PARAMETER :: short=SELECTED_INT_KIND(4)
as (multi-dimensional) arrays INTEGER, PARAMETER :: double=SELECTED_REAL_KIND(12,100)
INTEGER (KIND=short) :: index
Reals and integers can be declared to consume less REAL (KIND=double) :: x, y, z
COMPLEX (KIND=double) :: c
memory in expense of reduced numerical precision A floating point (real) number between
through kind parameter x=1.0_double; y=2.0_double * ACOS(x) -10100 < x < 10100, accurate up to 12
decimals

101 102
Numerical precision: example Fortran 2008 ISO_FORTRAN_ENV
PROGRAM Precision_Test MODULE prec
IMPLICIT NONE USE ISO_FORTRAN_ENV, ONLY: INT32, INT64, REAL32, REAL64
IMPLICIT NONE
INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6,30), &
dp = SELECTED_REAL_KIND(10,200) PRIVATE
REAL(KIND=sp) :: a INTERGER, PARAMETER :: i4 = INT32 &
REAL(KIND=dp) :: b i8 = INT64 &
WRITE(*,*) sp, dp, KIND(1.0), KIND(1.0_dp) r4 = REAL32 &
WRITE(*,*) KIND(a), HUGE(a), TINY(a), RANGE(a), PRECISION(a) r8 = REAL64
WRITE(*,*) KIND(b), HUGE(b), TINY(b), RANGE(b), PRECISION(b)
PUBLIC :: i4, i8, r4, r8
END PROGRAM Precision_Test END MODULE prec
Program output:
4 8 4 8
4 3.4028235E+38 1.1754944E-38 37 6
8 1.797693134862316E+308 2.225073858507201E-308 307 15

103 104

Numerical precision What is a derived data type ?


Other intrinsic functions related to numerical precision
Derived data type is a data structure composed of built-in
KIND(A) Returns the kind of the supplied argument data types and possibly other derived data types
TINY(A) The smallest positive number Equivalent to struct in C programming language
HUGE(A) The largest positive number
Derived type is defined in the variable declaration section
EPSILON(A) The smallest positive number added to 1.0
of the programming unit
returns a number just greater than 1.0
PRECISION(A) Decimal precision By default not visible to other programming units
DIGITS(A) Number of significant digits Unless defined in a module and used via USE clause, which is
RANGE(A) Decimal exponent most often the preferred way
MAXEXPONENT(A) Largest exponent (of the kind(A))
MINEXPONENT(A) Smallest exponent (of the kind(A))
105 106
Derived data types rationale Data type declaration: example
! define a type describing a skater
Properly constructed data types make the program more
type playertype
readable, lead to clean interfaces and reduce errors character (len=30) :: name
Changes in one part of the program will have limited effect integer :: goals
integer :: assists
in other parts end type playertype
Variables used in the same context should be grouped
! define a type describing a goalkeeper
together, using modules and derived data types type goalietype
character (len=30) :: name
real :: svs
real :: gaa
end type goalietype

107 108

Data type access: example Nested derived types: example


! declare variables of the player type ! type declaration
type(playertype) :: kim type hockeyteam
type(playertype), dimension(30) :: players character (len=80) :: name
type(playertype) :: players(30)
! Initialization of / access to type components type(goalietype) :: goalies(3)
kim % name = 'Kim Hirschovits end type hockeyteam
kim % goals = 13
kim % assists = 45 ! variable declaration
type(hockeyteam) :: blues, tappara, karpat
! Initialization via type constructor
kim = playertype('Kim Hirschovits',13,45)
! initialization / access
tappara % name = 'tappara'
! Arrays of derived types accessed elementwise tappara % players(1) % name = Teemu Aalto'
players(1) % name = 'Miro Aaltonen' tappara % players(1) % goals = 11
players(1) % goals = 16
players(1) % assists = 21

109 110
Visibility of derived data types Summary

When declared in the same programming unit derived Derived data types enables grouping of data to form
data types are visible to that unit only logical objects
and sub-units under CONTAINS statement A Fortran program becomes more readable and modular
When declared in a module unit, a derived data type can with sensible use of derived data types
be accessed outside the module through USE statement Handling of more complicated data structures becomes
The visibility can be controlled in more detailed level more manageable with use of derived types
using PRIVATE attribute Enables the use of object oriented programming
concepts

111 112
Outline

Fortran 2003 is a major extension over Fortran 90/95


Fortran 2008 is a smaller extension over Fortran 2003, but
still significant due to addition of coarrays
F03 and F08 standardize reading command line
arguments, getting values for environment variables, and
system calls
F03 brings improvements to semantics of ALLOCATABLE
Useful new features and POINTER variables
Several small miscellaneous enhancements

113 114

Command line arguments Command line arguments

Parameters to a program are very often given to Access separate command line arguments
programs as command line arguments get_command_argument(number[,value][,length][,status])

Input file(s), modify program behavior, etc. number is of type integer and denotes which argument to
get
Fortran 2003 has a standardized method for reading
command line arguments value is of type character string and contains the value of
the requested argument on return (optional)
get_command_argument and
length is of type integer and contains the length of the
command_argument_count
requested argument on return (optional)
To access the whole command line, use
status is of type integer. On successful return status is
get_command 0, -1 if value was too short to contain actual argument and
1 if argument could not be returned (optional)
115 116
Command line arguments Command line input

Get the number of command line arguments subroutine read_command_line(height, width)


Example: reading in integer, intent(out) :: height, width
integer :: command_argument_count()
two integer values character(len=10) :: args(2)
integer :: n_args, i
from the command n_args = command_argument_count()
if ( n_args /= 2 ) then
line, e.g. write(*,*) ' Usage : ./exe height width'
% ./a.out 100 100 call abort()
end if
do i = 1, 2
call get_command_argument(i,args(i))
args(i) = trim(adjustl(args(i)))
end do
read(args(1),*) height
read(args(2),*) width
end subroutine read_command_line

117 118

Command line arguments Environment variables

Access the whole command line Besides command line arguments, environment variables
call get_command(command[,length][,status]) are a common way to modify program behaviour
command is of type character string and contains the value Fortran 2003 has a standardized method for accessing
of the command line on return. values of environment variables
length is of type integer and contains the length of the
command line on return (optional)
status is of type integer. On successful return status is
0, -1 if value was too short to contain actual argument and
1 if argument could not be returned (optional)

119 120
Environment variables Environment variables: example
program environment
Access a value of an environment variable implicit none
call get_environment_variable(name,value[,length] character(len=256) :: enval
[,status][,trim_name]) integer:: len,stat

name is of type character string and contains the name of the ! extract hostname
requested variable call get_environment_variable('hostname',enval,len,stat)
if (stat == 0) write (*,'(a,a)') 'host=', enval(1:len)
value is of type character string and contains the value of the
requested variable ! extract user
call get_environment_variable('user',enval,len,stat)
length is of type integer and contains the length of the if (stat == 0) write (*,'(a,a)') 'user=', enval(1:len)
requested variable on return (optional) end program environment

status (optional)
trim_name is of type logical and sets if trailing blanks are
allowed in variable names or not (optional)
121 122

Executing commands Executing commands

Invoking external programs from within a program is Execute a command line


occasionally needed call execute_command_line(command[,wait][,exitstat]
[,cmdstat][,cmdmsg])
No source nor library API available for a useful program
command is a character string containing the command to be invoked
perl/python/etc parsing scripts wait is logical value indicating if command termination is to be waited
Fortran 2008 has a standardized method for invoking an (.true., the default) or if the command is to be executed
asynchronously (.false.) (optional)
external command
exitstat is an integer value containing the return value of the
command if wait=.true. (optional)
cmdstat is an integer value. It is assigned a value of zero if command
executed successfully. For other return codes, see docs (optional)
cmdmsg is a character string containing explanatory message for
positive values of cmdstat (optional)
123 124
Executing commands: example Enhancements to dynamic memory allocation
program execcommand
Fortran 2003 added features related to dynamic memory
implicit none
integer :: estat, cstat allocation
The most common are
! execute a unix command
call execute_command_line('ls -al', .true., estat, cstat) Automatic DEALLOCATE when ALLOCATABLE goes out of
if (estat==0) write (*,'(a)') 'command completed successfully scope
end program execcommand
ALLOCATABLE components in derived data types
ALLOCATABLE procedure arguments
ALLOCATABLE function return values

125 126

ALLOCATABLE type components ALLOCATABLE procedure arguments


module my_mod In Fortran90 dynamic program test Procedure arguments are
type my_type integer :: n
real, allocatable :: array(:) components of user real, allocatable :: a(:) permitted to be
end type my_type defined data types were call sub(a, n) ALLOCATABLE
end module my_mod call use_array(a, n)
restricted to have the deallocate(a) Dynamic memory
subroutine sub(n) POINTER attribute end program test
use my_mod allocation in the callee
implicit none The restriction was subroutine sub(a, n) based on sizing
integer, intent(in) :: n real,allocatable,intent(out)::a(:)
type(my_type) :: t removed in Fortran 2003 integer, intent(out) :: n information
: read *, n
allocate(t % array(n)) allocate(a(n))
Allocated (and possibly
: read *, a initialized) data returned
end subroutine sub ! no automatic deallocate here!
end subroutine sub
to the caller

127 128
Function return value as ALLOCATABLE ALLOCATABLE scalars
program test Functions are permitted program test Typically used with
real :: unpacked(1000) character(:), allocatable :: ch
real, allocatable :: a(:) to have an ALLOCATABLE integer :: lench CHARACTER strings,
a = pack_data(unpacked) value lench = len('hello world!') whose length is decided at
call use_packed_data(a) ! explicit allocation
deallocate(a) Functionality similar as allocate(character(lench)::ch) run time
contains ch(:) = 'hello world!'
function pack_data(x) result (pk) with procedure arguments print *,len(ch)
real, allocatable :: pk(:) end program test
real, intent(in) :: x(:)
Particularly useful when a
integer :: npk dynamically sized array is
npk = num_distinct_values(x)
allocate(pk(npk))
returned
call get_dist_vals(x,...,pk,npk)
end function pack_data
end program test

129 130

Transferring an allocation: MOVE_ALLOC Summary


program test Moves allocation from
integer, allocatable :: a(:), b(:) With Fortran 2003 and 2008, it is possible to obtain command
allocate(a(1:5)) ; a(:) = 0 one memory location to line arguments, access environment variables and run
a(3) = 3 another
! output: 0 0 3 0 0 operating system commands in a standardized way
print *, a=,a Previous allocation Dynamic memory allocation has been improved by means of
call move_alloc(a,b)
! a is now deallocated becomes unallocated and enhancements to ALLOCATABLE variables
! b is now allocated new allocation holds the
if (allocated(a)) print *, >a=,a
if (allocated(b)) print *, >b=,b previous data
! legal, but not required
deallocate(b)
Arrays to (=a) and from
! would be illegal: deallocate(a) (=b) must have the same
end program test
type and rank

131 132
Outline

Fortran 2003 and Fortran 2008 in short


Abstract interfaces and procedure pointers
Object-oriented features in Fortran 2003/2008
Fortran coarrays

Outlook on Fortran 2003/2008

133 134

Fortran 2003 in short Fortran 2008 in short

Fortran 2003 is a major revision over Fortran 95 standard Fortran 2008 upgrades the standard even further
Interaction with the environment Fortran coarray syntax
Interoperability with C Several new intrinsic procedures (bit manipulation etc.)
I/O enhancements Several performance related enhancements
Object-oriented features
Several minor enhancements and clarifications
Support for IEEE floating point arithmetics and exceptions
Several minor enhancements

135 136
Object-oriented programming in Fortran Fortran coarrays

Fortran 2003/2008 supports object-oriented (OO) Parallel processing as part of Fortran language standard
programming Only small changes required to convert existing Fortran code
Abstract interfaces to support a robust and potentially efficient parallelism
Type extensions, polymorphism (single inheritance), A Partitioned Global Address Space (PGAS) paradigm
abstract types Parallelism implemented over distributed shared memory
Type and- object-bound procedures, type operators, type- CAF is potentially massively parallel
bound generics, finalizers
Integrated into Fortran 2008 standard
Object model designed to maintain backwards Compiler support is still incomplete (Cray: excellent, Intel:
compatibility with Fortran 95 moderate, GNU: experimental)

137 138

Fortran coarrays in short Coarray execution model

Adds only a few syntactic alterations and rules to the Upon startup the program gets replicated into a number
Fortran language of copies called images (i.e. processes)
Provides mechanisms to allow The number of images is usually decided at the execution
SPMD (Single Program, Multiple Data) style of explicitly time, but (in rare cases) can also be fixed at compile time
parallel programming Each replica (image) runs asynchronously in a loosely
Data distribution over partitioned memory coupled way until program controlled synchronization
Synchronization primitives Images (local) data are visible within the image only
Memory management for dynamic shared entities except for data declared as special arrays i.e. coarrays
One-sided data communication enables movement of co-
array data across different images of a coarray program
139 140
Look & feel Automatic allocations
PROGRAM DATA Each image executes PROGRAM ALLOC_EXAMPLE Fortran 2008 standard has
INTEGER :: global(3)[*], & INTEGER, ALLOCATABLE :: a(:), b(:)
& local(3), npes concurrently, INTEGER :: i many enhancements to
npes = num_images() synchronization with ALLOCATE(a(10)) the ALLOCATE
! Initialize global data a = [(i, i=1,10)]
global(:) = this_image()*(/1,2,3/) separate calls ! This would fail: b(:) = a(:) Automatic allocation,
SYNC ALL b = a
! Initialize local data by copying Division of data to a = [a, b]
reallocation and
! from image number npes global: visible to all print *, size(a), size(b) deallocation
local(:) = global(:)[npes] END PROGRAM ALLOC_EXAMPLE
END PROGRAM data images, [] operator
local: visible only locally, ! Result: 20 10

() operator
Global data is read/write
accessible to all images
141 142

Summary

Fortran is a modern language that continues to evolve


Fortran remains as one of the major languages for
scientific computation
A more thorough introduction to Fortran object-oriented
features and coarrays are given during the course
Advanced Fortran programming

143

Вам также может понравиться