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
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 –
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
* "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 –