0% found this document useful (0 votes)
16 views37 pages

IntroFortran Handout

Fortran is a programming language well-suited for numerical computations. It has been widely used for over 50 years to write scientific applications, where over 50% of such applications are estimated to be written in Fortran. Fortran code can be optimized well by compilers to produce fast executing code. It provides handy built-in support for array data types and numerical libraries. The latest standard is Fortran 2008, with most compiler support being for Fortran 95/2003. Key aspects of the Fortran language include declaring variables and built-in data types, using control structures like branches and loops, and compiling/linking source code files into an executable program.

Uploaded by

sridevi10mas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views37 pages

IntroFortran Handout

Fortran is a programming language well-suited for numerical computations. It has been widely used for over 50 years to write scientific applications, where over 50% of such applications are estimated to be written in Fortran. Fortran code can be optimized well by compilers to produce fast executing code. It provides handy built-in support for array data types and numerical libraries. The latest standard is Fortran 2008, with most compiler support being for Fortran 95/2003. Key aspects of the Fortran language include declaring variables and built-in data types, using control structures like branches and loops, and compiling/linking source code files into an executable program.

Uploaded by

sridevi10mas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

Outline

Fortran as a language
– look and feel
– from code to program
Variables and operators
– declare, assign
– arrays

Getting started with Fortran Control structures


– branches
– loops

1 2

Why learn Fortran?

Well suited for numerical computations


– Likely over 50% of scientific applications are written in
Fortran
FORTRAN AS A LANGUAGE Fast code (compilers can optimize well)
Handy array data types
Clarity of code
Portability of code
Optimized numerical libraries available

3 4
Short history of Fortran Short history of Fortran

John W. Backus et al (1954): The IBM Mathematical Fortran 2003 (2004): a major revision, adding e.g. object-
Formula Translating System oriented features, C-bindings
Early years development: Fortran II (1958), Fortran IV – ”Fortran 95/2003” is the current de facto standard
(1961), Fortran 66 & Basic Fortran (1966) The latest standard is Fortran 2008 (2010): a minor
Fortran 77 (1978) revision
Fortran 90 (1991) a major revision and Fortran 95 (1997) – Most notable addition: Fortran coarray syntax
a minor revision to it – Compiler support nearly complete
– The next revision: Fortran 2015

5 6

Compiling and linking Transition from code to a program

source code Compile and link in one go, execute the binary
(.f, .F, .f90, .F90) gfortran main.f90 -o foo
./foo
INCLUDE
files compiler output
In more complex cases (multiple sources)
compiler
(optional) – Compile each source code file (.f90) into an object file (.o)
modules
object code gfortran -c main.f90
gfortran -c sub.f90
(.o, .so)
– Link object files into a binary and execute the binary
libraries linker output gfortran -o foo main.o sub.o
linker
(.a, .so) (optional) ./foo

# after some modifications in “sub.f90”


executable gfortran –c sub.f90
gfortran -o foo main.o sub.o
./foo
7 8
Look and feel Source code remarks
program square_root_example
! comments start with an exclamation point.
Free format source code, but
! you will find data type declarations, couple arithmetic operations – A variable name can be no longer than 31 characters containing
! and an interface that will ask a value for these computations.
implicit none only letters, digits or underscore, and must start with a letter
real :: x, y
intrinsic sqrt ! fortran standard provides many commonly used functions – Maximum row length is 132 characters
! command line interface. ask a number and read it in
No distinction between lower and uppercase characters
write (*,*) 'give a value (number) for x:' – Character strings are case sensitive
read (*,*) x
Line break is the statement separator
y = x**2+1 ! power function and addition arithmetic
– If a line is ended with an ampersand (&), the line continues onto
write (*,*) 'given value for x:', x the next line (max. 39 continuation lines allowed)
write (*,*) 'computed value of x**2 + 1:', y
! print the square root of the argument y to screen – Semicolon (;) is the separator between statements on a single
write (*,*) 'computed value of sqrt(x**2 + 1):', sqrt(y)
end program square_root_example line
9 10

Variables
Variables must be declared at the
integer :: n0
beginning of the program or
procedure where they are used
real :: a, b
real :: r1=0.0 the intrinsic data types in Fortran are
VARIABLES complex :: c
integer, real, complex, character and
logical
complex :: imag_number=(0.1, 1.0)
They can also be given a value at
character(len=80) :: place
declaration (not recommended)
character(len=80) :: name='james bond'

logical :: test0 = .true. Constants are defined with the


logical :: test1 = .false. PARAMETER clause – they cannot be
altered after their declaration
real, parameter :: pi=3.14159

11 12
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)
x = x*real(i) !multiplication and type change precedence: second real :: vector(0:n-1) By default, Fortran indexing starts
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

13 14

Conditionals (if-else)

Conditionals allow the program to execute different code


based on some condition(s)
if (condition) then
CONTROL STRUCTURES ! do something
else if (condition2) then
! .. or maybe alternative something else
else
! .. or at least this
end fi

Condition can be anything from a simple comparison to a


complex combination using logical operators

15 16
Conditionals example Loops
2
program placetest
implicit none Three loop formats available in Fortran
1
logical :: in_square1, in_square2
real :: x, y
– integer counter (fixed number of iterations)
write(*,*) ’give point coordinates x and y’ – condition controlled (do until condition is false)
read (*,*) x, y
in_square1 = (x >= 0. .and. x <= 2. .and. y >= 0. .and. y <= 2.) – explicit exit statement
in_square2 = (x >= 1. .and. x <= 3. .and. y >= 1. .and. y <= 3.)
if (in_square1 .and. in_square2) then ! inside both
write(*,*) ’point within both squares’ do {control clause}
else if (in_square1) then ! inside square 1 only ! execute something again and again until stopped
write(*,*) ’point inside square 1’ end do
else if (in_square2) then ! inside square 2 only
write(*,*) ’point inside square 2’ ! where the control clause (optional) is either of the form
else ! both are .false. ! i=init_value, max_value, increment
write(*,*) ’point outside both squares’ ! or a condition to execute while true
end if ! while (condition)
end program placetest
17 18

Loops example Loops example


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 ! instead 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

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

Summary

Fortran is – despite its long history – a modern


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

23
Outline

Structured programming
Modules
Procedures: functions and subroutines
Interfaces

Procedures and modules

24 25

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
26 27
What are procedures? Procedure declarations

Procedure is block of code that can be called from other Subroutine Function
code.
Declaration: Declaration:
Calling code passes data to procedure via arguments
subroutine sub(arg1, arg2,...) [type] function func(arg1,
Fortran has two types of procedures: arg2,...) [result(val)]
[declarations]
subroutines and functions [statements] [declarations]
[statements]
Subroutines pass data back via arguments end subroutine sub
call mySubroutine(arg1_in, arg2_in, arg_out) end function func

Functions return a value


Use as Use as
value = myFunction(arg1, arg2)
call sub(arg1, arg2,...) res = func(arg1, arg2,...)

28 29

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 – Only the memory addresses of the arguments are passed
d = sqrt(x**2 + y**2) dist = sqrt(x**2 + y**2)
end subroutine dist end function dist
to the called procedure
– Any change to the value of an argument changes the value
program do_something program do_something
... ... at the calling program
call dist(x, y, r) r = dist(x, y)
... ... – The INTENT keyword can be used to specify how
argument is used

30 31
INTENT keyword Local variables in procedures
subroutine foo(x, y, z) Declares how formal argument Local variables can be declared in the procedure
implicit none
is intended to be used for subroutine foo(x, y)
real, intent(in) :: x
real, intent(inout) :: y transferring a value implicit none
real, intent(out) :: z – IN: the value of the real, intent(in) :: x
real, intent(out) :: y
argument is read-only i.e.
x = 10 ! compilation error
y = 10 ! correct cannot be changed integer :: i ! Local variable
z = y * x ! correct – OUT: the value of the ...
end subroutine foo
argument must be provided
Local variables are not visible outside the procedure
– INOUT (the default)
Compiler uses INTENT for error By default, local variables do not retain their values
checking and optimization through successive calls of the procedure
Improves readability of code

32 33

Local variables in procedures Should I use subroutine or function?


If local variable is given SAVE attribute, its value is Main difference is that functions can be used in
retained through successive calls expressions:
Initialization in declaration is done only in the first call to r = dist(x1, y1) + dist(x2, y2)
procedure, and implicit SAVE is applied Recommendation as good programming practice:
subroutine foo1(x) subroutine foo2(x) – Use functions for computing value based on input
… …
integer :: i integer :: i = 0 – Use subroutines for performing operation that changes
i = 0 i = i + 1
i = i + 1 some of the inputs

In foo1 variable i starts always from 0 and gets value 1


In foo2 variable i gets values 1, 2, 3, … in each successive
call
34 35
Procedure types

There are four procedure types in Fortran 90: intrinsic,


external, internal and module procedures
Procedure types differ in
PROCEDURE TYPES, MODULES – Scoping, i.e. what data and other procedures a procedure
can access
– Interface type, explicit or implicit
Compiler can check the argument types of the at compile
time only if the interface is explicit!

36 37

Implicit and explicit 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

38 39
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

40 41

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 unit’s variables and objects are accessible
– Parent unit’s 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
Can be called only from declaring program unit j = 0 ! Variable j has local scope
END SUBROUTINE child
Often used for ”small and local, convenience” procedures
END SUBROUTINE parent

42 43
External procedures Interfaces

Declared in a separate program unit For external procedures, interfaces determine the type
– Referred to with the EXTERNAL keyword and properties of arguments and return values
– Compiled separately and linked to the final executable Defined by an INTERFACE block:
Avoid using them within a program, module procedures interface
provide much better compile time error checking interface-body
External procedures are often needed when using end interface
– procedures written with different programming language The interface-body matches the subprogram header
– library routines (e.g. BLAS and LAPACK libraries) – position, rank and type of arguments
– old F77 subroutines – return value type and rank (for functions)

44 45

Interfaces Interfaces: example


INTERFACE ! LU decomposition from LAPACK
SUBROUTINE not_dangerous(a, b, c)
Wrong calling arguments INTERFACE
INTEGER :: a, b, c to EXTERNAL procedures SUBROUTINE DGETRF(M, N, A, LDA, IPIV, INFO)
END SUBROUTINE not_dangerous INTEGER :: INFO, LDA, M, N
END INTERFACE
may lead to errors during INTEGER:: IPIV(*)
the executable linking DOUBLE PRECISION :: A(LDA,*)
INTEGER :: x, y, z END SUBROUTINE DGETRF
x=1; y=1; z=1
phase or even when the END INTERFACE
! Call external subroutine without executable is being run ! Euclidean norm from BLAS
! an interface INTERFACE
call dangerous(x,y,z) It is highly recommended FUNCTION DNRM2(N, X, INCX)
INTEGER :: N, INCX
! Call external subroutine with to construct INTERFACE DOUBLE PRECISION :: X(*)
! an interface
call not_dangerous(x,y,z) blocks for any external DOUBLE PRECISION :: DNRM2
END FUNCTION DNRM2
procedures used END INTERFACE

46 47
Global data and global variables Summary

Global variables can be accessed from any program unit Procedural programming makes the code more readable
Module variables with SAVE attribute provide and easier to develop
controllable way to define and use global variables – Procedures encapsulate some piece of work that makes
MODULE commons sense and may be worth re-using elsewhere
INTEGER, PARAMETER :: r = 0.42
INTEGER, SAVE :: n, ntot Fortran uses functions and subroutines
REAL, SAVE :: abstol, reltol
END MODULE commons – Values of procedure arguments may be changed upon
– Explicit interface: type checking, limited scope calling the procedure
Generally, use of global variables is not recommended Fortran modules are used for modular programming and
data encapsulation

48 49
Outline

Introduction to Fortran arrays


Array declaration and syntax
Array initialization
Array sections

Fortran arrays

50 51

Introduction to Fortran arrays Array declaration


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

declaration
INTEGER, DIMENSION(M) :: idx
– Fortran supports up to 15 dimensions 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

52 53
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
! 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

54 55

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

56 57
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(i–1:i+1,j–2:j+2) = k

! access a subcube of a 3D array


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

58 59

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

60 61
Summary

Arrays make Fortran a very versatile programming


language for computationally intensive program
development
Using array syntax, vectors and matrices can be initialized
and used in a very intuitive way
– perfect for scientific computing!
Use of array sections increase code readability and often
reduce the chance for mistakes

62
Outline

Dynamic memory allocation


Array intrinsic functions
Fortran pointer attribute

More about Fortran arrays

63 64

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:m–1) , 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 procedure’s 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)

65 66
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:m–1)
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

67 68

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]

69 70
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

71 72

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)

73 74
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)

75 76

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)

77 78
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

79 80

Pointers to arrays Array arguments to procedures


real, pointer :: p_mat(: ,:) => null() associated function can Two (three) ways to pass arrays to procedures
real, target :: mat(100,200)
be used to check whether – Explicit shape array (dimensions passed explicitly, F77-style)
p_mat => mat a pointer is associated subroutine foo(size1, size2, ..., matrix, ...)
if ( associated (p_mat) ) & implicit none
print *, 'points to something' with a target integer :: size1, size2
nullify(p_mat)
– Returns .true. if real, dimension(size1, size2) :: matrix
if (.not. associated (p_mat) ) & associated with a target, ...
print *, 'points to nothing' .false. if not – Assumed shape array (requires explicit interface)
– For an uninitialized subroutine foo(matrix)
pointer variables, the real, dimension(:,:) :: matrix
return value is undefined  One can use the intrinsic function SIZE for checking the
actual dimensions

81 82
Summary

Array intrinsic functions further simplify coding efforts


and improve program code readability when using
Fortran arrays
Dynamic memory allocation enables sizing of arrays
according to particular needs
Pointers offer a versatile alias mechanism to refer into
the existing arrays or array sections

83
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

84 85

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

86 87
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 and whitespace:
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
real (kind=4) :: sp = 1.23e0
It is possible that an edit descriptor will be repeated a real (kind=8) :: dp = 1.234567890d0
specified number of times write(*,fmt='("<i=",i0,", reals=",2(g0,1x),">")') i,sp,dp
write (*,'(5i8)') ivec(1:5) Output is <i=12345, reals=1.230000 1.234567890000000 >
write (*,'(4(i5,2x,f8.3))') (ivec(j),zvec(j),j=1,4)

88 89

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

90 91
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

92 93

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

94 95
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'

96 97

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

98 99
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

100 101

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
102 103
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
104 105

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

106
Built-in data types in Fortran

Fortran has built-in data types for 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

107 108

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

109 110
Derived type declaration Derived type declaration

Type declaration Data type initialization


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

111 112

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

113 114
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(:)

115 116
Outline

Generic procedures
Command line arguments
Environment variables
Executing commands

Useful features

117 118

Generic procedures Generic procedures example

Procedures which perform similar actions but for MODULE swapmod PROGRAM switch
IMPLICIT NONE USE swapmod
different data types can be defined as generic INTERFACE swap 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 n = 'J'
SUBROUTINE swap_real(a, b) 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

119 120
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
121 122

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)
123 124
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

125 126

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)

127 128
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)
129 130

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)
131 132
Executing commands: example Summary
program execcommand Generic procedures
implicit none
integer :: estat, cstat
– Same procedure name for multiple argument types
Operator overloading
! execute a unix command
– Can use operators for user-defined types
call execute_command_line('ls -al', .true., estat, cstat)
if (estat==0) write (*,'(a)') 'command completed successfully’ Reading command line arguments and environment
end program execcommand variables
Executing system commands

133 134

You might also like