Hi Richard,
After fixing the typos, the code works correctly for me. I also cleaned it up a bit since, no, the attach is not needed. I don’t believe we support Cray pointers directly in device code, but here “vec” is an alias for “A”, hence when the present check is done before entering the parallel loop, the correct device location will be used.
For example:
% cat test2.f90
program main
use OpenACC
real(8), allocatable,target :: A(:,:)
!$acc declare create(A)
allocate(A(10,3))
!$acc update device(A)
call Process
!$acc update self(A)
do index4=1,3
write(*,*) A(1:10,index4)
end do
contains
subroutine Process
pointer (iPvec,vec)
real(8) :: vec(1:10)
!acc declare create(iPvec)
do index=1,3
iPvec = loc(A(1,index))
!$acc parallel loop default(present)
do index2=1,10
vec(index2) = index2 + index
end do
end do
end subroutine Process
end program main
% nvfortran -Minfo=accel test2.f90 -acc; a.out
main:
8, Generating update device(a(:,:))
11, Generating update self(a(:,:))
process:
26, Generating Tesla code
27, !$acc loop gang ! blockidx%x
26, Generating default present(vec(:))
2.000000000000000 3.000000000000000 4.000000000000000
5.000000000000000 6.000000000000000 7.000000000000000
8.000000000000000 9.000000000000000 10.00000000000000
11.00000000000000
3.000000000000000 4.000000000000000 5.000000000000000
6.000000000000000 7.000000000000000 8.000000000000000
9.000000000000000 10.00000000000000 11.00000000000000
12.00000000000000
4.000000000000000 5.000000000000000 6.000000000000000
7.000000000000000 8.000000000000000 9.000000000000000
10.00000000000000 11.00000000000000 12.00000000000000
13.00000000000000
The problem with your first example before the edit was with putting “vec” in the declare create. This would create a separate copy of “vec”. Though since you wanted “vec” to be an alias to “A”, it should be left out. The acc_attach of “P” isn’t needed either since the present check will make the correct association.
% cat test.f90
program main
use OpenACC
pointer (iPvec,vec)
real(8) :: vec(1:10)
real(8), allocatable,target :: A(:,:)
real(8), pointer :: P(:)
!$acc declare create(A)
allocate(A(10,3))
A=0.0
!$acc update device(A)
do index=1,3
iPvec = loc(A(1,index))
P => A(1:10,index)
!$acc parallel loop default(present)
do index2=1,10
vec(index2) = index2 + index
end do
!$acc parallel loop default(present)
do index3=1,10
P(index3) = P(index3)+1
end do
end do
!$acc update self(A)
do index4=1,3
write(*,*) A(1:10,index4)
end do
end program main
% nvfortran -Minfo=accel test.f90 -acc ; a.out
main:
14, Generating update device(a(:,:))
19, Generating Tesla code
20, !$acc loop gang ! blockidx%x
19, Generating default present(vec(:))
24, Generating Tesla code
25, !$acc loop gang ! blockidx%x
24, Generating default present(p(1:10))
30, Generating update self(a(:,:))
3.000000000000000 4.000000000000000 5.000000000000000
6.000000000000000 7.000000000000000 8.000000000000000
9.000000000000000 10.00000000000000 11.00000000000000
12.00000000000000
4.000000000000000 5.000000000000000 6.000000000000000
7.000000000000000 8.000000000000000 9.000000000000000
10.00000000000000 11.00000000000000 12.00000000000000
13.00000000000000
5.000000000000000 6.000000000000000 7.000000000000000
8.000000000000000 9.000000000000000 10.00000000000000
11.00000000000000 12.00000000000000 13.00000000000000
14.00000000000000