Fortran90/95 Programming

advertisement
April 13, 2015
Fortran 90/95 Programming
Victor Anisimov, NCSA
FIU / SSERCA / XSEDE Workshop, Apr 4-5, 2013, Miami, FL
Few facts about Fortran
• Fortran is a modern powerful programming
language for scientific applications
• Fortran standard is actively evolving yet
maintaining unbeatable backward compatibility and
portability
• Fortran code is easy to read
• Fortran compiler produces the most optimized
binary code
• Fortran offers specific language constructs for
scientific computations which are not available in
other languages
Fortran 90 / 95 Programming
2
Fortran Compiler Efficiency
! compute vector product a(m,n) = b(m,n) * c(m,n)
a=b*c
! FORTRAN-90 code has one line
index = 0;
/* C code requires four lines */
for ( i=1; i<=m*n; i++ ) {
index++;
a(index) = b(index) * c(index);
}
Fortran 90 / 95 Programming
3
Fortran basics
• Compilers: gfortran, pgf90, ifort, crayftn, etc.
• File extensions: .f .F .f90 .F90
• lower case (.f .f90) no preprocessor will be invoked
• upper case (.F .F90) preprocessor will be invoked
• without number (.f .F) used with old F77 standard
• with number (.f90 .F90) to stress on F90 standard
• Fortran-90 compiler is fully backward compatible and allows
mixing of different standards in the code
• Recommended extension .F90
gfortran -c prog.F90
! Compiling produces object prog.o
gfortran -o prog.x prog.o ! Linking produced binary prog.x
Fortran 90 / 95 Programming
4
Fortran Program Structure
program program-name
implicit none
[declaration part]
[execution part]
end program program-name
! only one main program is defined
subroutine subroutine-name
! contains commonly executed pieces of code
implicit none
[declaration part]
[execution part]
end subroutine subroutine-name
Integer function function-name
implicit none
[declaration part]
[execution part]
end function function-name
! same as subroutine but used differently
Fortran 90 / 95 Programming
5
Fortran Data Type Operators
•
•
•
•
fortran language is case-insensitive
combine lower and upper case to improve readability
please use meaningful variable names
type declaration operators do not zero-initialize the variables
integer
:: counter
double precision :: pi=3.14159265358d0
character (len=80) :: string
integer, parameter:: nRows=5, nColumns=6
real
:: array(nRows,nColumns)
logical
:: completedSuccessfully = .False.
double complex :: phase = (4.0d0, 3.4d0)
Tip:
Unintialized variable contains machine garbage
Fortran 90 / 95 Programming
6
Passing Arguments to / from Procedures
a = function-name()
! By return value
Subroutines and Functions have a special mechanism to declare argument intent
subroutine subroutine-name ( arg1, arg2, arg3 )
implicit none
integer, intent (in)
:: arg1 ! Argument is read-only
double precision, intent(out)
:: arg2 ! Placeholder for return value
character (len=80), intent(inout) :: arg3 ! Argument is for reading and writing
[execution part]
end subroutine subroutine-name
Purpose:
• Clarity
• Protection against programming bugs
Presentation Title
7
Fortran Modules
Modules are Data and Function (subroutine) placeholders
we will design module loan (loan.F90)
module module-name
! Define data scope
implicit none
character (len=80), private :: string ! Local variable accessible within this module only
double precision, public
:: currentBalance
public :: Interest, Payment
contains
double precision function Interest()
! can be called from outside the module
end function Interest
double precision function Payment()
end function Payment
! can be called from outside the module
double precision function RoundToCents( amount )
end function RoundToCents
end module module-name
! Not visible from outside
Fortran 90 / 95 Programming
8
Fortran Modules in Use
program LoanSimulator
! Use module loan defined in loan.F90; note the use of variables and functions
use loan, only : currentBalance, Interest, Payment
implicit none
! .. local variables ..
integer :: month
! .. executable statement ..
! read input parameters
! execute while-loop until the loan is paid of
! in each loop iteration
! apply interest
! update balance
! determine payment amount
! apply payment
end program LoanSimulator
Fortran 90 / 95 Programming
9
Fortran Conditional Statements
if ( a > b ) then
[execution part]
elseif ( a .eq. b ) then
[execution part]
else ! a < b
[execution part]
end if
conditional operators
.lt. .le. .eq. .ne. .ge. .gt.
< <= == /= >= >
.and. .or. .not.
Example
if ( (a > b .and. b <= z) .or. .not. finishedSuccessfully ) then
[execution part]
end if
Tip: Use indentation to improve readability of the code
Fortran 90 / 95 Programming
10
Fortran DO loops
Formal definition of DO loop:
do index = indexFrom, indexTo, indexIncrement
[execution part]
end do
Example-1:
do i = 1, 10
! Loop starts from i=1; at the “end do” i=i+1; last loop i=10
[execution part]
end do
Example-2:
do i = -5, 10, 2
! Loop starts from i=-5; at the “end do” i=i+2; last loop i=9
[execution part]
end do
Example-3:
do i = 10, 1, -1
! Loop starts from i=10; at the “end do” i=i-1; last loop i=1
[execution part]
end do
Fortran 90 / 95 Programming
11
Fortran DO and WHILE loops
Example-4:
a = 5; b = 4; c = 1
do i = a, b, c
[execution part]
end do
! Attention: Loop will be skipped
Rule: Fortran checks the loop exit condition (a <= b) before starting the iteration
do while (a < b)
[execution part]
end do
do i = a, b, c
[execution part -1]
if ( x == y ) cycle
if ( m .ne. n ) exit
[execution part-2]
end do
! Loop will be continued as long as the condition is true
! If satisfied, skip part of the loop after this point
! If satisfied, exit the loop
Fortran 90 / 95 Programming
12
Fortran Arrays
program arrays
implicit none
integer, parameter
integer
double precision
double precision, allocatable
character (len=80)
:: nRows = 5, nColumns = 3
:: allocStat
:: a(nRows, nColumns) ! Static array
:: b(:,:)
! Dynamic array
:: string = “text”
allocate( b(nRows, nColumns), stat=allocStat)
! Allocate memory
if (allocStat .ne. 0) stop ‘Error in memory allocation’
! Check for allocation error
a = 1.0d0
! Assign 1.0d0 to each element of the array
b=a
! Copy array a to b
b(1,2) = 3.1d0
! Access specific array element
deallocate ( b, stat=allocStat )
! Free the memory for other uses
string(3:3) = “s”
! String is a special type of array
! continue computation and perform new cycles of allocation and deallocation, if necessary
end program arrays
Fortran 90 / 95 Programming
13
Fortran Input / Output: Files
integer, parameter :: inputUnit = 10
character (len=512) :: fname = “input.txt”
open (unit=inpUnit, file=fname, status='old', form='formatted’, access=‘sequential’)
! .. do some work on the file here ..
close (inpUnit)
unit - can be any number except system reserved ones; number >= 10 should be fine
status - ‘old’
requires existing file fname, otherwise error
‘new’
new file will be created
‘unknown’
open existing file or new file will be created if one does not exist
form ‘formatted’
text file; can be ‘unformatted’ (binary file)
access - ‘sequential’
default; can be ‘direct’ (for random access)
Fortran 90 / 95 Programming
14
Fortran Input / Output: Read and Write
Synopsis:
read(unit, format) list-of-variable
write(unit, format) list-of-variables
Sample input string (for visual clarity, we use underscore to represent white space):
Hydrogen _ _1 _ _ 1.35 _ _ 2.60 _ -1.24
! _ will be used instead of white-space character
program ReadFormattedText
implicit none
character (len=20)
:: label
integer
:: index
double precision
:: x, y, z
read(*,’(a8, i3, 3f6.2)’) label, index, x, y, z
write(*,’(a8, i3, 3f6.2)’) label, index, x, y, z
end program ReadFormattedText
! Read from standard input (console)
! Write to standard input
Question: what will the result of write(*,’(a,i0)’) label, index
Fortran 90 / 95 Programming
15
Fortran: Reading Command-Line Arguments
program ReadArguments
implicit none
character (len=512)
:: prgName, string
integer
:: nArgs
double precision
:: startingBalance
nArgs = command_argument_count() ! Get the number of command-line arguments
call getarg(0, prgName) ! 0-th argument is the program name
if (nArgs < 3) then
write(*,'(a,a,a)') "Usage: ", trim(prgName), &
" startingBalance annualInterestRate minPaymentRate [fixedMinimum]"
stop
endif
call getarg(1, string)
read (string,*) startingBalance
write (*,'(/a,f10.2)') "Starting balance = $", startingBalance
end program ReadArgument
Fortran 90 / 95 Programming
16
Fortran Intrinsic Functions
Function
Example
Function
Example
Conversion to integer
int(2.3) = 2
Starting position
index(“abcd”,”cd”)=3
Rounding
nint(2.5) = 3
Remove trailing blanks
trim(“aa “) = “aa”
Absolute value
abs(-2.4) = 2.4
String length
len(“aa “) = 3
Remainder
mod(4,2) = 0
String length
len_trim(“aa “) = 2
Maximum
max(2,3) = 3
Return size of array
size(array)
Minimum
min(2,3) = 2
Minimum element
minval(array)
Conversion to double
dble(1) = 1.0d0
Maximum element
maxval(array)
Mathematical functions: sin, cos, tan, log, log10, exp, sqrt
Presentation Title
17
Exercise: Sum up Even and Odd Numbers
integer :: i, sumEven=0, sumOdd=0
! Naive implementation
do i = 1, 10
if (mod(i,2) == 0) then
sumEven = sumEven + i
else
sumOdd = sumOdd + I
endif
eddo
! High-performance implementation
do i = 1, 10
sumEven = sumEven + mod(i+1,2) * i
sumOdd = sumOdd + mod(i,2) * i
enndo
Fortran 90 / 95 Programming
18
Fortran Compiler Efficiency
Which code is faster?
do i = 1, n
a(i) = b(i+1)
c(i) = b(i+1)
end do
do i = 1, n
i1 = i+1
a(i) = b(i1)
c(i) = b(i1)
end do
The code on the left side performs one less addition. Would it help?
Fortran 90 / 95 Programming
19
Fortran Compiler Efficiency
Which code is faster?
do i = 1, n
a(i) = b(i+1)
c(i) = b(i+1)
end do
do i = 1, n
i1 = i+1
a(i) = b(i1)
c(i) = b(i1)
end do
The code on the left side performs one less addition. Would it help?
Answer: Both codes have the same speed, because fortran compiler
automatically eliminates redundant operations. But, code on the left is
easier to read. Thus, it represents the best coding practice.
Fortran 90 / 95 Programming
20
Index Computation
We are doing a(i,j) = b(i,j) * 2.0d0, but “a” is a one-dimensional array
index = 0
do j = 1, jSize
do i = 1, iSize
index = index + 1
a(index) = b(i,j) * 2.0d0
end do
end do
do j = 1, jSize
do i = 1, iSize
index = (j-1)*iSize + i
a(index) = i * j
end do
end do
Which code is better?
Fortran 90 / 95 Programming
21
Index Computation
We are doing a(i,j) = b(i,j) * 2.0d0, but “a” is a one-dimensional array
index = 0
do j = 1, jSize
do i = 1, iSize
index = index + 1
a(index) = b(i,j) * 2.0d0
end do
end do
do j = 1, jSize
do i = 1, iSize
index = (j-1)*iSize + i
a(index) = i * j
end do
end do
Which code is better?
Better for serial computation
Better for parallel computation
Fortran 90 / 95 Programming
22
Exercise: Compile Loan Simulator
ls –l
Makefile
loan.F90
main.F90
read.F90
Type in the command-line:
module add make
make
./loan.x 1000 7.2 1.0 200.0
Fortran 90 / 95 Programming
23
User Defined Data Type
type fmmcub
! Declare new data type “fmmcube”
integer
:: parent
integer
:: xyz(3)
integer
:: atomStart, nAtoms
double complex, allocatable
:: multipoleExpansion(:)
end type fmmcube
integer :: nBoxes = 8, allocStat, nSzExpansion=10
type (fmmcube), allocatable :: box(:)
fmmcube
! Declare variable box using type
! Perform two-level memory allocation
allocate(box(0:nBoxes), stat=allocStat)
do iBox = 1, nBoxes
allocate(box(iBox)%multipoleExpansion(0:nSzExpansion), stat=allocStat)
box(iBox)%multipoleExpansion = (0.0d0, 0.0d0)
enddo
Fortran 90 / 95 Programming
24
Useful Internet Resources
• Fortran 90 intrinsic functions
http://www.nsc.liu.se/~boein/f77to90/a5.html
• Fortran 90 tutorial
https://www.cac.cornell.edu/VW/Fintro/default.aspx
• More
just Goooooogle
Fortran 90 / 95 Programming
25
Let us know your opinion
http://www.bitly.com/fiuworkshop
Thank you !!!
Presentation Title
26
Download