openacc fortran pointers

I am trying to understand how fortran pointers work in OpenACC.

I know OpenACC keeps separte device and host pointers, but I do not understand how explicitly declared fortran pointers are handled. The following code fails if I comment out the declar present§ in the subroutine, but it works if I don’t. In the code I am working on, always pointers to structures (“type(data), pointer:: p”) is passed to subroutines, and it would be a lot more convenient if i can just declare present that in the beginning.

I also tried to declare create§ and then update device§ during the assignment =>, that also doesn’t work.

program test
    integer, target :: x
!$acc declare create(x)
    integer, pointer :: p
!$acc declare create(p)  

    x = 2 
    p => x
!$acc kernels
    p => x
!$acc end kernels
    call pr(p)

contains

    subroutine pr(p)
        integer,  pointer :: p
!$acc declare present(p)

!$acc kernels
        p = 10
!$acc end kernels

        print*, p
    end subroutine

end program test

Hi dshawul,

This is a tough issue that I don’t have a great solution for you. The problem here is that when accessing a pointer, Fortran semantics state that the code accesses the target. Hence, if you put “p” in an OpenACC data region, the target is actually created on the device, not the pointer. However, the pointer needs to exists in order to access it on the device. In C/C++, we could create the device pointer and then “attach” it to the device target, but there isn’t a good way to do this in Fortran.

I not sure this will work for what you need in the real program, but as a work around you pass the pointer target instead of the pointer itself, i.e. change “integer, pointer :: p” in “pr” to “integer :: p”.

% cat ptr.f90
program test
     integer, target :: x
     integer, pointer :: p
!$acc declare create(x)
     x = 2
     p => x
     call pr(p)

contains
     subroutine pr(p)
         integer :: p
!$acc serial present(p)
         p = 10
!$acc end serial
!$acc update self(p)
         print*, p
     end subroutine
end program test
% pgf90 ptr.f90 -Minfo=accel -V18.1 -ta=tesla:cc70; a.out
test:
      4, Generating create(x)
pr:
     12, Generating present(p)
         Accelerator serial kernel generated
         Generating Tesla code
     15, Generating update self(p)
           10

Hope this helps,
Mat

Hello Matt,

Thank you as always for your reply.

Unfortunately I want to keep the declaration as integer,pointer::p

So what I am doing is to NOT do a declare present on p at the beginning of the subroutine. I will not bother about keeping the pointer to the device association.

Daniel