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

Reply via email to