2016-08-31 1 views
1

gfortran a maintenant le support de host_data, donc je voulais tester DGEMM. Basé sur le cas de test affiché iciOpenACC avec erreur d'appel DGEMM dans gfortran

host_data patch

J'ai écrit un exemple de code pour DGEMM en utilisant 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 

Malheureusement j'obtiens cette erreur. Il me semble qu'il y a une certaine discordance dans le type de données de caractères. Mais je ne peux pas le comprendre. Je mets l'appel DGEMM avec les mêmes variables à la fin et ça marche parfaitement.

Merci pour toute aide.

COMPILATION:

Pour compiler ce que j'utilise gfortran 6.2 compilé sur la base des instructions à ce lien

gfortran with nvptx

Je puis copiez de

/usr/local/cuda/src/ 

les fichiers

fortran_common.h 
fortran.h 
fortran.c 

puis faire

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

pour obtenir le fichier fortran.o pour interface cuBLAS.

Alors je

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 

Ce processus je courais avec succès l'exemple Saxpy dans le premier lien.

+0

Selon la documentation [ici] (http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemm) le premier argument de 'cublasdgemm' devrait être une sorte de la poignée plutôt que de l'option de transposition 'dgemm' standard. En d'autres termes 'cublasdgemm' n'a pas la même interface que' dgemm'. Bien sûr, si la version 'saxpy' fonctionne, cela peut ne pas être le cas. –

+0

Merci. Je n'avais pas vu ça plus tôt. D'autre part, le fichier fortran.c a cublasDgemm (transa [0], transb [0], * m, * n, * k, * alpha, A, * lda, B, * ldb, * bêta, C , * ldc) Et c'est la fonction que je suppose que nous sommes en interface avec. En outre, comme vous l'avez noté, l'exemple saxpy fonctionne bien. – Vikram

Répondre

1

Il s'avère que la réponse était plutôt simple. J'ai dû ajouter "valeur" à la définition des variables de caractères.

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