Значение, отправленное хостом, не возвращается правильно устройством, использующим 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 
Другие вопросы по тегам