Difference between revisions of "Programming/Fortran"

From HPC
Jump to: navigation , search
m
m (Navigation)
 
(8 intermediate revisions by the same user not shown)
Line 66: Line 66:
 
The following modules are available:
 
The following modules are available:
  
* module add gcc/4.9.3 (GNU compiler)
+
* module add gcc/8.2.0 (GNU compiler)
* module add intel/compiler/64/2016.2.181 (Intel compiler)
+
* module add intel/2018 (Intel compiler)
  
'''Note''' : It is generally accepted that the intel compiler generates faster code on Intel hardware than gcc, although gcc is generally more compatible with a wide range of hardware.
+
'''Note''': It is generally accepted that the intel compiler generates faster code on Intel hardware than GCC, although GCC is generally more compatible with a wide range of hardware.
  
 
====Design considerations====
 
====Design considerations====
  
* Array storage in Fortran is column-major. That is to say, when stored in memory as a linear array, the matrix will be arranged as . Thus, accessing the elements of column-wise is most efficient. A useful way to remember this is that in Fortran, the first index varies fastest.
+
* Array storage in Fortran is column-major. That is to say, when stored in memory as a linear array, the matrix will be arranged as. Thus, accessing the elements of column-wise is most efficient. A useful way to remember this is that in Fortran, the first index varies fastest.
  
Accessing the memory in the order in which it is stored will be faster, and also means any vectorisation optomisations can be easily performed by the compiler.
+
Accessing the memory in the order in which it is stored will be faster, and also means any vectorization optimizations can be easily performed by the compiler.
  
 
In Fortran, this means writing loops like:
 
In Fortran, this means writing loops like:
Line 87: Line 87:
 
</pre>
 
</pre>
  
This is the opposite way around to languages like C, which is row major.
+
This is the opposite way around to languages like C, which is row-major.
  
 
* When reading or writing an array, use the array name and not a DO loop or an implied DO-loop that specifies each element number. Fortran 95/90 array syntax allows you to reference a whole array by using its name in an expression.
 
* When reading or writing an array, use the array name and not a DO loop or an implied DO-loop that specifies each element number. Fortran 95/90 array syntax allows you to reference a whole array by using its name in an expression.
Line 147: Line 147:
 
</pre>
 
</pre>
  
* Go to statements are sometimes useful but they are discouraged because they are generally difficult to manage;
+
* Go-to statements are sometimes useful but they are discouraged because they are generally difficult to manage;
  
  
Line 153: Line 153:
 
====Debugging code====
 
====Debugging code====
  
There does exist a number of FORTRAN code analysis tools (static and dynamic checking), a particular useful one is FORCHECK.
+
There does exist a number of FORTRAN code analysis tools (static and dynamic checking), a particularly useful one is FORCHECK.
  
Also is camFORT a tool for cross checking variables and they computation elements within a program, this is particularly useful for high mathematical/ scientific codes.
+
Also, camFORT is a tool for cross-checking variables and their computation elements within a program, this is particularly useful for high mathematical/ scientific codes.
  
  
====Fortran Pre-Processing====
+
====Fortran pre-processing====
  
The pre-processor is a text processing tool which is usually integrated into the compiler;
+
The pre-processor is a text-processing tool that is usually integrated into the compiler;
  
 
It is a separate stage and occurs prior to compilation;
 
It is a separate stage and occurs prior to compilation;
Line 173: Line 173:
  
 
<pre style="background-color: black; color: white; border: 2px solid black; font-family: monospace, sans-serif;">
 
<pre style="background-color: black; color: white; border: 2px solid black; font-family: monospace, sans-serif;">
[username@login01 ~]$  gfortran -c - DDEBUG code.F
+
[username@login01 ~]$  gfortran -c -DDEBUG code.F
 
</pre>
 
</pre>
  
Line 181: Line 181:
  
 
<pre style="background-color: black; color: white; border: 2px solid black; font-family: monospace, sans-serif;">
 
<pre style="background-color: black; color: white; border: 2px solid black; font-family: monospace, sans-serif;">
[username@login01 ~]$  module add gcc/4.9.3
+
[username@login01 ~]$  module add gcc/8.2.0
 
[username@login01 ~]$  gfortran -o testFortran  testFortran.f03
 
[username@login01 ~]$  gfortran -o testFortran  testFortran.f03
 
</pre>
 
</pre>
  
* '''Good practice''' when compiling is to only use compiler optimization flags at the final stages towards production release, Intel's fortran compiler usually has -O2 set by default, so placing compiler flag -O0 would be necessary to turn this off.
+
* '''Good practice''' when compiling is to only use compiler optimization flags at the final stages towards production release, Intel's Fortran compiler usually has -O2 set by default, so placing compiler flag -O0 would be necessary to turn this off.
* '''Note''' : mpifort would be used as the compiler wrapper if the above example used [[Applications/OpenMPI|openMPI]].
+
* '''Note''' : mpifort would be used as the compiler wrapper if the above example is used [[Applications/OpenMPI|openMPI]].
  
 
====Documentation generators====
 
====Documentation generators====
  
Suitable automatic source code generators for fortran are [http://fortranwiki.org/fortran/show/FORD FORD] and [http://fortranwiki.org/fortran/show/Doxygen doxygen]
+
Suitable automatic source code generators for FORTRAN are [http://fortranwiki.org/fortran/show/FORD FORD] and [http://fortranwiki.org/fortran/show/Doxygen doxygen]
  
 
== Usage Examples ==
 
== Usage Examples ==
Line 208: Line 208:
 
#SBATCH -p compute
 
#SBATCH -p compute
 
#SBATCH --exclusive
 
#SBATCH --exclusive
 +
#SBATCH --mail-user= your email address here
  
 
echo $SLURM_JOB_NODELIST
 
echo $SLURM_JOB_NODELIST
  
 
module purge
 
module purge
module add gcc/4.9.3
+
module add gcc/8.2.0
  
 
export I_MPI_DEBUG=5
 
export I_MPI_DEBUG=5
Line 228: Line 229:
 
==HDF5 library==
 
==HDF5 library==
  
HDF5 is a versatile data model that can represent very complex data objects and a wide variety of metadata, which is ideal for data which has a large disparity to be stored in a standard format description. [https://en.wikipedia.org/wiki/NetCDF NetCDF] is a similar system as well.
+
HDF5 is a versatile data model that can represent very complex data objects and a wide variety of metadata, which is ideal for data that has a large disparity to be stored in a standard format description. [https://en.wikipedia.org/wiki/NetCDF NetCDF] is a similar system as well.
  
 
(''Example from the HDF group'')
 
(''Example from the HDF group'')
Line 236: Line 237:
 
PROGRAM H5_CRTDAT
 
PROGRAM H5_CRTDAT
  
   USE HDF5 ! This module contains all necessary modules
+
   USE HDF5 ! This module contains all the necessary modules
  
 
   IMPLICIT NONE
 
   IMPLICIT NONE
Line 298: Line 299:
 
</pre>
 
</pre>
  
==Further Information==
+
==Next Steps==
  
 
* [http://www.tutorialspoint.com/fortran/ http://www.tutorialspoint.com/fortran/]
 
* [http://www.tutorialspoint.com/fortran/ http://www.tutorialspoint.com/fortran/]
Line 311: Line 312:
 
* [[programming/C-Plusplus|C++ Programming]]
 
* [[programming/C-Plusplus|C++ Programming]]
 
* [[programming/Python|Python Programming]]
 
* [[programming/Python|Python Programming]]
{|
+
 
|style="width:5%; border-width: 0" | [[File:icon_home.png]]
+
{{Languagespagenav}}
|style="width:95%; border-width: 0" |
 
* [[Main_Page|Home]]
 
* [[Applications|Application support]]
 
* [[General|General]]
 
* [[Training|Training]]
 
* [[Programming|Programming support]]
 
|-
 
|}
 

Latest revision as of 11:28, 16 November 2022

Programming Details

Fortran (formerly FORTRAN, derived from Formula Translation) is a general-purpose, imperative programming language that is especially suited to numeric computation and scientific computing. The GFortran compiler is fully compliant with the Fortran 95 Standard and includes legacy F77 support. In addition, a significant number of Fortran 2003 and Fortran 2008 features are implemented. Intel's Fortran compiler (ifort) is also compliant with Fortran back to F77 and earlier to most implementations.

Icon tick.png There is direct support for openMP and openMPI.

Programming example

Non-Parallel example

program variableTesting
implicit none

   ! declaring variables
   integer :: total,average
   complex :: cx
   logical :: done
   character(len=80) :: message ! a string of 80 characters

   !assigning values
   total = 20000
   average = 1666
   done = .true.
   message = "A big Hello from HPC"

   cx = (3.0, 5.0) ! cx = 3.0 + 5.0i

        if (total .ge. average) then
                print *, total, " greater or equal than average"
        else
                print *, total, " less than average"
        endif

   Print *, average
   Print *, cx
   Print *, done
   Print *, message

end program variableTesting

Parallel example (openMP)

program helloworld
  use omp_lib
  implicit none

!$OMP PARALLEL
!$OMP CRITICAL
  print *,'Hello from thread number',OMP_GET_THREAD_NUM()
!$OMP END CRITICAL
!$OMP END PARALLEL

end program helloworld

Modules available

The following modules are available:

  • module add gcc/8.2.0 (GNU compiler)
  • module add intel/2018 (Intel compiler)

Note: It is generally accepted that the intel compiler generates faster code on Intel hardware than GCC, although GCC is generally more compatible with a wide range of hardware.

Design considerations

  • Array storage in Fortran is column-major. That is to say, when stored in memory as a linear array, the matrix will be arranged as. Thus, accessing the elements of column-wise is most efficient. A useful way to remember this is that in Fortran, the first index varies fastest.

Accessing the memory in the order in which it is stored will be faster, and also means any vectorization optimizations can be easily performed by the compiler.

In Fortran, this means writing loops like:

do j = 1, n
    do i = 1, n
        ! operate on A(i,j) ...
    end do
end do

This is the opposite way around to languages like C, which is row-major.

  • When reading or writing an array, use the array name and not a DO loop or an implied DO-loop that specifies each element number. Fortran 95/90 array syntax allows you to reference a whole array by using its name in an expression.
real ::  array(100,100)

array = 0.0

array = array + 1           ! Increment all elements
        

This is particularly true for I/O operations:

- Write Whole Arrays or Strings - Write Array Data in the Natural Storage Order - Use Memory for Intermediate Results - Enable Implied-DO Loop Collapsing

  • Use the intent keyword to indicate which variables are passed and returned within subroutines and functions, this allows for compiler optimizations.

An example is shown below:

function fun( time, x ) result(dx)
  real, intent(in) :: time
  real, intent(in),dimension(:) :: x
  real, dimension(size(x)) :: dx

    dx(1) = 0.1 * ( 1.0-x(1) ) - 0.2 * x(2)
    dx(2) = -0.05 * x(2)
end function fun
  • Be careful for incorrect mismatching of integer and real variables. An example is shown below, note how the integer division results in a rounded down result (ie 2/3 = 0, hence 2**(0) = 1 an incorrect result).
program variableTesting
   implicit none
   real :: outerror, outcorrect

   outerror  = 2**(2/3)

   outcorrect = 2**(2.0/3.0)

   Print *,"outerror = ",outerror
   Print *,"outcorrect = ",outcorrect

end program variableTesting

This produces the following erroneous and correct outputs:

[dlbird@login01 FORTRAN]$ ./a.out
 outerror =    1.00000000
 outcorrect =    1.58740103
  • Go-to statements are sometimes useful but they are discouraged because they are generally difficult to manage;


Debugging code

There does exist a number of FORTRAN code analysis tools (static and dynamic checking), a particularly useful one is FORCHECK.

Also, camFORT is a tool for cross-checking variables and their computation elements within a program, this is particularly useful for high mathematical/ scientific codes.


Fortran pre-processing

The pre-processor is a text-processing tool that is usually integrated into the compiler;

It is a separate stage and occurs prior to compilation;

#ifdef DEBUG
    print *, ‘count is’, counter
#endif

To assign the macro DEBUG, compile

[username@login01 ~]$  gfortran -c -DDEBUG code.F

Compilation

The program would be compiled in the following way, optional Intel compiler available too:

[username@login01 ~]$  module add gcc/8.2.0
[username@login01 ~]$  gfortran -o testFortran  testFortran.f03
  • Good practice when compiling is to only use compiler optimization flags at the final stages towards production release, Intel's Fortran compiler usually has -O2 set by default, so placing compiler flag -O0 would be necessary to turn this off.
  • Note : mpifort would be used as the compiler wrapper if the above example is used openMPI.

Documentation generators

Suitable automatic source code generators for FORTRAN are FORD and doxygen

Usage Examples

Batch example


#!/bin/bash

#SBATCH -J openmpi-single-node
#SBATCH -N 1
#SBATCH --ntasks-per-node 28
#SBATCH -o %N.%j.%a.out
#SBATCH -e %N.%j.%a.err
#SBATCH -p compute
#SBATCH --exclusive
#SBATCH --mail-user= your email address here

echo $SLURM_JOB_NODELIST

module purge
module add gcc/8.2.0

export I_MPI_DEBUG=5
export I_MPI_FABRICS=shm:tmi
export I_MPI_FALLBACK=no

/home/user/CODE_SAMPLES/OPENMP/demo
[username@login01 ~]$ sbatch demo.job
Submitted batch job 239552

HDF5 library

HDF5 is a versatile data model that can represent very complex data objects and a wide variety of metadata, which is ideal for data that has a large disparity to be stored in a standard format description. NetCDF is a similar system as well.

(Example from the HDF group)


PROGRAM H5_CRTDAT

  USE HDF5 ! This module contains all the necessary modules

  IMPLICIT NONE

  CHARACTER(LEN=8), PARAMETER :: filename = "dsetf.h5" ! File name
  CHARACTER(LEN=4), PARAMETER :: dsetname = "dset"     ! Dataset name

  INTEGER(HID_T) :: file_id       ! File identifier
  INTEGER(HID_T) :: dset_id       ! Dataset identifier
  INTEGER(HID_T) :: dspace_id     ! Dataspace identifier


  INTEGER(HSIZE_T), DIMENSION(2) :: dims = (/4,6/) ! Dataset dimensions
  INTEGER     ::   rank = 2                        ! Dataset rank

  INTEGER     ::   error ! Error flag

  !
  ! Initialize FORTRAN interface.
  !
  CALL h5open_f(error)

  !
  ! Create a new file using default properties.
  !
  CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error)

  !
  ! Create the dataspace.
  !
  CALL h5screate_simple_f(rank, dims, dspace_id, error)

  !
  ! Create the dataset with default properties.
  !
  CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_INTEGER, dspace_id, &
       dset_id, error)

  !
  ! End access to the dataset and release resources used by it.
  !
  CALL h5dclose_f(dset_id, error)

  !
  ! Terminate access to the data space.
  !
  CALL h5sclose_f(dspace_id, error)

  !
  ! Close the file.
  !
  CALL h5fclose_f(file_id, error)

  !
  ! Close FORTRAN interface.
  !
  CALL h5close_f(error)

END PROGRAM H5_CRTDAT

Next Steps





Languages | Main Page | Further Topics