#fortran #openacc #pgi-accelerator
#fortran #openacc #pgi-ускоритель
Вопрос:
В настоящее время я ускоряю код Fortran, где у меня есть основной ускоренный цикл в подпрограмме sub
. В цикле я хочу вызвать подпрограмму subsub
на устройстве с acc routine
помощью . Подпрограмма имеет intent(out)
аргумент val
, который является закрытым в цикле. Как subsub
и в самом цикле, я хочу использовать vector
предложение:
module calc
implicit none
public :: sub
private
contains
subroutine sub()
integer :: i
integer :: array(10)
integer :: val
!$acc kernels loop independent private(val)
do i = 1, 10
call subsub(val)
array(i) = val
enddo
print "(10(i0, x))", array
endsubroutine
subroutine subsub(val)
!$acc routine vector
integer, intent(out) :: val
integer :: i
val = 0
!$acc loop independent reduction( :val)
do i = 1, 10
val = val 1
enddo
endsubroutine
endmodule
program test
use calc, only: sub
implicit none
call sub()
endprogram
При компиляции с помощью компилятора PGI версии 20.9-0 и запуске программы я получаю бессмысленные значения в переменной array
. Когда я просто использую acc routine
for subsub
, я получаю правильное поведение (10 во всех значениях array
). Что не так в моем подходе к распараллеливанию этой подпрограммы?
Ответ №1:
Это похоже на проблему генерации кода компилятора в отношении того, как val обрабатывается в основном цикле. К счастью, обходной путь прост, просто добавьте установку val в основной цикл.
% cat test.f90
module calc
implicit none
public :: sub
private
contains
subroutine sub()
integer :: i
integer :: array(10)
integer :: val
!$acc kernels loop independent private(val)
do i = 1, 10
val = 0
call subsub(val)
array(i) = val
enddo
print "(10(i0, x))", array
endsubroutine
subroutine subsub(val)
!$acc routine vector
integer, intent(out) :: val
integer :: i
val = 0
!$acc loop independent reduction( :val)
do i = 1, 10
val = val 1
enddo
endsubroutine
endmodule
program test
use calc, only: sub
implicit none
call sub()
endprogram
% nvfortran -acc -Minfo=accel test.f90 -V20.9 ; a.out
sub:
10, Generating implicit copyout(array(:)) [if not already present]
11, Loop is parallelizable
Generating Tesla code
11, !$acc loop gang ! blockidx%x
subsub:
18, Generating Tesla code
24, !$acc loop vector ! threadidx%x
Generating reduction( :val)
Vector barrier inserted for vector loop reduction
24, Loop is parallelizable
10 10 10 10 10 10 10 10 10 10