2

Now I want to transfer a piece of a device array to another device array using following code:

program main
  implicit none
  integer :: a(5,5,5,5)
  integer, device :: a_d(5,5,5,5),b_d(5,5,5,5)
  a=0
  a_d=a
  b_d(1:2,:,:,:)=a_d(2:3,:,:,:)
end program

The pgi compiler returns following error for b_d(1:2,:,:,:)=a_d(2:3,:,:,:):

PGF90-S-0519-More than one device-resident object in assignment.

How to solve this problem or, is there an efficient way to transfer only a piece of a device array to another device array?

S.C. Zheng
  • 51
  • 6
  • I ahve zero experience with Fortran, but, can you create an intermediate `integer` that is not in device and copy to there and from there? – Ander Biguri Apr 10 '19 at 12:58
  • 2
    I am pretty sure that answer will be that a slicing copy assignment between two device variables requires running a kernel on the device, unlike a simple assignment which generates a cudaMemcpy call. There might be some sort of fancy cuf loop based solution you could try, or maybe a cudaMemcpy2D call instead. Maybe someone from PGI can chime in.... – talonmies Apr 10 '19 at 14:05

1 Answers1

1

The documentation says the following:

3.4.2. Implicit Data Transfer in Expressions

Some limited data transfer can be enclosed within expressions. In general, the rule of thumb is all arithmetic or operations must occur on the host, which normally only allows one device array to appear on the right-hand-side of an expression.

I'm pretty sure that means that a slicing assignment of the kind you are trying to do is not supported because you have a device array on the left hand side of the expression.

I am not sure what is the best way to solve this. cudaMemcpy2D will definitely work if you can deduce the pitch of the arrays. Hopefully someone from PGI can edit a solution into this community wiki entry.

talonmies
  • 70,661
  • 34
  • 192
  • 269