Pointer array

Hello!
I have a problem with using pointer to arrays. I have created the following example just to demonstrate the nature of the problem.

program test
implicit none
real, TARGET :: a
real, POINTER :: pa
real, allocatable,TARGET:: x(:),y(:)
real, POINTER :: px(:),py(:)

a=1
pa=>a

allocate(x(1))
x(1)=3
px=>x

allocate(y(1))
y(1)=4
py=>y

!$acc enter data create(a,pa,x,px,y,py)
!$acc kernels present(a,pa,x,px,y,py) default(none)

x(1)=3
y(1)=4

px(:)=py(:)

a=px(1)

!$acc end kernels
!$acc update self(a)
!$acc exit data delete(a,pa,x,y,px,py)

write (,) a

end program test



when I compile the code, it creates the following error:

$ pgfortran test.f90 -acc -o test.out

PGF90-S-0155-Data clause required with default(none): px$f (test.f90: 21)
PGF90-S-0155-Data clause required with default(none): px$f(:) (test.f90: 21)

Although px is already in “Present” clause, the compile still complains!

I removed the “default” clause, and the compilation succeeds but the runtime generates a segmentation fault:



!$acc enter data create(a,pa,x,px,y,py)
!$acc kernels present(a,pa,x,px,y,py)

x(1)=3
y(1)=4

px(:)=py(:)

a=px(1)

!$acc end kernels
!$acc update self(a)
!$acc exit data delete(a,pa,x,y,px,py)



$>./test.out
Segmentation fault

I even assign pointers inside the kernels code region, but it still generates a segmentation fault:

!$acc enter data create(a,pa,x,px,y,py)
!$acc kernels present(a,pa,x,px,y,py)

x(1)=5
y(1)=6

px=>x
py=>y
px(:)=py(:)

a=px(1)

!$acc end kernels
!$acc update self(a)
!$acc exit data delete(a,pa,x,y,px,py)

\

./test.out
Segmentation fault


I finally removed the pointers and everything worked:

!$acc enter data create(a,pa,x,px,y,py)
!$acc kernels present(a,pa,x,px,y,py)

x(1)=5
y(1)=6

x(:)=y(:)

a=x(1)

!$acc end kernels
!$acc update self(a)
!$acc exit data delete(a,pa,x,y,px,py)

$>./test.out
6.000000


I would appreciate it if anybody can advise.

My best regards
Reza

Hi Reza,

Fortran array syntax sematic rules require that the right hand side be fully evaluated before assignment to the left-hand side. Hence a temporary array is created to store the results before assignment. (“px$f” is compiler generated temp array). If the compiler can determine there are no dependencies, then it can optimize away the temp array. However given these are pointers, it must presume a dependency and keep the temp array.

This is a case where you’ll need write an explicit loop rather use array syntax so that the temp array isn’t needed and you can use the “independent” clause to tell the compiler that there isn’t a dependency. For example:

% cat test.f90
program test
 implicit none
 integer :: size, i
 real, TARGET :: a
 real, POINTER :: pa
 real, allocatable,TARGET:: x(:),y(:)
 real, POINTER :: px(:),py(:)

 size = 1
 a=1
 pa=>a

 allocate(x(size))
 x(1)=3
 px=>x

 allocate(y(size))
 y(1)=4
 py=>y

 !$acc enter data create(a,pa,x,px,y,py)
 !$acc kernels present(a,pa,x,px,y,py) default(none)

 x(1)=3
 y(1)=4

 !$acc loop independent
 do i=1,size
   px(i)=py(i)
 end do

 a=px(1)

 !$acc end kernels
 !$acc update self(a)
 !$acc exit data delete(a,pa,x,y,px,py)

 write (*,*) a

 end program test

% pgf90 test.f90 -Minfo=accel -acc
test:
      0, Accelerator kernel generated
         28, !$acc loop seq
     21, Generating enter data create(a,pa,px(:),py(:),x(:),y(:))
     22, Generating present(a,pa,px(:),py(:),x(:),y(:))
         Accelerator scalar kernel generated
     28, Loop is parallelizable
     35, Generating update self(a)
     36, Generating exit data delete(a,pa,px(:),py(:),x(:),y(:))
% a.out
    4.000000

Hope this helps,
Mat

Hello Mat!
Thank you for your kind reply. Now I understand what is the root of the problem. I wonder if this is an issue only with PGI compiler? If I am not wrong, I think CRAY compiler can handle the syntax and does not require an explicit loop. My real code compiles and runs with CRAY, but PGI compiler makes similar complaints. I would appreciate it if you could also shed some light into the reason why two compilers behaves differently.

My best regards,
Reza

Hi Reza,

I can’t say for sure but most likely the Cray compiler is doing a better job of pointer dependency analysis than PGI. It’s a very difficult thing to do in all but the most simple cases and often requires runtime pointer checking (which we do in C in vectorization on host but not on an accelerator).

-Mat