Значение, отправленное хостом, не возвращается правильно устройством, использующим CUDA Fortran
Я взял пример передачи данных между хостом и устройством для CUDA Fortran и нашел это:
Код хоста:
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
Ожидаемый результат - консоль, представляющая "Успех", но этого не произошло. На экране ничего не появляется, нет ошибок или сообщений. Это происходит потому, что не вводите в if, потому что a_d имеет то же значение, что и до вызова inc подпрограммы.
Я использую:
ОС: Linux - Ubuntu 16
Куда 8
PGI для компиляции
Команды для компиляции:
pgf90 -Mcuda -c Device.cuf
pgf90 -Mcuda -c Host.cuf
pgf90 -Mcuda -o HostDevice Device.o Host.o
./HostDevice
Я пробовал другие примеры, и они тоже не работали.
Я попытался использовать простой код Fortran (.f90) с теми же командами для компиляции, и это работает!
Как я могу исправить эту проблему?
1 ответ
Какой тип устройства вы используете? (Если вы не знаете, опубликуйте вывод утилиты pgaccelinfo).
Мое лучшее предположение, что у вас есть устройство на основе Pascal, в этом случае вам нужно скомпилировать с "-Mcuda=cc60".
Например, если я добавлю проверку ошибок в пример кода, мы увидим, что мы получаем недопустимую ошибку ядра устройства при запуске на Pascal без "cc60" как часть компиляции.
% 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