Hands on intro to
parallel computing in
Fortran
time < 3 minutes
Problem
Simple algebraic system
• One dimensional steady state heat transfer
or
• Discretize on 1 dimensional grid
• At point i,
∇ ⋅ k(∇T) = 0 k
∂2
T
∂x2
= 0
Ti+1 − 2Ti + Ti−1
δx2
= 0
Th Tc
i=0 i
i-1 i+1
x
δx δx
Single domain
System of Equations
• For i=1 to N
• The equivalent system
Ti−1 − 2Ti + Ti+1
δx2
−2 1 0 0 . . . 0
1 −2 1 0 . . . 0
0 ⋱ ⋱ ⋱ . . . 0
0 . . . 0 1 −2 1
0 . . . 0 0 1 −2 N×N
T1
T2
⋮
Tn−1
Tn
N×1
=
−Th
0
⋮
0
−Tc
i=0 i
i-1 i+1
δx
δx
Th Tc
i=N+1
Single domain
Solution of the System
• Solve directly!
• Or use Jacobi or Gauss Seidel method
• For a given system of linear equations
• The iterative solution is
a11x1 + a12x2 + a13x3 = b1
a21x1 + a22x2 + a23x3 = b2
a31x1 + a32x2 + a33x3 = b3
xnew
1 = xold
1 +
1
a11
[b1 − (a11xold
1 + a12xold
2 + a13xold
3 )]
xnew
2 = xold
2 +
1
a21
[b2 − (a21xold
1 + a22xold
2 + a23xold
3 )]
xnew
3 = xold
3 +
1
a31
[b3 − (a31xold
1 + a32xold
2 + a33xold
3 )]
a11 a12 a13
a21 a22 a23
a31 a32 a33
x1
x2
x3
=
b1
b2
b3
x1 x2 x3
<
Parallel Computation
MPI
i=0 i
i-1 i+1
δx
Th Tc
i=N+1
i
i-1 i+1
i=0 i=n+1
Processor 1 Processor 2 Processor M
i
i-1 i+1
i=0 i=n+1
n =
N
Mprocs
MPI Send
MPI Recv
n+2 nodes
Aqeel Ahmed
Parallel Computation
Fortran and MPI
1 program laplacian_1d_parallel
2 use mpi_f08 ! call the MPI library
3 implicit none ! always declare variables (no auto type deduction)
4
5 ! declare variables
6 integer :: points_total, npoints, i, j, k, l, iter_max
7 real, dimension(:), allocatable :: T, T_full
8 real :: T_initial, Tr, Tl, omega, size, Temp, R
9 integer myrank, nranks, tag, ierror
10 type(MPI_Status) :: istatus
11
12 ! initialize MPI
13 call MPI_INIT(ierror)
14 call MPI_COMM_SIZE(MPI_COMM_WORLD, nranks, ierror) ! get no. of procs
15 call MPI_COMM_RANK(MPI_COMM_WORLD, myrank, ierror) ! get rank
16
17 ! total number of points
18 points_total = 2400
19 ! number of points per processor
20 npoints = int(points_total/nranks)
21 ! allocate T with 2 ghost points T(1) and T(npoints+2)
22 allocate(T(npoints+2))
23 if (myrank == 0) then
24 allocate(T_full(npoints*nranks)) ! this is for gather only
25 end if
26
27 ! initial conditions and parameters
28 Tl = 25;Tr = 18;T_initial = 20;omega = 1.5;Temp = 0.0;iter_max = 500000
29 T = T_initial
30 R = 0.0
31
32 ! set boundary conditions
33 if (myrank == 0) then
34 T(1) = Tl
35 end if
36 if (myrank == nranks-1) then
37 T(npoints+2) = Tr
38 end if
39
MPI
speci
fi
c
variables
Variables
declarations
Domain
discretisation
parameters
Problem
inputs
Boundary
conditions
Parallel Computation
Fortran and MPI
40 ! iterative solution of the system
41 do k = 1, iter_max
42 ! trasfer data at processors boundaries
43 do i = 0,nranks-2
44 if (myrank==i) then ! send the 2nd last point to next processor 1st point
45 Temp = T(npoints+1)
46 call MPI_SEND(Temp, 1, MPI_REAL, myrank+1, i, MPI_COMM_WORLD, ierror)
47 elseif (myrank==i+1) then ! receive the 2nd last point from the previous proc as 1st point
48 call MPI_RECV(Temp, 1, MPI_REAL, myrank-1, i, MPI_COMM_WORLD, istatus, ierror)
49 T(1) = Temp
50 end if
51 end do
52
53 do l = 1,nranks-1
54 ! send the second point T(2) of the current proc to previous proc last point T(npoints+2)
55 if (myrank==l) then ! send the second point to previous procs
56 Temp = T(2)
57 call MPI_SEND(Temp, 1, MPI_REAL, myrank-1, l, MPI_COMM_WORLD, ierror)
58 elseif (myrank==l-1) then ! receive the second point from the next procs as last point
59 call MPI_RECV(Temp, 1, MPI_REAL, myrank+1, l, MPI_COMM_WORLD, istatus, ierror)
60 T(npoints+2) = Temp
61 end if
62 end do
63
64 ! solution using Gauss-Seidel method with Successive Over Relaxation (SOR)
65 do i = 2,npoints+1
66 R = 0.5*omega*(T(i+1) - 2*T(i) + T(i-1))
67 T(i) = T(i) + R
68 end do
69
70 ! set boundary conditions
71 if (myrank == 0) then
72 T(1) = Tl
73 end if
74 if (myrank == nranks-1) then
75 T(npoints+2) = Tr
76 end if
77 end do
78
79 ! put T from all procs to root (master) in T_full
80 call MPI_Gather(T(2:npoints+1), npoints, MPI_REAL, T_full, npoints, &
81 MPI_REAL, 0, MPI_COMM_WORLD, ierror)
82
83 call MPI_FINALIZE(ierror)
MPI
communications
Iterative solution

Hands on Intro to parallel computing in FORTRAN

  • 1.
    Hands on introto parallel computing in Fortran time < 3 minutes
  • 2.
    Problem Simple algebraic system •One dimensional steady state heat transfer or • Discretize on 1 dimensional grid • At point i, ∇ ⋅ k(∇T) = 0 k ∂2 T ∂x2 = 0 Ti+1 − 2Ti + Ti−1 δx2 = 0 Th Tc i=0 i i-1 i+1 x δx δx
  • 3.
    Single domain System ofEquations • For i=1 to N • The equivalent system Ti−1 − 2Ti + Ti+1 δx2 −2 1 0 0 . . . 0 1 −2 1 0 . . . 0 0 ⋱ ⋱ ⋱ . . . 0 0 . . . 0 1 −2 1 0 . . . 0 0 1 −2 N×N T1 T2 ⋮ Tn−1 Tn N×1 = −Th 0 ⋮ 0 −Tc i=0 i i-1 i+1 δx δx Th Tc i=N+1
  • 4.
    Single domain Solution ofthe System • Solve directly! • Or use Jacobi or Gauss Seidel method • For a given system of linear equations • The iterative solution is a11x1 + a12x2 + a13x3 = b1 a21x1 + a22x2 + a23x3 = b2 a31x1 + a32x2 + a33x3 = b3 xnew 1 = xold 1 + 1 a11 [b1 − (a11xold 1 + a12xold 2 + a13xold 3 )] xnew 2 = xold 2 + 1 a21 [b2 − (a21xold 1 + a22xold 2 + a23xold 3 )] xnew 3 = xold 3 + 1 a31 [b3 − (a31xold 1 + a32xold 2 + a33xold 3 )] a11 a12 a13 a21 a22 a23 a31 a32 a33 x1 x2 x3 = b1 b2 b3 x1 x2 x3
  • 5.
    < Parallel Computation MPI i=0 i i-1i+1 δx Th Tc i=N+1 i i-1 i+1 i=0 i=n+1 Processor 1 Processor 2 Processor M i i-1 i+1 i=0 i=n+1 n = N Mprocs MPI Send MPI Recv n+2 nodes Aqeel Ahmed
  • 6.
    Parallel Computation Fortran andMPI 1 program laplacian_1d_parallel 2 use mpi_f08 ! call the MPI library 3 implicit none ! always declare variables (no auto type deduction) 4 5 ! declare variables 6 integer :: points_total, npoints, i, j, k, l, iter_max 7 real, dimension(:), allocatable :: T, T_full 8 real :: T_initial, Tr, Tl, omega, size, Temp, R 9 integer myrank, nranks, tag, ierror 10 type(MPI_Status) :: istatus 11 12 ! initialize MPI 13 call MPI_INIT(ierror) 14 call MPI_COMM_SIZE(MPI_COMM_WORLD, nranks, ierror) ! get no. of procs 15 call MPI_COMM_RANK(MPI_COMM_WORLD, myrank, ierror) ! get rank 16 17 ! total number of points 18 points_total = 2400 19 ! number of points per processor 20 npoints = int(points_total/nranks) 21 ! allocate T with 2 ghost points T(1) and T(npoints+2) 22 allocate(T(npoints+2)) 23 if (myrank == 0) then 24 allocate(T_full(npoints*nranks)) ! this is for gather only 25 end if 26 27 ! initial conditions and parameters 28 Tl = 25;Tr = 18;T_initial = 20;omega = 1.5;Temp = 0.0;iter_max = 500000 29 T = T_initial 30 R = 0.0 31 32 ! set boundary conditions 33 if (myrank == 0) then 34 T(1) = Tl 35 end if 36 if (myrank == nranks-1) then 37 T(npoints+2) = Tr 38 end if 39 MPI speci fi c variables Variables declarations Domain discretisation parameters Problem inputs Boundary conditions
  • 7.
    Parallel Computation Fortran andMPI 40 ! iterative solution of the system 41 do k = 1, iter_max 42 ! trasfer data at processors boundaries 43 do i = 0,nranks-2 44 if (myrank==i) then ! send the 2nd last point to next processor 1st point 45 Temp = T(npoints+1) 46 call MPI_SEND(Temp, 1, MPI_REAL, myrank+1, i, MPI_COMM_WORLD, ierror) 47 elseif (myrank==i+1) then ! receive the 2nd last point from the previous proc as 1st point 48 call MPI_RECV(Temp, 1, MPI_REAL, myrank-1, i, MPI_COMM_WORLD, istatus, ierror) 49 T(1) = Temp 50 end if 51 end do 52 53 do l = 1,nranks-1 54 ! send the second point T(2) of the current proc to previous proc last point T(npoints+2) 55 if (myrank==l) then ! send the second point to previous procs 56 Temp = T(2) 57 call MPI_SEND(Temp, 1, MPI_REAL, myrank-1, l, MPI_COMM_WORLD, ierror) 58 elseif (myrank==l-1) then ! receive the second point from the next procs as last point 59 call MPI_RECV(Temp, 1, MPI_REAL, myrank+1, l, MPI_COMM_WORLD, istatus, ierror) 60 T(npoints+2) = Temp 61 end if 62 end do 63 64 ! solution using Gauss-Seidel method with Successive Over Relaxation (SOR) 65 do i = 2,npoints+1 66 R = 0.5*omega*(T(i+1) - 2*T(i) + T(i-1)) 67 T(i) = T(i) + R 68 end do 69 70 ! set boundary conditions 71 if (myrank == 0) then 72 T(1) = Tl 73 end if 74 if (myrank == nranks-1) then 75 T(npoints+2) = Tr 76 end if 77 end do 78 79 ! put T from all procs to root (master) in T_full 80 call MPI_Gather(T(2:npoints+1), npoints, MPI_REAL, T_full, npoints, & 81 MPI_REAL, 0, MPI_COMM_WORLD, ierror) 82 83 call MPI_FINALIZE(ierror) MPI communications Iterative solution