Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 7/13/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

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 END 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)
       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 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 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 NOWAIT clause 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
      do i = 1, n
        b(i) = b(i) / a(i)
      end do
    !$OMP END DO NOWAIT
  !$OMP END PARALLEL 
end

More Samples

Additional OpenMP code samples for the Intel® Fortran Compiler are available in the oneAPI Samples GitHub* repository.