Developer Guide and Reference

ID 767251
Date 10/31/2024
Public
Document Table of Contents

OpenMP* Examples

The following examples show how to use OpenMP* features.

A Simple Difference Operator

This example shows a simple parallel loop where the amount of work in each iteration is different. Dynamic scheduling is used to improve load balancing.

The END DO directive has a NOWAIT clause because there is an implicit barrier at the end of the parallel region. Therefore it is not necessary to also have a barrier at the end of the DO region.

subroutine do_1(a,b,n)
  real a(n,n), b(n,n)
  !$OMP PARALLEL SHARED(A,B,N)
     !$OMP DO SCHEDULE(DYNAMIC,1) PRIVATE(I,J)
       do i = 2, n
          do j = 1, i
            b(j,i) = ( a(j,i) + a(j,i-1) ) / 2.0
          end do
      end do
  !$OMP END DO NOWAIT 
!$OMP END PARALLEL 
end

Two Difference Operators: DO Loop Version

This example uses two parallel loops fused to reduce fork/join overhead. The first DO directive has a NOWAIT clause 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)
  !$OMP PARALLEL SHARED(A,B,C,D,M,N) PRIVATE(I,J)
    !$OMP DO SCHEDULE(DYNAMIC,1) NOWAIT
       do i = 2, n
        do j = 1, i
          b(j,i) = ( a(j,i) + a(j,i-1) ) / 2.0
        end do
      end do
    !$OMP DO SCHEDULE(DYNAMIC,1)
      do i = 2, m
        do j = 1, i
          d(j,i) = ( c(j,i) + c(j,i-1) ) / 2.0
        end do
      end do
    !$OMP END DO NOWAIT
  !$OMP END PARALLEL 
end

Two Difference Operators: SECTIONS Version

This example demonstrates the use of the SECTIONS directive. The logic is identical to the preceding DO directive example, but it uses a SECTIONS directive instead of a DO directive. Here the speedup is limited to two because there are only two units of work whereas in the example 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 SHARED(A,B,C,D,M,N) 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.0
             end do
          end do
       !$OMP SECTION
          do i = 2, m
             do j = 1, i
                d(j,i)=( c(j,i) + c(j,i-1) ) / 2.0
             end do
          end do
    !$OMP END SECTIONS NOWAIT
  !$OMP END PARALLEL 
end

Update a Shared Scalar

This example demonstrates how to use a SINGLE construct to update an element of the shared array a. The optional !$OMP DO 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 to avoid a race condition.

subroutine sp_1a(a,b,n)
  real a(n), b(n)
  !$OMP PARALLEL SHARED(A,B,N) PRIVATE(I)
    !$OMP DO
       do i = 1, n
         a(i) = 1.0 / a(i)
       end do
    !$OMP SINGLE
      a(1) = min( a(1), 1.0 )
    !$OMP END SINGLE
    !$OMP DO NOWAIT
      do i = 1, n
        b(i) = b(i) / a(i)
      end do
    !$OMP END DO 
  !$OMP END PARALLEL 
end

More Samples

Additional OpenMP code samples for the Intel® Fortran Compiler are available in the oneAPI Samples GitHub* repository. See also the OpenMP API Examples document available on the OpenMP website.