# Examples of OpenMP Usage

The following examples show how to use the OpenMP feature. See more examples in the OpenMP Fortran version 2.0 specifications.

## DO: A Simple Difference Operator

This example shows a simple parallel loop where each iteration contains a different number of instructions. To get good load balancing, dynamic scheduling is used. The END DO has a NOWAIT because there is an implicit BARRIER at the end of the parallel region.

subroutine do_1 (a,b,n)
real a(n,n), b(n,n)
c\$omp parallel
c\$omp&   shared(a,b,n)
c\$omp&   private(i,j)
c\$omp do schedule(dynamic,1)
do i = 2, n
do j = 1, i
b(j,i) = ( a(j,i) + a(j,i-1) ) / 2
enddo
enddo
c\$omp end do nowait
c\$omp end parallel
end

## DO: Two Difference Operators

This example shows two parallel regions fused to reduce fork/join overhead. The first END DO has a NOWAIT because all the data used in the second loop is different than all the data used in the first loop.

subroutine do_2 (a,b,c,d,m,n)
real a(n,n), b(n,n), c(m,m), d(m,m)
c\$omp parallel
c\$omp&   shared(a,b,c,d,m,n)
c\$omp&   private(i,j)
c\$omp do schedule(dynamic,1)
do i = 2, n
do j = 1, i
b(j,i) = ( a(j,i) + a(j,i-1) ) / 2
enddo
enddo
c\$omp end do nowait
c\$omp do schedule(dynamic,1)
do i = 2, m
do j = 1, i
d(j,i) = ( c(j,i) + c(j,i-1) ) / 2
enddo
enddo
c\$omp end do nowait
c\$omp end parallel
end

## SECTIONS: Two Difference Operators

This example demonstrates the use of the SECTIONS directive. The logic is identical to the preceding DO example, but uses SECTIONS instead of DO. Here the speedup is limited to 2 because there are only two units of work whereas in DO: Two Difference Operators above there are n-1 + m-1 units of work.

subroutine sections_1 (a,b,c,d,m,n)
real a(n,n), b(n,n), c(m,m), d(m,m)
!\$omp parallel
!\$omp& shared(a,b,c,d,m,n)
!\$omp& private(i,j)
!\$omp sections
!\$omp section
do i = 2, n
do j = 1, i
b(j,i)=( a(j,i) + a(j,i-1) ) / 2
enddo
enddo

!\$omp section
do i = 2, m
do j = 1, i
d(j,i)=( c(j,i) + c(j,i-1) ) / 2
enddo
enddo
!\$omp end sections nowait
!\$omp end parallel
end

## SINGLE: Updating a Shared Scalar

This example demonstrates how to use a SINGLE construct to update an element of the shared array a. The optional NOWAIT after the first loop is omitted because it is necessary to wait at the end of the loop before proceeding into the SINGLE construct.

subroutine sp_1a (a,b,n)
real a(n), b(n)
!\$omp parallel
!\$omp& shared(a,b,n)
!\$omp& private(i)
!\$omp do
do i = 1, n
a(i) = 1.0 / a(i)
enddo
!\$omp single
a(1) = min( a(1), 1.0 )
!\$omp end single
!\$omp do
do i = 1, n
b(i) = b(i) / a(i)
enddo
!\$omp end do nowait
!\$omp end parallel
end