# Lecture 20

OpenMP

## What is OpenMP?

• OpenMP is a collection of compiler directives and library routines for parallel shared memory programs.
• Thread A, B, C & D share memory. Fork - Join Model!

## How does OpenMP work?

• The idea is to take your serial code and "convert it" in such a way that you can still run it in serial mode.

• This is done by two directive sentinels

1. !$OMP 2. !$
• When a non-OpenMP compiler encounters these it will treat those lines as comments.

• When an OpenMP compiler encounters !$it will replace it by two whitespaces leading to a conditional compiling. • OpenMP compiler also knows that !$OMP will be followed by an OpenMP directive.

## Compiler Directives

Used for various purposes:

• Splitting loops
• Parallel regions
• Distributing blocks of code on threads
• Synchronization

Syntax:

sentinel directive-name [clause, ...]

## A simple example

 1 2 3 4 5 6 program OMPtest !$use omp_lib IMPLICIT NONE integer :: my_id,n_threads,i real(kind = 8) :: sum !$ call OMP_set_num_threads(8) 
• Line 2: Use the OpenMP module to have access to subroutines.
• Line 6: Set the number of threads.

## Compiling and output

bash-3.2$make gfortran -fopenmp -c OMPtest.f90 gfortran -fopenmp OMPtest.o -o ./OPMtest.x bash-3.2$ ./OPMtest.x
Hello world, I am            4  my sum is    4.0000000000000000
Hello world, I am            3  my sum is    3.0000000000000000
Hello world, I am            2  my sum is    2.0000000000000000
Hello world, I am            1  my sum is    1.0000000000000000
Hello world, I am            5  my sum is    5.0000000000000000
Hello world, I am            6  my sum is    6.0000000000000000
Hello world, I am            0  my sum is    0.0000000000000000
Hello world, I am            7  my sum is    7.0000000000000000

• Order of execution in NOT guaranteed!

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 integer, parameter :: n = 1000 real(kind = 8) :: sum,h,x(0:n),f(0:n) !$call OMP_set_num_threads(8) h = 2.d0/dble(n) !$OMP PARALLEL DO PRIVATE(i) do i = 0,n x(i) = -1.d0+dble(i)*h f(i) = 2.d0*x(i) end do !$OMP END PARALLEL DO sum = 0.d0 !$OMP PARALLEL DO PRIVATE(i) do i = 0,n-1 sum = sum + h*f(i) end do !$OMP END PARALLEL DO write(*,*) "The integral is ", sum  ## Output bash-3.2$ make
gfortran -fopenmp -c OMPtest2.f90
gfortran -fopenmp OMPtest2.o -o ./OPMtest.x
bash-3.2$./OPMtest.x The integral is -3.9999999999998405E-003 bash-3.2$ ./OPMtest.x
The integral is    -3.9999999999997295E-003
bash-3.2$./OPMtest.x The integral is -0.14137599999999978 bash-3.2$ ./OPMtest.x
The integral is    -3.9999999999998960E-003