Hi Julian,
thanks for the patch and the post-review fixes. (The revised patch was
committed as r279628. And I have committed a few minor follow-up
improvements.)
I still have an issues with the following.
On 12/18/19 11:51 PM, Tobias Burnus wrote:
+ /* Disallow duplicate bare variable references and multiple
+ subarrays of the same array here, but allow multiple
components of
+ the same (e.g. derived-type) variable. For the latter,
duplicate
+ components are detected elsewhere. */
Do we have a test case for "the latter"?
Seemingly, the latter is neither tested-for nor diagnosed:
type t
integer, allocatable :: i
end type t
type(t) :: x
!$acc enter data copyin(x%i, x, x%i) ! Bad: accepted
!$acc data pcopy(x) pcopy(x) ! OK – rejected: Symbol 'x' present on multiple
clauses at (1)
!$acc end data
end
Thirdly, I am not sure whether the following will work with your code:
…
!$acc data copy (x(:)%k, x(:)%j(3))
This data is strided; I don't quickly see whether that's rejected. (I
also
didn't check whether it is valid, but I think it is not.)
For attach/detach, the crucial bit is that the sub-references are
*allocatable* or *pointer* variables, otherwise it does not make sense to
talk about attach/detach. — For those, already the Fortran semantic
gives an error. I have attached a test case (strided-alloc-ptr.f90),
which shows that this is correctly rejected.
However, the other question is how component access w/o allocatables
or pointers is handled (i.e. they are all in the same aggregated type).
I attached a test case for this (mapping-tests.f90).
In particular:
* "copy(x, x%k)" – rejected by OpenMP and, hence, OpenACC for C/C++
Accepted by gfortran for OpenACC (for gfortran: missing OpenMP 4.5 feature)
* "copy(y(:)%i)" – strided access, i.e. y(1)%i + y(2)%i + …
Is this valid OpenACC or not?
[Currently equivalent to "copy(y)"]
* "copy(z(1)%cc(:)%i)" – also strided access, but gives an ICE
See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93025
Tobias
implicit none
type t
integer, allocatable :: i, j(:)
integer, pointer :: k, ll(:)
end type t
type(t) :: x(2)
!$acc enter data copyin(x)
!$acc enter data copyin(x(:)%i)
! { dg-error "Component to the right of a part reference with nonzero rank must not have the ALLOCATABLE attribute" "" { target "*-*-*" } 10 }
! { dg-error "Error: 'x' in MAP clause at .1. is not a proper array section" "" { target "*-*-*" } 10 }
!$acc enter data copyin(x(:)%j(3))
! { dg-error "Component to the right of a part reference with nonzero rank must not have the ALLOCATABLE attribute" "" { target "*-*-*" } 14 }
! { dg-error "Error: 'x' in MAP clause at .1. is not a proper array section" "" { target "*-*-*" } 14 }
!$acc enter data copyin(x(:)%j)
! { dg-error "Component to the right of a part reference with nonzero rank must not have the ALLOCATABLE attribute" "" { target "*-*-*" } 18 }
! { dg-error "Error: 'x' in MAP clause at .1. is not a proper array section" "" { target "*-*-*" } 18 }
!$acc enter data copyin(x(:)%k)
! { dg-error "Component to the right of a part reference with nonzero rank must not have the POINTER attribute" "" { target "*-*-*" } 23 }
! { dg-error "Error: 'x' in MAP clause at .1. is not a proper array section" "" { target "*-*-*" } 23 }
!$acc enter data copyin(x(:)%ll(3))
! { dg-error "Component to the right of a part reference with nonzero rank must not have the POINTER attribute" "" { target "*-*-*" } 27 }
! { dg-error "Error: 'x' in MAP clause at .1. is not a proper array section" "" { target "*-*-*" } 27 }
!$acc enter data copyin(x(:)%ll)
! { dg-error "Component to the right of a part reference with nonzero rank must not have the POINTER attribute" "" { target "*-*-*" } 31 }
! { dg-error "Error: 'x' in MAP clause at .1. is not a proper array section" "" { target "*-*-*" } 31 }
end
subroutine foo
type t
integer :: i, j
end type t
type t2
type(t) :: cc(3)
end type t2
type(t) x, y(3)
type(t2) :: z(3)
! OK - map whole aggregated variable
!$acc enter data copyin(x)
! map(to:x [len: 8])
! OK - map two components of the aggregated variable
!$acc enter data copyin(x%j, x%i)
! map(struct:x [len: 2]) map(to:x.i [len: 4]) map(to:x.j [len: 4])
! WRONG? Accepted – but should it?
! Maps whole 'x' plus 'x%j' again.
! In gcc/g++ rejected for OpenMP and, hence, for OpenACC.
! - only "x.i, x.j" or "x" is accepted by OpenMP.
! gfortran: not yet implemented OpenMP 4.5 feature.
!$acc enter data copyin(x, x%i)
! map(to:x [len: 8]) map(to:x.i [len: 4])
! I think this only works by chance.
! WRONG? Strided access of 'x'
! No C/C++ equivalent
!$acc enter data copyin(y(:)%i)
! In terms of Fortran semantic this is equivalent to
! copyin(y(1)%i, y(2)%i, y(3)%i).
! Dump shows:
! map(to:MEM[(c_char *)_6] [len: _5])
! which is map(to:y [len: 3*sizeof(t)]),
! i.e. equivalent to "copyin(y)".
! I am not sure what the expected input is
!$acc enter data copyin(z(1)%cc(:)%i)
! ICE in gfc_trans_omp_array_section
end