2017-07-31 2 views
0

Je lis la copie en profondeur manuelle de types dérivés de Fortran est possible, mais le programme de test simple suivant échoue à l'exécution; programme compilé proprement avec PGI v16.10. Qu'est-ce qui ne va pas?Types dérivés de fortran openacc avec allocable

program Test 

    implicit none 

    type dt 
     integer :: n 
     real, dimension(:), allocatable :: xm 
    end type dt 

    type(dt) :: grid 
    integer :: i 

    grid%n = 10 
    allocate(grid%xm(grid%n)) 

!$acc enter data copyin(grid) 
!$acc enter data pcreate(grid%xm) 

!$acc kernels 
    do i = 1, grid%n 
     grid%xm(i) = i * i 
    enddo 
!$acc end kernels 

    print*,grid%xm 

end program Test 

L'erreur que je reçois est:

call to cuStreamSynchronize returned error 700: Illegal address during kernel execution 
call to cuMemFreeHost returned error 700: Illegal address during kernel execution 
+0

selon la documentation (PGI guide OpenACC, v2015 et v2017): Les tableaux de type dérivé, où le type dérivé contient des membres affectables, n'ont pas été testées et ne devrait pas être considéré comme pris en charge pour cette version. https://stackoverflow.com/questions/45233207/allocatable-arrays-in-cuda-fortran-device-data-structures#comment77460575_45233207 –

+0

Il s'avère que commenter la création de pcreate (grid% xm) fait fonctionner correctement le programme . Cela pourrait-il signifier que la copie en profondeur est maintenant supportée? – danny

+0

* "n'a pas été testé et ne doit pas être considéré comme pris en charge" * ... Bit destiné aux baies. Vous avez une seule variable donc je ne sais pas, essayez de chercher dans le manuel –

Répondre

1

Vous avez juste besoin d'ajouter un "présent (grille)" clause de la directive sur les noyaux.

Voici un exemple de votre programme avec le correctif ainsi que quelques autres choses comme la mise à jour des données afin qu'elles puissent être imprimées sur l'hôte.

% cat test.f90 
program Test 

    implicit none 

    type dt 
     integer :: n 
     real, dimension(:), allocatable :: xm 
    end type dt 

    type(dt) :: grid 
    integer :: i 

    grid%n = 10 
    allocate(grid%xm(grid%n)) 

!$acc enter data copyin(grid) 
!$acc enter data create(grid%xm) 
!$acc kernels present(grid) 
    do i = 1, grid%n 
     grid%xm(i) = i * i 
    enddo 
!$acc end kernels 
!$acc update host(grid%xm) 
    print*,grid%xm 

!$acc exit data delete(grid%xm, grid) 
    deallocate(grid%xm) 

end program Test 

% pgf90 -acc test.f90 -Minfo=accel -ta=tesla -V16.10; a.out 
test: 
    16, Generating enter data copyin(grid) 
    17, Generating enter data create(grid%xm(:)) 
    18, Generating present(grid) 
    19, Loop is parallelizable 
     Accelerator kernel generated 
     Generating Tesla code 
     19, !$acc loop gang, vector(128) ! blockidx%x threadidx%x 
    23, Generating update self(grid%xm(:)) 
    1.000000  4.000000  9.000000  16.00000 
    25.00000  36.00000  49.00000  64.00000 
    81.00000  100.0000 

Notez que PGI 17.7 inclura la copie profonde du support bêta dans Fortran. Par opposition à la copie profonde manuelle que vous avez ci-dessus. Voici un exemple d'utilisation vraie copie profonde:

% cat test_deep.f90 
program Test 

    implicit none 

    type dt 
     integer :: n 
     real, dimension(:), allocatable :: xm 
    end type dt 

    type(dt) :: grid 
    integer :: i 

    grid%n = 10 
    allocate(grid%xm(grid%n)) 

!$acc enter data copyin(grid) 
!$acc kernels present(grid) 
    do i = 1, grid%n 
     grid%xm(i) = i * i 
    enddo 
!$acc end kernels 
!$acc update host(grid) 
    print*,grid%xm 

!$acc exit data delete(grid) 
    deallocate(grid%xm) 

end program Test 

% pgf90 -acc test_deep.f90 -Minfo=accel -ta=tesla:deepcopy -V17.7 ; a.out 
test: 
    16, Generating enter data copyin(grid) 
    17, Generating present(grid) 
    18, Loop is parallelizable 
     Accelerator kernel generated 
     Generating Tesla code 
     18, !$acc loop gang, vector(128) ! blockidx%x threadidx%x 
    22, Generating update self(grid) 
    1.000000  4.000000  9.000000  16.00000 
    25.00000  36.00000  49.00000  64.00000 
    81.00000  100.0000 
+0

Mat, merci beaucoup et je vais utiliser une copie profonde Pourquoi la présente clause est-elle nécessaire, même dans la version 17.7? Copier/présent implicite de la grille, ce que je m'attends à faire quand j'utilise une région de noyaux sans clause de données, fonctionne aussi bien? Merci encore – danny

+1

Je considère cela comme un bug puisque vous avez raison, avec une copie profonde la copie implicite devrait fonctionner La copie profonde accordée est nouvelle et une fonctionnalité bêta afin que ces types de problèmes ne sont pas inattendus. –