Difference between revisions of "HowTo:fortran"

From CAC Wiki
Jump to: navigation, search
(Some Other Features)
(Fortran (Programming Language))
 
(26 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
= Fortran (Programming Language) =
 
= Fortran (Programming Language) =
  
FORTRAN, C, and C++ have a long history as the basic/main compiled languages for high performance computing. The key parallel computing packages, MPI and OpenMP, have been implemented in all of them from the beginning. While C and C++ have been extended for all programming purposes, FORTRAN originated from FORmular TRANslation, and developed with an emphasis on scientific computing. After the FORTRAN I-IV, 66, and 77 stages, the FORTRAN 90, 95, 2003, 2008, and 2015 versions have adopted many advanced features to become a true modern (object oriented) programming language, especially geared toward scientific computations. The following lists some of the most useful and prominent programming features of FORTRAN.  
+
FORTRAN, C, and C++ have a long history as the basic/main compiled languages for high performance computing. The key parallel computing packages, MPI and OpenMP, have been implemented in all of them from the beginning. While C and C++ have been extended for all programming purposes, FORTRAN, originated from FORmular TRANslation, developed with an emphasis on scientific computing. After the FORTRAN I-IV, 66, and 77 stages, the FORTRAN 90, 95, 2003, 2008, and 2015 versions have adopted many advanced features to become a true modern (object oriented) programming language, especially geared toward scientific computations. The following lists some of the most useful and prominent programming features of FORTRAN.  
  
 
{|  style="border-spacing: 8px;"
 
{|  style="border-spacing: 8px;"
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#e1eaf1; border-radius:7px" |
+
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
 
== Well Structured ==
 
== Well Structured ==
  
FORTRAN is very well structured. All routines should have a clear beginning statement, and a corresponding ending one. For example (since case-in-sensitiveness, usually written in either lower or upper case only)
+
FORTRAN is very well structured. All routines should have a clear beginning statement, and a corresponding ending one. For example (since case-in-sensitiveness, usually written in either all lower or all upper case)
  
 
<pre>
 
<pre>
 
PROGRAM MY_VERY_USEFUL_CODE
 
PROGRAM MY_VERY_USEFUL_CODE
...
+
    ...
CALL PROBLEM_SOLVING (...)
+
    CALL PROBLEM_SOLVING (...)
...
+
    ...
STOP
+
    STOP
 
END PROGRAM MY_VERY_USEFUL_CODE
 
END PROGRAM MY_VERY_USEFUL_CODE
  
 
SUBROUTINE PROBLEM_SOLVING (...)
 
SUBROUTINE PROBLEM_SOLVING (...)
...
+
    ...
RESULT = AVERAGE_SCORE (...)
+
    RESULT = AVERAGE_SCORE (...)
RETURN
+
    RETURN
 
END SUBROUTINE PROBLEM_SOLVING
 
END SUBROUTINE PROBLEM_SOLVING
  
 
FUNCTION  AVERAGE_SCORE (...)
 
FUNCTION  AVERAGE_SCORE (...)
...
+
    ...
RETURN
+
    RETURN
 
END FUNCTION AVERAGE_SCORE
 
END FUNCTION AVERAGE_SCORE
 
</pre>
 
</pre>
  
The DO loop and IF structure are also finished with an END statement.
+
Even the DO loop and IF structure are also finished with an END statement.
  
 
<pre>
 
<pre>
Line 50: Line 50:
 
== Modules ==
 
== Modules ==
  
Similar to classes in C++, modules are very important and widely-used in FORTRAN. Theoretically modules are not classes, but usually contain many objects, since in most scientific computations data structures are known and given objects. Modules can also contain specific routines operating on the objects inside, similar to the encapsulation concept of classes. Meanwhile modules are also a good method to share such objects, so that routines arguments can be reduced to necessaries only.  
+
Similar to classes in C++, modules are very important and widely-used in FORTRAN. Modules, in the form of a separate code structure, may contain various definitions/declarations and  can use other predefined modules. Theoretically modules are not classes, but usually used to provide some data structures (objects) for sharing, since in most scientific computations objects are known beforehand and the task is to manipulate them. Modules can also contain specific routines accessing the objects inside and accessible only when the module is used, similar to the encapsulation concept of classes. By using modules, the code can be written very concisely. Here is an example and its usage.
 +
<pre>
 +
MODULE MY_PARAMETERS
 +
    DOUBLE PRECISION, PARAMETER :: THE_EARTH_RADIUS = 6371.0D0
 +
END MODULE  MY_PARAMETERS
 +
 
 +
SUBROUTINE EARTH_STORY (...)
 +
    USE MY_PARAMETERS
 +
    DOUBLE PRECISION:: THE_EARTH_DIAMETER
 +
    ...
 +
    THE_EARTH_DIAMETER = 2 * THE_EARTH_RADIUS
 +
    ...
 +
    RETURN
 +
END SUBROUTINE EARTH_STORY
 +
</pre>
 +
 
 +
|}
 +
 
 +
{|  style="border-spacing: 8px;"
 +
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
  
 
== Overloading ==
 
== Overloading ==
  
As a modern language, FORTRAN also supports routine overloading.
+
As a modern language, FORTRAN also supports routine overloading: the ability to pick up the correct one from a group of routines with different unique interfaces by calling a fixed routine name. The routines are usually of the same functionality.  
  
 
<pre>
 
<pre>
Line 88: Line 107:
 
Most FORTRAN compilers have built-in data types of very high precision, like quadruple precision
 
Most FORTRAN compilers have built-in data types of very high precision, like quadruple precision
 
<pre>
 
<pre>
REAL*16 ::  VELOCITY(3,1000)
+
REAL*16   ::  VELOCITY(3,1000)
COMPLEX*32 ::  HAMILTON(1000, 1000)
+
COMPLEX*32 ::  HAMILTONIAN(1000, 1000)
 
</pre>
 
</pre>
 +
 +
|}
 +
 +
{|  style="border-spacing: 8px;"
 +
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
 +
 +
 +
== Collective Operations ==
 +
FORTRAN supports collective operations on a whole array or a section of it.
 +
<pre>
 +
REAL*16 ::  V1(3,100), V2(3,100), V3(3,100)
 +
...
 +
V1 = 0.0Q0
 +
V1(2:3, 20:50) = 0.9Q0
 +
V2 = 0.8Q0 * V3
 +
</pre>
 +
which assign all the "mentioned" elements with the corresponding values, without a need of loop(s). A pure array name means all elements.
 +
|}
 +
 +
{|  style="border-spacing: 8px;"
 +
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#e1eaf1; border-radius:7px" |
  
 
== Dynamic Memory Allocation ==
 
== Dynamic Memory Allocation ==
  
Early versions of FORTRAN had a big drawback: they did not allow for dynamic memory allocation, forcing re-compilation array sizes were changed. Newer versions of FORTRAN (since F90) support such operations even for many-dimensional arrays.  
+
Early versions of FORTRAN had a big drawback: they did not allow for dynamic memory allocation, forcing re-compilation for array sizes changed. Newer versions of FORTRAN (since F90) support such operations even for many-dimensional arrays.  
  
 
<pre>
 
<pre>
REAL*16, ALLOCATABLE :: COMPLICATED_DATA(:, :, :, :, :, :)  
+
REAL*16, ALLOCATABLE :: COMPLICATED_DATA(:, :, :, :, :, :)  
ALLOCATE(COMPLICATED_DATA(3, 90, 80, 72, 500, 28))  
+
INTEGER              :: I1=3, I2=90, I3=80, I4, I5, I6=28
 +
I4 = 24; I5 = 500
 +
ALLOCATE(COMPLICATED_DATA(I1, I2, I3, I4, I5, I6))  
 
</pre>
 
</pre>
  
Line 105: Line 147:
  
 
{|  style="border-spacing: 8px;"
 
{|  style="border-spacing: 8px;"
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#e1eaf1; border-radius:7px" |
+
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
  
 
== User Defined Data Types ==
 
== User Defined Data Types ==
Line 126: Line 168:
  
 
{|  style="border-spacing: 8px;"
 
{|  style="border-spacing: 8px;"
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
+
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#e1eaf1; border-radius:7px" |
  
 
== Some Other Features ==
 
== Some Other Features ==
Line 133: Line 175:
 
* OpenMP and OpenAcc can easier understand and parallelize FORTRAN code.
 
* OpenMP and OpenAcc can easier understand and parallelize FORTRAN code.
 
* Compilers check FORTRAN code strictly based on grammars and point out any problems they find.
 
* Compilers check FORTRAN code strictly based on grammars and point out any problems they find.
 +
|}
 +
  
 
{|  style="border-spacing: 8px;"
 
{|  style="border-spacing: 8px;"
 
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
 
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#f7f7f7; border-radius:7px" |
  
== Links and Further Redading ==
+
== Links and Further Reading ==
  
 
* [http://www.j3-fortran.org/ Fortran Standard Technical Committee]
 
* [http://www.j3-fortran.org/ Fortran Standard Technical Committee]
 
* [https://en.wikipedia.org/wiki/Fortran Fortran Wikipedia Entry] with information about History, features, and variants of Fortran.
 
* [https://en.wikipedia.org/wiki/Fortran Fortran Wikipedia Entry] with information about History, features, and variants of Fortran.
 +
* [https://en.wikipedia.org/wiki/List_of_compilers#Fortran_compilers List of Fortran Compilers.] We are operating the [https://gcc.gnu.org/ GNU] and [https://software.intel.com/en-us/intel-compilers Intel] compilers on our systems, see [[HowTo:Compilers|our compiler help file]].
 
* [https://www.amazon.ca/Fortran-90-Explained-Michael-Metcalf/dp/0198505582 FORTRAN 90/95 explained, by Michael Metcalf and John Reid.] A good introduction focussing on the 90 version that introduced many of the "modern" features.
 
* [https://www.amazon.ca/Fortran-90-Explained-Michael-Metcalf/dp/0198505582 FORTRAN 90/95 explained, by Michael Metcalf and John Reid.] A good introduction focussing on the 90 version that introduced many of the "modern" features.
 
|}
 
|}
  
== Some Tools ==
 
  
Standard debugging and profiling tools such as Sun Studio are designed for serial or multi-threaded programs. They do not handle multi-process runs very well.
+
{|  style="border-spacing: 8px;"
 
+
| valign="top" width="50%" style="padding:1em; border:1px solid #aaaaaa; background-color:#e1eaf1; border-radius:7px" |
Quite often, the best way to check the performance of an MPI program is timing it by insertion of suitable routines. MPI supplies a "wall-clock" routine called ''MPI_WTIME()'', that lets you determine how much actual time was spent in a specific segment of your code. An other method is calling the subroutines ''ETIME'' and ''DTIME'', which can give you information about the actual CPU time used. However, it is advisable to carefully read the documentation before using them with MPI programs. In this case, refer to the [http://docs.oracle.com/cd/E19205-01/819-5259/ Sun Studio 12: Fortran Library Reference].
+
 
+
We also provide a package called the [[Software:HWT|HPCVL Working Template (HWT)]], which was created by Gang Liu. The HWT provides 3 main functionalities:
+
 
+
* '''Maintenance of multiple versions''' of the same code from a single source file. This is very useful, if your MPI code is based on a serial code that you want to convert.
+
* '''Automatic Relative Debugging''' which allows you to use pre-existing code (for example the serial version of your program) as a reference when checking the correctness of your MPI code.
+
* '''Simple Timing''' which is needed to determine bottlenecks for parallelization, to optimize code, and to check its scaling properties.
+
 
+
The HWT is based on libraries and script files. It is easy to use and portable (written largely in Fortran). Fortran, C, C++, and any mixture thereof are supported, as well as MPI and OpenMP for parallelism. [http://hpcvl.org/sites/default/files/hpcvl%20HWTmanual_1.pdf Documentation of the HWT is available]. The package is installed on our clusters in /opt/hwt.
+
  
 
== Help ==
 
== Help ==
 
[mailto:cac.help@queensu.ca Send email to cac.help@queensu.ca]. We have scientific programmers on staff who will probably be able to help you out. Of course, we can't do the coding for you but we do our best to get your code ready for parallel machines and clusters.
 
[mailto:cac.help@queensu.ca Send email to cac.help@queensu.ca]. We have scientific programmers on staff who will probably be able to help you out. Of course, we can't do the coding for you but we do our best to get your code ready for parallel machines and clusters.
 
|}
 
|}

Latest revision as of 17:00, 23 November 2016

Fortran (Programming Language)

FORTRAN, C, and C++ have a long history as the basic/main compiled languages for high performance computing. The key parallel computing packages, MPI and OpenMP, have been implemented in all of them from the beginning. While C and C++ have been extended for all programming purposes, FORTRAN, originated from FORmular TRANslation, developed with an emphasis on scientific computing. After the FORTRAN I-IV, 66, and 77 stages, the FORTRAN 90, 95, 2003, 2008, and 2015 versions have adopted many advanced features to become a true modern (object oriented) programming language, especially geared toward scientific computations. The following lists some of the most useful and prominent programming features of FORTRAN.

Well Structured

FORTRAN is very well structured. All routines should have a clear beginning statement, and a corresponding ending one. For example (since case-in-sensitiveness, usually written in either all lower or all upper case)

PROGRAM MY_VERY_USEFUL_CODE
    ...
    CALL PROBLEM_SOLVING (...)
    ...
    STOP
END PROGRAM MY_VERY_USEFUL_CODE

SUBROUTINE PROBLEM_SOLVING (...)
    ...
    RESULT = AVERAGE_SCORE (...)
    RETURN
END SUBROUTINE PROBLEM_SOLVING

FUNCTION  AVERAGE_SCORE (...)
    ...
    RETURN
END FUNCTION AVERAGE_SCORE

Even the DO loop and IF structure are also finished with an END statement.

DO I = ISTART, IEND
    ...
END DO

IF (CONDITION)
    ...
ELSE
    ...
END IF

Modules

Similar to classes in C++, modules are very important and widely-used in FORTRAN. Modules, in the form of a separate code structure, may contain various definitions/declarations and can use other predefined modules. Theoretically modules are not classes, but usually used to provide some data structures (objects) for sharing, since in most scientific computations objects are known beforehand and the task is to manipulate them. Modules can also contain specific routines accessing the objects inside and accessible only when the module is used, similar to the encapsulation concept of classes. By using modules, the code can be written very concisely. Here is an example and its usage.

MODULE MY_PARAMETERS
    DOUBLE PRECISION, PARAMETER :: THE_EARTH_RADIUS = 6371.0D0
END MODULE  MY_PARAMETERS

SUBROUTINE EARTH_STORY (...)
    USE MY_PARAMETERS
    DOUBLE PRECISION:: THE_EARTH_DIAMETER 
    ...
    THE_EARTH_DIAMETER = 2 * THE_EARTH_RADIUS 
    ...
    RETURN
END SUBROUTINE EARTH_STORY 

Overloading

As a modern language, FORTRAN also supports routine overloading: the ability to pick up the correct one from a group of routines with different unique interfaces by calling a fixed routine name. The routines are usually of the same functionality.

MODULE MY_KINETICS
     INTERFACE  GENERIC_KINETIC
           SUBROUTINE KINETIC_ROUTINE_A(...)
                   ...
           END SUBROUTINE KINETIC_ROUTINE_A

           SUBROUTINE KINETIC_ROUTINE_B(...)
                   ...
           END SUBROUTINE KINETIC_ROUTINE_B

           SUBROUTINE KINETIC_ROUTINE_C(...)
                   ...
           END SUBROUTINE KINETIC_ROUTINE_C
                   ...
     END INTERFACE GENERIC_KINETIC
END MODULE  MY_KINETICS

After this module is cited

USE MY_KINETICS

with each of the specific routines available, the call

CALL GENERIC_KINETIC(...)

will invoke the specific routine with the matching unique interface. In C++, overloading is a type of class polymorphism.

High Precision

Most FORTRAN compilers have built-in data types of very high precision, like quadruple precision

REAL*16    ::  VELOCITY(3,1000)
COMPLEX*32 ::  HAMILTONIAN(1000, 1000)


Collective Operations

FORTRAN supports collective operations on a whole array or a section of it.

REAL*16 ::  V1(3,100), V2(3,100), V3(3,100)
...
V1 = 0.0Q0
V1(2:3, 20:50) = 0.9Q0
V2 = 0.8Q0 * V3 

which assign all the "mentioned" elements with the corresponding values, without a need of loop(s). A pure array name means all elements.

Dynamic Memory Allocation

Early versions of FORTRAN had a big drawback: they did not allow for dynamic memory allocation, forcing re-compilation for array sizes changed. Newer versions of FORTRAN (since F90) support such operations even for many-dimensional arrays.

REAL*16, ALLOCATABLE :: COMPLICATED_DATA(:, :, :, :, :, :) 
INTEGER              :: I1=3, I2=90, I3=80, I4, I5, I6=28
I4 = 24; I5 = 500
ALLOCATE(COMPLICATED_DATA(I1, I2, I3, I4, I5, I6)) 

in contrast to C/C++ where all arrays are allocated as one-dimensional.

User Defined Data Types

FORTRAN also supports user defined data types:

TYPE PERSON
     CHARACTER(LEN=10) ::  NAME
     REAL              ::  AGE
     INTEGER           ::  ID
END TYPE PERSON
TYPE(PERSON) :: YOU, ME
REAL :: DIFF
YOU%ID = 12345
DIFF = YOU%AGE - ME%AGE

Some Other Features

  • FORTRAN also supports recursive routines calls and optional arguments for routines.
  • OpenMP and OpenAcc can easier understand and parallelize FORTRAN code.
  • Compilers check FORTRAN code strictly based on grammars and point out any problems they find.


Links and Further Reading


Help

Send email to cac.help@queensu.ca. We have scientific programmers on staff who will probably be able to help you out. Of course, we can't do the coding for you but we do our best to get your code ready for parallel machines and clusters.