主机发出的值不能由使用CUDA Fortran的设备正确返回

时间:2017-04-11 08:16:20

标签: parallel-processing cuda fortran gpgpu pgi

我举了一个关于CUDA Fortran的Host和Device之间数据传输的例子,发现了这个:

主机代码:

program incTest  
    use cudafor
    use simpleOps_m
    implicit none
    integer, parameter :: n = 256
    integer :: a(n), b, i
    integer, device :: a_d(n)
    a = 1
    b = 3
    a_d = a
    call inc<<<1,n>>>(a_d, b)
    a = a_d
    if (all(a == 4)) then
        write(*,*) 'Success'
    endif
end program incTest

设备代码:

module simpleOps_m
contains
    attributes(global) subroutine inc(a, b)
        implicit none
        integer :: a(:)
        integer, value :: b
        integer :: i
        i = threadIdx%x
        a(i) = a(i)+b
    end subroutine inc
end module simpleOps_m

预期结果是控制台呈现&#34;成功&#34;,但这没有发生。屏幕上没有任何内容,没有任何错误或消息。 发生这种情况是因为不要输入if,因为a_d具有与调用inc子例程之前相同的值。

我正在使用:

操作系统:Linux - Ubuntu 16

Cuda 8

PGI编译

要编译的命令:

pgf90 -Mcuda -c Device.cuf
pgf90 -Mcuda -c Host.cuf
pgf90 -Mcuda -o HostDevice Device.o Host.o
./HostDevice

我尝试了其他一些例子,但它们也没有用。

我尝试使用简单的Fortran(.f90)代码和相同的命令进行编译,然后才能运行!

如何解决此问题?

1 个答案:

答案 0 :(得分:1)

您使用的是哪种类型的设备? (如果您不知道,请发布&#34; pgaccelinfo&#34;实用程序的输出)。

我最好的猜测是你有一个基于Pascal的设备,在这种情况下你需要使用&#34; -Mcuda = cc60&#34;进行编译。

例如,如果我将错误检查添加到示例代码中,我们会发现在没有&#34; cc60&#34;的情况下在Pascal上运行时会出现无效的设备内核错误。作为汇编的一部分。

% cat test.cuf 
 module simpleOps_m 
      contains 
          attributes(global) subroutine inc(a, b) 
              implicit none 
              integer :: a(:) 
              integer, value :: b 
              integer :: i 
              i = threadIdx%x 
              a(i) = a(i)+b 
          end subroutine inc 
  end module simpleOps_m 

 program incTest 
          use cudafor 
          use simpleOps_m 
          implicit none 
          integer, parameter :: n = 256 
          integer :: a(n), b, i, istat 
          integer, device :: a_d(n) 
          a = 1 
          b = 3 
          a_d = a 
          call inc<<<1,n>>>(a_d, b) 
          istat=cudaDeviceSynchronize() 
          istat=cudaGetLastError() 
          a = a_d 
          if (all(a == 4)) then 
              write(*,*) 'Success' 
          else 
              write(*,*) 'Error code:', cudaGetErrorString(istat) 
          endif 
  end program incTest 
 % pgf90 test.cuf -Mcuda 
 % a.out 
  Error code: 
  invalid device function                                                        
 % pgf90 test.cuf -Mcuda=cc60 
 % a.out 
  Success