2016-08-31 3 views
1

gfortran теперь поддерживает host_data, поэтому мне захотелось протестировать DGEMM. На основании теста размещена здесьOpenACC с ошибкой вызова DGEMM в gfortran

host_data patch

Я написал пример кода для DGEMM с помощью cuBLAS.

program test 

    use iso_c_binding 

    implicit none 

    integer(c_int), parameter :: N = 10 
    integer(c_int) :: i, j 
    real(c_double) :: x(N, N), y(N, N), z(N, N) 
    character(kind=c_char)  :: flag 

    interface 
    subroutine cublasdgemm(transa, transb, m, n, k, alpha, A, lda, B, & 
      ldb, beta, C, ldc) bind(c, name="cublasDgemm") 
     use iso_c_binding 
     character(kind=c_char)  :: transa, transb 
     integer(kind=c_int), value :: m, n, k 
     real(c_double), value  :: alpha 
     type(*), dimension(*)  :: A 
     integer(kind=c_int), value :: lda 
     type(*), dimension(*)  :: B 
     integer(kind=c_int), value :: ldb 
     real(c_double), value  :: beta 
     type(*), dimension(*)  :: C 
     integer(kind=c_int), value :: ldc 

    end subroutine cublasdgemm 

    end interface 

    do i = 1, N 
    do j = 1, N 
     x(i, j) = 4.0 * i 
     y(i, j) = 3.0 + j 
     z(i, j) = 0.0 
    end do 
    end do 

    flag = 'N' 

    !$acc data copyin (x, y) copy (z) 

    !$acc host_data use_device (x, y, z) 
    call cublasdgemm(flag, flag, n, n, n, 1.0_c_double, x, n, y, n, 0.0_c_double, z, n) 
    !$acc end host_data 

    !$acc end data 

    call dgemm(flag, flag, n, n, n, 1.0_c_double, x, n, y, n, 0.0_c_double, z, n) 

    write(*, *) z 

end program test 

К сожалению, я получаю эту ошибку.

** On entry to DGEMM parameter number 1 had an illegal value 

Мне кажется, что существует некоторая несоответствие в символьном типе данных. Но я не могу понять. Я положил вызов DGEMM с теми же переменными в конце, и он отлично работает.

Спасибо за любую помощь.

ОБОБЩЕНИЕ:

Для компиляции этого я использую gfortran +6,2 составлен на основании инструкции по этой ссылке

gfortran with nvptx

Я тогда копируют из

/usr/local/cuda/src/ 

файловсписок

fortran_common.h 
fortran.h 
fortran.c 

, а затем сделать

gcc -Wall -g -I/usr/local/cuda/include -I/usr/local/cuda/src -DCUBLAS_GFORTRAN -c fortran.c 

, чтобы получить файл fortran.o для интерфейса cuBLAS.

Тогда я

gfortran -Wall -g test.f90 fortran.o -fopenacc -foffload=nvptx-none -foffload=-O3 -O3 -o gpu.x -L/usr/local/cuda/lib64 -lcublas -lcudart -lblas 

Это процесс, который я использовал, чтобы успешно запустить saxpy пример в первой ссылке.

+0

Согласно документации [здесь] (http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemm) первый аргумент 'cublasdgemm' должен быть какой-то а не стандартная опция транспонирования dgemm. Другими словами, 'cublasdgemm' не имеет того же интерфейса, что и' dgemm'. Конечно, если версия 'saxpy' работает, тогда это может быть не так. –

+0

Спасибо. Раньше я этого не видел. С другой стороны, файл fortran.c имеет cublasDgemm (transa [0], transb [0], * m, * n, * k, * alpha, A, * lda, B, * ldb, * beta, C , * ldc) И это функция, которую я предполагаю, что мы взаимодействуем. Кроме того, как вы отметили, пример saxpy отлично работает. – Vikram

ответ

1

Оказывается, ответ был довольно прост. Мне пришлось добавить «значение» к определению символьных переменных.

subroutine cublasdgemm(transa, transb, m, n, k, alpha, A, lda, B, & 
      ldb, beta, C, ldc) bind(c, name="cublasDgemm") 
     use iso_c_binding 
     character(kind=c_char), value  :: transa, transb 
     integer(kind=c_int), value :: m, n, k 
     real(c_double), value  :: alpha 
     type(*), dimension(*)  :: A 
     integer(kind=c_int), value :: lda 
     type(*), dimension(*)  :: B 
     integer(kind=c_int), value :: ldb 
     real(c_double), value  :: beta 
     type(*), dimension(*)  :: C 
     integer(kind=c_int), value :: ldc 

    end subroutine cublasdgemm 
Смежные вопросы