You are on page 1of 34

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 Compiling and linking

Fortran 2003 (2004): a major revision, adding e.g. object- source code
oriented features, C-bindings (.f, .F, .f90, .F90)

Fortran 95/2003 is the current de facto standard INCLUDE


files compiler output
compiler
The latest standard is Fortran 2008 (2010): a minor (optional)
modules
revision object code
Most notable addition: Fortran coarray syntax (.o, .so)

Compiler support nearly complete libraries linker output


linker
(.a, .so) (optional)
The next revision: Fortran 2015
executable

5 6

The transition from a code to a program Look and feel


program square_root_example
Compile and link in one go, execute the binary ! comments start with an exclamation point.
gfortran main.f90 -o foo ! you will find data type declarations, couple arithmetic operations
./foo ! and an interface that will ask a value for these computations.
implicit none
In more complex cases (multiple sources) real :: x, y
Compile each source code file (.f90) into an object file (.o) intrinsic sqrt ! fortran standard provides many commonly used functions

gfortran -c main.f90 ! command line interface. ask a number and read it in


gfortran -c sub.f90 write (*,*) 'give a value (number) for x:'
read (*,*) x
Link object files into a binary and execute the binary y = x**2+1 ! power function and addition arithmetic
gfortran -o foo main.o sub.o
./foo write (*,*) 'given value for x:', x
(Modify sub.f90) write (*,*) 'computed value of x**2 + 1:', y
gfortran c sub.f90 ! print the square root of the argument y to screen
gfortran -o foo main.o sub.o write (*,*) 'computed value of sqrt(x**2 + 1):', sqrt(y)
./foo end program square_root_example

7 8
Source code remarks Variables
Variables must be declared at the
Free format source code, but integer :: n0
beginning of the program or
A variable name can be no longer than 31 characters containing real :: a, b
procedure where they are used
only letters, digits or underscore, must start with a letter real :: r1=0.0 the intrinsic data types in Fortran are
Maximum row length is 132 characters complex :: c
integer, real, complex, character and
logical
No distinction between lower and uppercase characters complex :: imag_number=(0.1, 1.0)

Character strings are case sensitive They can also be given a value at
character(len=80) :: place
declaration (not recommended)
character(len=80) :: name='james bond'
Line break is the statement separator
Constants are defined with the
If a line is ended with ampersand (&), the line continues onto logical :: test0 = .true.
PARAMETER clause they cannot be
logical :: test1 = .false.
the next line altered after their declaration

There can be 39 continuation lines at the maximum real, parameter :: pi=3.14159

Semicolon (;) as a separator between statements on a single line


9 10

Operators Arrays
Arithmetic operators
real :: x,y
integer, parameter :: m = 100, n = 500
integer :: i = 10
x = 2.0**(-i) !power function and negation precedence: first integer :: idx(m)
real :: vector(0:n-1) By default, Fortran indexing starts
x = x*real(i) !multiplication and type change precedence: second
x = x/2.0 !division precedence: second real :: matrix(m, n) from 1
i = i+1 !addition precedence: third character (len = 80) :: screen ( 24)
i = i-1 !subtraction precedence: third
Relational operators ! or
< or .lt. !less than
<= or .le. !less than or equal to integer, dimension(m) :: idx
== or .eq. !equal to
real, dimension(0:n-1) :: vector
/= or .ne. !not equal to
> or .gt. !greater than real, dimension(m, n) :: matrix
>= or .ge. !greater than or equal to character(len=80), dimension(24) :: screen
Logical operators
.not. !logical negation precedence: first
.and. !logical conjunction precedence: second
.or. !logical inclusive disjunction precedence: third

11 12
Control structures: conditionals Control structures example
2
program test_if program placetest
implicit none implicit none
1
real :: x, y, eps, t logical :: in_square1, in_square2
real :: x, y
write(*,*) give x and y : write(*,*) give point coordinates x and y
read(*,*) x, y read (*,*) x, y
eps = epsilon(x) in_square1 = (x >= 0. .and. x <= 2. .and. y >= 0. .and. y <= 2.)
if (abs(x) > eps) then in_square2 = (x >= 1. .and. x <= 3. .and. y >= 1. .and. y <= 3.)
t = y/x if (in_square1 .and. in_square2) then ! inside both
else write(*,*) point within both squares
write(*,*)division by zero else if (in_square1) then ! inside square 1 only
t = 0.0 write(*,*) point inside square 1
end if else if (in_square2) then ! inside square 2 only
write(*,*) y/x = , t write(*,*) point inside square 2
end program else ! both are .false.
write(*,*) point outside both squares
end if
end program placetest
13 14

Control structures: loops Control structures: 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
! a do-loop with an integer counter (count controlled) do
stepsize = 2 read(*,*) x
do i = 1, max_points, 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

15 16
Control structures example Control structures: select case
program gcd
... select case statements
! computes the greatest common divisor, Euclidean algorithm
integer :: i
implicit none
integer :: m, n, t
logical :: is_prime, matches the entries of a
test_prime_number list against the case index
write(*,*) give positive integers m and n :
...
read(*,*) m, n
write(*,*)m:, m, n:, n
select case (i) Only one found match is
Labels can be given to case (2,3,5,7)
positive_check: if (m > 0 .and. n > 0) then allowed
main_algorithm: do while (n /= 0) control structures and used is_prime = .true.
t = mod(m,n) in conjunction with e.g. exit case (1,4,6,8:10) Usually arguments are
is_prime = .false.
m = n and cycle statements
case default
character strings or
n = t
is_prime=test_prime_number(i) integers
end do main_algorithm
end select
write(*,*) greatest common divisor: ,m
...
default branch if no
else
write(*,*) negative value entered
match found
end if positive_check
end program gcd
17 18

Summary

Fortran is despite of its long history a modern


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

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 Array initialization
INTEGER :: m = 3, n = 4, i, j Array syntax in modern Arrays can be initialized
REAL :: A(m,n), x(n), y(m)
Fortran enables a neat element-by-element basis
! Array syntax (and fast) way to express
y=0.0 copied from another array
do j = 1, n linear algebra operations
y(:) = y(:) + A(:,j)*x(j) using single line data initialization statements
end do
= = using the FORALL and WHERE statements
! Or, equivalently, with explicit
=1
! loops 1
y=0.0 1 11 12 13 14
2
do j = 1, n 2 = 21 22 23 24
3
do i = 1, m 3 31 32 33 34
4
y(i) = y(i) + A(i,j)*x(j)
end do
end do

47 48

Array initialization Array initialization with array constructors


! Element-by-element initialization
do j = 1, n integer :: idx(0:10)
idx(j)=j
vector(j)=0 ! array constructor [ ]
end do idx(0:10) = [0, (i, i = 1, 3), (0, j = 4, 10)]
! these can be used in setting variable values upon declaration
! Initialization by copying from another array integer :: values(3) = [11, 22, 33]
REAL :: to1(100,100), from1(100,100)
REAL :: to2(100,100), from2(0:199,0:199) ! equivalently, the older notation (/ /)
... idx(0:10) = (/ 0, (i, i = 1, 3), (0, j = 4, 10) /)
to1 = from1 ! or the archaic F77 way
data idx / 0, 1, 2, 3, 7 * 0 /
to2(1:100, 1:100) = from2(0:199:2,0:199:2)

Every 2nd element

49 50
Array sections Array sections
! set elements from 3 to n+8 to 0 Fortran array syntax ! Conforming size of 3-by-10 When copying array
sub_vector(3:n+8)=0 LHS(1:3, 0:9)=RHS(-2:0, 20:29)
enables accessing a subset sections, both left and
! access a subblock of a matrix of an array in an intuitive ! Error: LHS 2-by-10, RHS 3-by-10 right hand sides of the
a(2:500,3:300:3) = 4.0 LHS(1:2, 0:9) = RHS(-2:0, 20:29)
way: array sections assignment statement
! set every third element from 1 to must have conforming
! 3*n+1 to 1
every_third(1:3*n+1:3) = 1 dimensions
! set block [i-1:i+1,j-2:j+2] to k
diag_block(i1:i+1,j2:j+2) = k

! access a subcube of a 3D array


pixel_3d(128:150,56:80,1:256:8)=32000

51 52

Array sections Data layout in multi-dimensional arrays


integer :: array(10, 20) Array sections can be Always increment the left-most index of multi-
! pass a full array passed into a procedure dimensional arrays in the innermost loop (i.e. fastest)
call sub(array)
An array section is usually Column major ordering in Fortran vs. Row major
! pass a subblock copied into a hidden ordering in C
call sub(array(5:10,10:20))
temporary array upon A compiler (with sufficient optimization flags) may re-
! pass a non-contiguous subblock calling a procedure and order loops automatically
call sub(array(1:10:2,1:1))
copied back to the array
! pass an array slice section upon return do i=1,N do j=1,M
call sub(array(1:4,1:))
do j=1,M do i=1,N
call sub(array(:10,:))
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

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

Dynamic memory allocation


Array intrinsic functions
Fortran pointer attribute

More about Fortran arrays

56 57

Dynamic memory allocation Dynamic memory allocation: example


integer :: m, n, alloc_stat
Fortran provides two different mechanisms for allocating integer, allocatable :: idx(:)
dynamically memory for arrays: real, allocatable :: mat(:,:)

1. Array variable declaration has an allocatable (or a m = 100 ; n = 200


pointer) attribute, and memory is allocated through
allocate( idx(0:m1) , stat = alloc_stat )
the allocate statement if (alloc_stat /= 0) stop ! an error
2. Array variable, which is declared in the procedure with
allocate( mat(m, n) , stat = alloc_stat )
(runtime) size information coming from the procedures if (alloc_stat /= 0) stop ! an error
argument list or from a Fortran module, is called an
automatic array: no allocate is needed deallocate(idx , mat)

58 59
Dynamic memory allocation: example Array intrinsic functions
subroutine sub (m) When automatic arrays Array intrinsic functions are built-in functions which can
use some_module, only : n
integer, intent(in) :: m are being used, no explicit apply various operations on the whole array at once
integer :: idx(0:m1)
allocate or As a result another array or just a scalar value is returned
real :: mat(m , n) deallocate is needed
! implementation omitted A subset selection through masking is also possible
end subroutine sub
Operations are performed for those elements where
corresponding elements of the mask are .true.
Masking and use of array (intrinsic) functions is often
accompanied with use of forall and where array
statements

60 61

Array intrinsic functions:


Array intrinsic functions
size, shape, count, sum
The most commonly used array intrinsic functions are: size(array [, dim]) returns # of elements in the
size, shape, count, sum array [, along the specified dimension]
any, all shape(array) returns an integer vector containing the
minval, maxval , minloc, maxloc size of array in each dimension
reshape count(l_array [,dim]) returns count of elements
dot_product, matmul, transpose which are .true. in l_array
pack, unpack, spread sum(array[, dim][, mask]) sum of the elements of
array [, along dimension] [, under mask]

62 63
Array intrinsic functions:
Array intrinsic functions: any, all
minval, maxval, minloc, maxloc
any(l_array [, dim]) returns a scalar value of minval(array [,dim] [, mask]) returns the
.true. if any value in l_array is .true. minimum value of a given array
[, along the specified dimension] and [, under mask]
all(l_array [, dim]) returns a scalar value of maxval is the same as minval, but returns the maximum
.true. if all values in l_array are .true. value of a given array
minloc(array [, mask]) returns a vector of location(s)
[, under mask], where the minimum value(s) is/are
found
maxloc similar to minloc, but for maximums

64 65

Array intrinsic functions: example Array intrinsic functions: reshape


integer :: j
integer, parameter :: m = 10, n = 20 reshape(array, shape) returns a reconstructed (=a
real :: x(m,n), v(n) copy of an) array with different shape than in the
call random_number(x) input array
print *, size(x), size(v) ! prints m * n, n can be used as a single line statement to initialize an array
print *, shape(x) ! prints m, n
print *, size(shape(x)) ! prints 2 (sometimes at the expense of readability)
print *, count(x >= 0)
print *, sum(x, dim=2, mask=x < 0.5) ! the result is a vector
integer :: a(6), b(3,2), i
v(1:n) = [ (j, j=1,n) ] a = [(i, i=1,6)]
print *, any(v > -1 .and. v < 1)
print *, all(x >= 0, dim=1) b = reshape(a, [3,2])
print *, minval(v), maxval(v)
print *, minloc(v), maxloc(v)

66 67
Array intrinsic functions: Array intrinsic functions: example
dot_product, matmul, transpose
dot_product(a_vec, b_vec) returns a scalar dot integer :: l, m, n
real :: a(l,m), b(m,n), c(l,n)
product of two vectors real :: a_tr(m,l)
real :: v1(n), v2(n), dotp
matmul(a_mat, b_mat) returns a matrix containing
matrix multiply of two matrices ! transpose a matrix
a_tr = transpose(a)
transpose(a_mat) returns a transposed matrix of the ! compute matrix-matrix product c=a*b
input matrix c = matmul(a, b)
! compute dot product (v1,v2)=v2^t*v1
dotp = dot_product(v1, v2)

68 69

Array intrinsic functions Array intrinsic functions: example

Array control statements forall and where are integer :: j, ix(10000) integer :: j
... real :: a(100,100), b(100), c(100)
commonly used in the context of manipulating arrays where (ix < 0)
forall and where can provide masked assignment of ... ! fill in diagonal elements
elsewhere forall (j=1:100) a(j,j) = b(j)
values using efficient vector operations ...
end where ! fill in lower bi-diagonal matrix
forall (j=2:100) a(j,j-1) = c(j)

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
Pointer variables are usually employed to refer to another Initialized to point to nothing
integer, pointer :: p_x(:) => null()
array or an array section integer, target :: x(1000)
...
A pointer variable can also be a sole dynamic variable p_x => x Pointers provide a neat way for array
itself p_x => x(2 : 300) sections
p_x => x(1 : 1000 : 5)
Not recommended; use the allocatable attribute ...
instead and employ pointer variables for aliasing only p_x(1) = 0
This would also change x(1) to 0
nullify(p_x)
Note for C programmers: a "pointer" has a different
meaning in C and Fortran Disconnects p_x from x

72 73

Pointers to arrays Summary


real, pointer :: p_mat(: ,:) => null() associated function can Array intrinsic functions further simplify coding efforts
real, target :: mat(100,200)
be used to check whether and improve program code readability when using
p_mat => mat a pointer is associated Fortran arrays
if ( associated (p_mat) ) &
print *, 'points to something' 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
write (*,'(i3,2x,f6.3)') i, x ! 2 spaces between i & x integer :: i = 12345
write (*,'(i5,t2,i5)') i, j ! 2 tabs between i & j real (kind=4) :: sp = 1.23e0
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

exist does file exist? (logical) ! check the existence of a file


opened is file / unit opened? (logical) logical :: file_exist
form 'formatted' or 'unformatted' (char) inquire(file='foo.dat', exist=file_exist)
access 'sequential' or 'direct' or 'stream' (char) if (.not. file_exist) then
write(*,*) 'the file does not exist'
action 'read', 'write', 'readwrite' (char)
else
recl record length (integer)
! do something with the file foo.dat
size file size in bytes (integer)
endif

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
Note: 'fmt' is applicable to formatted, text files only number 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
Built-in data types in Fortran

Fortran supports a wide variety of fundamental data


types to represent integers, floating point numbers (real),
truth values (logical) and variable length character strings
Each of these built-in types may be declared as multi-
dimensional arrays
The numerical precision of reals and integers can be
controlled through the kind parameter, e.g.
Derived data types use iso_fortran_env, only : REAL64, INT16
...
real(kind=REAL64) :: double_precision_number
integer(kind=INT16) :: short_integer_number

99 100

What is a derived data type? What is a derived data type?

Derived data type is a data structure composed of built- For real-world applications, using only intrinsic types is
in data types and possibly other derived data types often insufficient
Equivalent to structs in C programming language It is beneficial to group the data together as larger
Derived type is defined in the variable declaration section objects
of programming unit Code becomes easier to read and maintain
Not visible to other programming units Cleaner interfaces
Unless defined in a module and used via the use clause, Encapsulation of data
which is most often the preferred way Variables used in the same context should be grouped
together, using modules and derived data types

101 102
Derived type declaration Derived type declaration

Type declaration Data type initialization


type particletype water(1) = particletype(0.75, 0.19, 0.0, 1)
real :: x water(2) = particletype(0.0, -0.38, 0.0, 8)
real :: y water(3) = particletype(-0.75, 0.19, 0.0, 1)
real :: z ...
integer :: charge ! or elementwise
end type particletype water(1) % x = 0.75
water(1) % y = 0.19
water(1) % z = 0.0
Declaring a variable with the type declaration ...
type(particletype) :: proton, water(300)

103 104

Nested derived types Data structures: memory layout

Derived types can contain other derived types as Array of Structures Structure of Arrays
components type point type point
type moleculetype real :: x, y, z real, allocatable :: x(:)
type(particletype), allocatable :: atoms(:) end type point real, allocatable :: y(:)
real :: mu real, allocatable :: z(:)
type(point), allocatable :: points
end type moleculetype end type point
... ...
type(point) :: points
type solvent allocate(points(N))
...
type(moleculetype), allocatable :: fluid(:) ...
complex :: epsilon allocate(points%x(N), &
points%y(N),&
end type solvent
points%z(N))
Access as
beverage % fluid(1) % atoms(1) % x = 0.75

105 106
Data structures: memory layout Summary

Array of Structures Structure of Arrays Derived data types enables grouping of data to form
integer :: i, j integer :: i, j
logical objects
real :: dist(4,4) real :: dist(4,4)
do i = 1, 4 do i = 1, 4 A Fortran program becomes more readable and modular
do j = i, 4 do j = i, 4
dist(i,j) = sqrt( & dist(i,j) = sqrt( & with sensible use of derived data types
(points(i)%x-points(j)%x)**2 + (points%x(i)-points%x(j))**2 +
(points(i)%y-points(j)%y)**2 + (points%y(i)-points%y(j))**2 + Handling of complex data structures such as linked lists
(points(i)%z-points(j)%z)**2) (points%z(i)-points%z(j))**2)
end do end do or binary trees becomes more manageable with use of
end do Memory layout end do Memory layout
derived types
0 0
Enables the use of object oriented programming
concepts
points(i)%x points(i)%y points(i)%z points%x(:) points%y(:) points%z(:)

107 108
Outline

Generic procedures
Command line arguments
Environment variables
Executing commands

Useful new features

109 110

Generic procedures Generic procedures example

Procedures which perform similar actions but for MODULE swapmod PROGRAM switch
IMPLICIT NONE
different data types can be defined as generic INTERFACE swap
USE swapmod
IMPLICIT NONE
procedures MODULE PROCEDURE swap_real, swap_char CHARACTER :: n,s
END INTERFACE REAL :: x,y
Procedures are called using the generic name and CONTAINS
SUBROUTINE swap_real(a, b)
n = 'J'
s = 'S'
compiler uses the correct procedure based on the REAL, INTENT(INOUT) :: a, b x=10
REAL :: temp y=20
argument number, type and dimensions temp = a; a = b; b = temp PRINT *,x,y
END SUBROUTINE PRINT *,n,s
Compare with overloading in C++ SUBROUTINE swap_char(a, b) CALL swap(n,s)
CHARACTER, INTENT(INOUT) :: a, b CALL swap(x,y)
Generic name is defined in INTERFACE section CHARACTER :: temp PRINT *,x,y
temp = a; a = b; b = temp PRINT *,n,s
END SUBROUTINE END PROGRAM
END MODULE swapmod

111 112
Overloading operators Operator overloading example

Procedures can also be assigned to operators MODULE operator_demo PROGRAM switch


IMPLICIT NONE USE operator_demo
For example *, +, -, ==, <, > TYPE pair IMPLICIT NONE
REAL :: a, b TYPE(pair) :: p1, p2
Own operator names can be used too, for example .dot. END TYPE
INTERFACE operator (<) p1%a = 1.0; p1%b = 2.0
Can improve code readability MODULE PROCEDURE is_smaller p2%a = 3.0; p2%b = 4.0
END INTERFACE
Overuse can have opposite effect! CONTAINS IF (p1 < p2) THEN
LOGICAL FUNCTION is_smaller(x, y) PRINT *, p1 is smaller
Useful with user-defined datatypes TYPE(pair), INTENT(INOUT) :: x, y ELSE
IF (x%a < y%a .and. x%b < y%b) THEN PRINT *, p1 not smaller
is_smaller = .true. END
ELSE
is_smaller = .false. END PROGRAM
END IF
END SUBROUTINE
END MODULE swapmod
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 Summary
program execcommand
implicit none Generic procedures
integer :: estat, cstat Same procedure name for multiple argument types
Operator overloading
! execute a unix command
call execute_command_line('ls -al', .true., estat, cstat) Can use operators for user-defined types
if (estat==0) write (*,'(a)') 'command completed successfully Reading command line arguments and environment variables
end program execcommand
Executing system commands

125 126

You might also like