PGF90-S-0155-Compiler failed to translate accelerator region

Hi,
During compilation, I get an error
PGF90-S-0155-Compiler failed to translate accelerator region

at the statement
!$acc kernels present(wavefield(nx,ny,nw,n_wave))

As you see, the variable wavefield is a 4d array that was declared and allocated in a different file. It is a member of a user-defined type.

In the other file, I have

allocate(img_arrays%wavefield(…))
!$acc enter data copyin(img_arrays%wavefield)
call foo(img_arrays%wavefield)

Looking at previous posts on this forum, it seems that there might be an issue related to allocatable arrays in user-defined types.

What is the work-around for this problem? Fyi, I am using PGI 14.6

Thanks,
KM

Hi KM,

The problem here is that OpenACC doesn’t support “deep-copies”. Hence, using dynamically allocated members in user defined types is not supported. See section 1.9 of the OpenACC 2.0 specification.

This is the main topic of discussion within the OpenACC standards committee and several proposals are in progress. While we are experimenting with solutions as well, until defined by the standard it’s not something we officially support.

Personally I’ve been working on dynamic memory within C++ classes, but that’s a bit easier since I can encapsulate the deep-copy into the class itself. Though the same ideas would apply here.

For this code you may just need to create “img_arrays” and then copyin “wavefield”. “wavefield” will then get “attached” (i.e. the dynamic array is created on the device then the associated pointer member in the type gets updated with this address).

Something like:

   !$acc data create(b) copy(b%x)
   !$acc parallel present(b,b%x)
   do i = 2,VL-1
      b%x(i) = (a0(i-1)*a0(i+1)) + a0(i)
   enddo
   !$acc end parallel
   !$acc end data

Again, this is experimental and may change once the OpenACC standard is updated.

Hope this helps,
Mat

Thanks.

If I create a pointer to the allocatable matrix, is that an acceptable solution?

integer, dimension(:,:,:,:), pointer  :: wavefield_ptr
allocate(img_arrays%wavefield(x,v,y,n))
wavefield_ptr=>img_arrays%wavefield

!$acc data create(wavefield_ptr)

Yes, that will work as well. Of course you need access the pointer in the compute region and not the member.

  • Mat