Fortran ASSOCIATE Construct
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