On the correct array syntax to be used in data clauses

Dear All,
I create a new topic on what seems to us a different issue, even though always related to the use of arrays in OpenACC (the first topic was Wrong results when using vector clause in parallel loop with array syntax).
It seems that the acc data copyout clause requires the array bounds to be explicited even when only one element of an array has to be accessed, namely: to copyout only the inner ith element of an array (computed on GPUs) one should write:

!$acc data copyout(a(i:i))

If we write:

!$acc data copyout(a(i))

what happens is:

34, Generating copyout(a(:i)) [if not already present]

while the the copyout(a(i:i)):

34, Generating copyout(a(2)) [if not already present]

which is what we want. Is that a known feature? can’t I use the syntax a(i) for specifying a single element?
Thank you for any clarification you may provide,
best
Isabella

Toy reproducer of the error:

! nvfortran -c -o test.o test.F90 -cuda -acc -gpu=cc70 -Minfo=accel -g -r8 -traceback -Mnoinline
! nvfortran -o test test.o -cuda -acc -gpu=cc70 -Minfo=accel -g -r8 -traceback -Mnoinline 

module simple
  type TType
    integer :: a, b, c
  end type

contains
  subroutine set_val_gpu(test, idx)
    type(TType), intent(out) :: test
    integer, intent(in) :: idx
    !$acc serial present(test) copyin(idx) async(1)
    test%a = 10
    test%b = 20
    test%c = 30
    !$acc end serial
  end subroutine set_val_gpu

  subroutine set_val_cpu(test, idx)
    type(TType), intent(out) :: test
    integer, intent(in) :: idx
    test%a = 1
    test%b = 2
    test%c = 3
  end subroutine set_val_cpu
end module simple


program testprogram
  use simple
  implicit none
  type(TType), dimension(3) :: a
  integer :: i

  write (*,*) "test start"
  !$acc data copyout(a(2))
  CALL set_val_gpu(a(2), 2)
  CALL set_val_cpu(a(1), 1)
  CALL set_val_cpu(a(3), 3)
  write (*,*) "result"
  write (*,*) "a"
  write (*,*)  a
  !$acc wait(1)
  !$acc end data
  write (*,*) "result"
  write (*,*) "a"
  write (*,*)  a
end program testprogram

Hi Isabella,

When we first implemented OpenACC, users would use the syntax “copy a(2)” but expected this to copy all elements up to 2. Hence, we decide to help by making the lower bound of the triple implicitly defined as “1” in Fortran and “0” in C/C++ when not present.

Though recently we’ve had more users like yourself wanting to copy single element and given this is actually what the OpenACC standard specifies, we changed out behavior in the 21.11 release that the lower bound is no longer implicitly provided. In other words, if you update to 21.11 or later, you’ll see the behavior you’re expecting.

For example, here’s the output from 21.9:

% nvfortran test.F90 -acc -V21.9 ; a.out
NVFORTRAN-W-0155-Upcoming behavior change: array reference in data/update clause with no triplet notation will be treated as an array element in a future release: a (test.F90: 37)
  0 inform,   1 warnings,   0 severes, 0 fatal for testprogram
 test start
 result
 a
            1            2            3            0            0            0
            1            2            3
 result
 a
            0            0            0           10           20           30
            1            2            3

But with 21.11, you see the expect answers.

% nvfortran test.F90 -acc -V21.11 ; a.out
 test start
 result
 a
            1            2            3            0            0            0
            1            2            3
 result
 a
            1            2            3           10           20           30
            1            2            3

Hope this helps,
Mat

Dear Mat,
this perfectly helps, thank you very much! I’ll immediately update the nvhpc toolkit (we’ve been a libt lazy on that I’m afraid) and provide a note on the matter on our site.
Cheers,
Isabella