memo for fortran commands
After a few days of Fortran programming, I found a record of commonly used Fortran commands need to be kept, as there are subtle differences between Fortran and other languages I have used in the past.
Terminal Commands
Simple compilation
gfortran my_program.f90 -o my_program
Compiling only
gfortran -c my_program.f90
Multi-thread compilation
caf my_program.f90 -o my_program
Multi-thread execution
cafrun -n x ./my_program
where x is the number of images
note
$!can be used to speed up command typing
Fortran commands
Variable initialization
Declaration statement
single variable declaration
data_type :: variable_name
Array declaration
data_type :: array_name(n)
data_type, dimension(n) :: array_name
Finally don’t need to indexing with (y, x) lol
Dynamic array declaration
data_type, allocatable :: array_name(:)
Coarray declaration
data_type :: array_name(n)[*]
Constant declaration
data_type, parameter :: const_name = xxx
Allocation and Initialization of array
Array initialization
a = [(0, i = 1, 1000)]
Dynamic array allocation
integer :: is = -5, ie = 10
allocate(a(is:ie))
mold—A variable or an expression that has the same type as the object being allocated
real, allocatable :: a(:), b(:)
allocate(b(10:20))
allocate(a, mold=b)
a = 0
source—Equivalent to mold, except that the values of source are used to initial- ize the object being allocated
real, allocatable :: a(:), b(:)
b = [1.0, 2.0, 3.0]
allocate(a, source=b)
note If you assign an array to an allocatable array variable, the target array variable is auto-matically allocated with the correct size to match the array on the right side. The array variable can be already allocated or not.
clean use array after use
deallocate(a)
check a array is allocated or not
allocated(a)
Catching allocation
allocate(u(im), stat=stat, errmsg=err)
stat—An integer that indicates the status of the allocate statement. stat will be zero if allocation was successful; otherwise, it will be a nonzero positive number. errmsg—A character string that contains the error message if an error occurred (such as stat being nonzero) and is undefined otherwise.
Variable type
integer :: i, n
real :: x
complex :: c = (a, b)
note
- a constant can be used to initialize other variables
- constant’s value must be provided on initialization
specific kind of variable
use iso_fortran_env
integer(kind = int32) :: n
Control flow statements
if statement
if (condition) !...
if (condition) then
!...
end if
if (condition) then
!...
else if (other_condition) then
!...
end if
do loop
do n = start, end
!...
end do
do n = start, end, increment
!...
end do
!named loop
outer_loop: do j = 1, jm
inner_loop: do i = 1, im
!...
end do inner_loop
end do outer_loop
Fortran program units
program: the only unit can be invoked as an executable from the operating system
program xxx
implicit none
integer :: a, b !declaration of variables
if a == 1 call add(a, b) !invoke a subroutine
end program
function: Invoked in expressions, return only one value.
function sum(a,b)
integer, intent(in) :: a, b
integer :: sum
sum = a + b
end function sum
OR
integer function sum(a,b)
integer, intent(in) :: a, b
! no need to define sum
sum = a + b
end function sum
OR
integer function sum(a,b) results(res)
integer, intent(in) :: a,b
res = a+b
end function sum
subroutine: Invoked with a call statement.
subroutine add(a,b)
integer, intent(inout) :: a
integer, intent(in) :: b
a = a+b
print *, 'a=', a
end subroutine add
Attributes
pure : indicate the function has no side effects. This includes modifying the value of a variable declared outside the procedure.
elemental : allows receiving array arguments in place of scalars
pure elemental integer function sum(a,b)
integer, intent(in) :: a, b
sum = a+b
end function sum
sum([1,2], 3) ! is valid
sum([1,2], [3,4]) ! is valid
sum([1,2,3], [4,5]) ! is not valid as arrays are not of the same shape.
optional argument
subroutine add(a, b, res, debug)
integer, intent(in) :: a, b
integer, intent(out) :: res
logical, intent(in), optional :: debug
if (present(debug)) then
if (debug) then
!...
end if
end if
res = a + b
end subroutine add
modules
import module
use iso_fortran_env, only: int32, real32
rename entity when import
use mod_atmosphere, only: temperature
use mod_ocean, only: temperature_ocean => temperature, velocity_ocean => velocity
=> means point to
Module variable
module mod_circle
implicit none
private :: pi
real, parameter :: pi = 3.14159265
contains
!...
end module mod_circle
Parallel programming commands
Parallel programming image indexing
get current image number
this_image()
get total image number
num_images()
wait and sync
sync all
Coarray initialization
scalar coarray
real :: a[*]
array coarray
real :: a(10)[*]
dynamic coarray
real, allocable :: a(:)[:]
Coarray operation
assign value to coarray
a = 3.14 !assign value to local image
a[2] = 3.14 !assign value to indexed image
Parallel programming flow statements
embarrassingly parallel iteration
do concurrent (i = 1:grid_size)
!...
end do