10.14. Fortran ASSOCIATE Construct#

The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the ASSOCIATE statement. The associate name b is associated with the shared variable a . With the predetermined data-sharing attribute rule, the associate name b is not allowed to be specified on the private clause.

!!%compiler: gfortran
!!%cflags: -fopenmp

! name: associate.1
! type: F-fixed
! version: omp_4.0
      program example_broken
      real :: a, c
      associate (b => a)
!$omp parallel private(b, c)        ! invalid to privatize b
      c = 2.0*b
!$omp end parallel
      end associate
      end program

In next example, within the parallel construct, the association name thread_id is associated with the private copy of i . The print statement should output the unique thread number.

!!%compiler: gfortran
!!%cflags: -fopenmp

! name: associate.2
! type: F-fixed
! version: omp_4.0
      program example
      use omp_lib
      integer  i
!$omp parallel private(i)
      i = omp_get_thread_num()
      associate(thread_id => i)
        print *, thread_id       ! print private i value
      end associate
!$omp end parallel
      end program

The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name u is associated with v and the variable v is specified on the private clause of the parallel construct. The construct association is established prior to the parallel region. The association between u and the original v is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the parallel region, v has the value of -1 and u has the value of the original v .

!!%compiler: gfortran
!!%cflags: -fopenmp

! name: associate.3
! type: F-free
! version: omp_4.0
program example
  integer :: v
  v = 15
associate(u => v)
!$omp parallel private(v)
  v = -1
  print *, v               ! private v=-1
  print *, u               ! original v=15
!$omp end parallel
end associate
end program

The following example illustrates mapping behavior for a Fortran associate name and its selector for a target construct.

For the first 3 target constructs the associate name a_aray is associated with the selector aray , an array. For the target construct of code block TARGET 1 just the selector aray is used and is implicitly mapped, likewise for the associate name a_aray in the TARGET 2 block. However, mapping an associate name and its selector is not valid for the same target construct. Hence the TARGET 3 block is non-conforming.

In TARGET 4, the scalr selector used in the target region has an implicit data-sharing attribute of firstprivate since it is a scalar. Hence, the assigned value is not returned. In TARGET 5, the associate name a_scalr is implicitly mapped and the assigned value is returned to the host (default tofrom mapping behavior). In TARGET 6, the use of the associate name and its selector in the target region is conforming because the scalar firstprivate behavior of the selector and the implicit mapping of the associate name are allowed. At the end of the target region only the associate name’s value is returned to the host. In TARGET 7, the selector and associate name appear in an explicit mapping for the same target construct, hence the code block is non-conforming.

!!%compiler: gfortran
!!%cflags: -fopenmp

! name: associate.4
! type: F-free
! version: omp_5.1
program main
  integer :: scalr, aray(3)
  scalr = -1 ; aray = -1

  associate(a_scalr=>scalr, a_aray=>aray)

 !$omp target            !! TARGET 1
    aray = [1,2,3]
  !$omp end target
  print *, a_aray, aray  !!  1 2 3   1 2 3

  !$omp target           !! TARGET 2
    a_aray = [4,5,6]
  !$omp end target
  print *, a_aray, aray  !! 4 5 6   4 5 6

!!!$omp target           !! TARGET 3
!!                       !! mapping, in this case implicit,
!!                       !! of aray AND a_aray NOT ALLOWED
!!    aray = [4,5,6]
!!  a_aray = [1,2,3]
!!!$omp end target


  !$omp target              !! TARGET 4
    scalr = 1               !! scalr is firstprivate
  !$omp end target
  print *, a_scalr, scalr   !! -1  -1

  !$omp target              !! TARGET 5
    a_scalr = 2             !! a_scalr implicitly mapped
  !$omp end target
  print *, a_scalr, scalr   !!  2   2

  !$omp target              !! TARGET 6
    scalr = 3               !!          scalr is firstprivate
    print *, a_scalr, scalr !!  2   3
    a_scalr = 4             !!          a_scalr implicitly mapped
    print *, a_scalr, scalr !!  4   3
  !$omp end target
  print *, a_scalr, scalr   !!  4   4

!!!$omp target map(a_scalr,scalr)  !! TARGET 7
                                   !! mapping, in this case explicit,
                                   !! of scalr AND a_sclar NOT ALLOWED
!!    scalr = 5
!!  a_scalr = 5
!!!$omp end target

  end associate

end program