Skip to content

Commit 79d5118

Browse files
committed
Add MPI Fortran tutorial
1 parent 7c1f152 commit 79d5118

1 file changed

Lines changed: 161 additions & 0 deletions

File tree

tutorials/mpi-fortran/index.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
layout: post
3+
title: Using MPI with Fortran
4+
author: Stephen Cook
5+
categories: Beginner MPI
6+
tags:
7+
translations:
8+
redirect_from: '/mpi-fortran/'
9+
---
10+
11+
The MPI specification defines bindings for use within Fortran, a programming language frequently used for scientific computing.
12+
In this tutorial, we shall see some of the specifics for using MPI with Fortran, focussing on the similarities and differences compared to the C binding covered in the other tutorials.
13+
14+
> **Note** - Fortran versions of most of the MPI example code is provided on [GitHub]({{ site.github.repo }}) under [tutorials/mpi-fortran/code]({{ site.github.code }}/tutorials/mpi-fortran/code).
15+
16+
## Fortran Hello World code example
17+
18+
We shall first have a look at the Fortran 2008 version of a Hello World located in [mpi_hello_world.f90]({{ site.github.code }}/tutorials/mpi-fortran/code/mpi_hello_world.f90).
19+
20+
```fortran
21+
program hello_world_mpi
22+
use mpi_f08
23+
24+
implicit none
25+
26+
integer :: world_rank, world_size
27+
integer :: name_len
28+
29+
character (len=MPI_MAX_PROCESSOR_NAME) :: processor_name
30+
31+
! Initialize the MPI environment
32+
call MPI_INIT()
33+
34+
! Get the number of processes
35+
call MPI_COMM_SIZE(MPI_COMM_WORLD, world_size)
36+
37+
! Get the rank of the process
38+
call MPI_COMM_RANK(MPI_COMM_WORLD, world_rank)
39+
40+
! Get the name of the processor
41+
call MPI_GET_PROCESSOR_NAME(processor_name, name_len)
42+
43+
! Print off an hello world message
44+
print '("Hello world from processor ", A, ", rank ", I0, " out of ", I0, " processors")', &
45+
processor_name(:name_len), world_rank, world_size
46+
47+
! Finalize the MPI environment
48+
call MPI_FINALIZE()
49+
50+
end program
51+
```
52+
53+
Comparing this with the equivalent C code in [mpi_hello_world.c]({{ site.github.code }}/tutorials/mpi-hello-world/code/mpi_hello_world.c):
54+
55+
```c
56+
#include <mpi.h>
57+
#include <stdio.h>
58+
59+
int main(int argc, char** argv) {
60+
// Initialize the MPI environment
61+
MPI_Init(NULL, NULL);
62+
63+
// Get the number of processes
64+
int world_size;
65+
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
66+
67+
// Get the rank of the process
68+
int world_rank;
69+
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
70+
71+
// Get the name of the processor
72+
char processor_name[MPI_MAX_PROCESSOR_NAME];
73+
int name_len;
74+
MPI_Get_processor_name(processor_name, &name_len);
75+
76+
// Print off a hello world message
77+
printf("Hello world from processor %s, rank %d out of %d processors\n",
78+
processor_name, world_rank, world_size);
79+
80+
// Finalize the MPI environment.
81+
MPI_Finalize();
82+
}
83+
```
84+
85+
We see many similarities but a few important differences.
86+
87+
## Importing and initializing MPI
88+
89+
In order to make MPI calls from within a Fortran program, the library must be imported and then initialized.
90+
91+
The modern implementation of MPI was introduced with MPI 3.0 and Fortran 2008, and is imported into the program with
92+
93+
```fortran
94+
USE mpi_f08
95+
```
96+
97+
The fortran binding to the MPI routines are implemented as subroutines, and require the syntax
98+
99+
```fortran
100+
call MPI_XXXXXX()
101+
```
102+
103+
> **Note** - Unlike C, Fortran is case insensitive. We adopt the convention of using all-capital names of the MPI routines.
104+
105+
As an example, the first few lines of a fortran MPI program may look like this:
106+
107+
```fortran
108+
use mpi_f08
109+
implicit none
110+
call MPI_INIT()
111+
```
112+
113+
All the Fortran routines have an optional argument to return an error-code, so the above could could also be
114+
115+
```fortran
116+
use mpi_f08
117+
implicit none
118+
integer :: ierror
119+
call MPI_INIT(ierror)
120+
```
121+
122+
The routine `MPI_INIT` has no required arguments and an error code can be returned as an optional argument.
123+
Compare this with the C function `MPI_Init` which has two required arguments (the number of command-line arguments and a list of these as character arrays) and can optionally give the error code as the return value.
124+
125+
## Other MPI routines
126+
127+
Despite the differences in arguments required by the C and Fortran versions of `MPI_Init`, most other Fortran MPI routines share similar interfaces as the C implementations.
128+
Again, the Fortran 2008 routines all end in the optional argument `IERROR`.
129+
130+
```fortran
131+
program hello_world_mpi
132+
use mpi_f08
133+
integer :: world_size
134+
call MPI_INIT()
135+
136+
! Get the number of processes
137+
call MPI_COMM_SIZE(MPI_COMM_WORLD, world_size)
138+
! Alternatively:
139+
! MPI_COMM_SIZE(MPI_COMM_WORLD, world_size, ierror)
140+
```
141+
142+
Fortran versions of most of the C MPI example code from these tutorials has been translated to Fortran and is provided on [GitHub]({{ site.github.repo }}) under [tutorials/mpi-fortran/code]({{ site.github.code }}/tutorials/mpi-fortran/code).
143+
These have mostly been written to mirror the C versions, with some Fortran-specific functionality added where it does not impact the MPI code (such as using the fortran function `sum` instead of performing a summation in a loop).
144+
145+
## Older MPI implementations
146+
147+
Prior to the introduction of `mpi_f08`, the library was imported with the syntax
148+
149+
```fortran
150+
USE mpi
151+
```
152+
153+
or the Fortran77 compatible
154+
155+
```fortran
156+
INCLUDE 'mpif.h'
157+
```
158+
159+
In the older versions of the interface (both `mpi` and `mpif.h`), most of the arguments such as the communicator object or the probe return status are integers or arrays of integers.
160+
In the newer syntax, these objects are implemented as custom typedefs (as in the C interface) leading to better compile-time argument checking.
161+
There is also an error code returned with all MPI calls, which is a required argument in the older versions, and an optional argument in the modern implementation.

0 commit comments

Comments
 (0)