我举了一个关于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)代码和相同的命令进行编译,然后才能运行!
如何解决此问题?
答案 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