How to do "a_d = -b_d" in the device?

a_d and b_d are two device arrays. It seems that we can not put “a_d = -b_d” directly in the code. How can I do it, please?

Is the following the best one?


a_d = 0.0
call cublas_device_saxpy (n, -1.0, b_d, 1, a_d, 1)

Hi happyfish,

It seems that we can not put “a_d = -b_d” directly in the code.

Correct. A straight device to device array copy can be translated into a call to cudaMemCopy, but any transformation of the data requires a kernel call. The easiest way to do this is to put the transformation in a loop and have the compiler create the kernel for you, via the “cuf” directive.

For example:

!$cuf kernel do (1) <<< *,* >>>
  do idx=1,N
       dB(idx) = -dA(idx)

Hope this helps,

Many thanks. It seems that the “cuf” directive does not work for me. My file “q.cuf” is like this:

        PROGRAM main
        use cudafor


        INTEGER, PARAMETER :: M = 512
        INTEGER :: i,j

        complex*16, device::A_d(M,M),B_d(M,M)

        B_d = 2.0

        !$cuf kernel do (1) <<< *,256 >>>
        do i=1,M
            do j=1,M
                 A_d(i,j) = -B_d(i,j)

I compile it with the command:

pgf90 q.cuf -o q

or pgf90 -Mcuda q.cuf -o q

I always get this error:

PGF90-S-0155-more than one device-resident object in assignment (q.cuf: 18)

Line 18 is “B_d(i,j) = -A_d(i,j)”

So, what is wrong, please?

It seems that the sentence "!$cuf kernel do (1) <<< *,256 >>> " is considered as a comment.

Hi Happyfish,

Your code compiles fine for me, hence something else is wrong. We didn’t add the CUF directive till the 11.1 release, are you using an earlier compiler version? If so, then you’ll need to update your compiler or write a small kernel to perform the copy.

  • Mat
% pgf90 -Mcuda q.cuf -V12.9 -Minfo
     15, CUDA kernel generated
         15, !$cuf kernel do <<< (*), (256) >>>