Я пытаюсь использовать рабочий-приватный массив с OpenACC, но получаю неправильные результаты. Я предполагаю, что происходит какая-то проблема с условиями гонки, но я не могу найти где.
Я использую компилятор PGI (18.10, OpenPower) и компилирую с:
pgf90 -gopt -O3 -Minfo=all -Mcuda=ptxinfo -acc -ta=tesla:cc35 main.F90
Вот минимальный пример того, чего я пытаюсь достичь:
#define lx 7000
#define ly 500
program test
implicit none
integer :: tmp(ly,1), a(lx,ly), b(lx,ly)
integer :: x,y,i
do x=1,lx
do y=1,ly
a(x,y) = x+y
end do
end do
!$acc parallel num_gangs(1)
!$acc loop worker private(tmp)
do x=1,lx
!$acc loop vector
do y=1,ly
tmp(y,1) = -a(x,y)
end do
!$acc loop vector
do y=1,ly
b(x,y) = -tmp(y,1)
end do
end do
!$acc end parallel
print *, "check"
do x=1,lx
do y=1,ly
if(b(x,y) /= x+y) print *, x, y, b(x,y), x+y
end do
end do
print*, "end"
end program
Я ожидал получить b == a, но это не так.
Обратите внимание, что я определил tmp(ly,1)
, потому что я получаю ожидаемый результат, когда определяю tmp(ly)
как одномерный массив. Даже если он работает с одномерным массивом, я не уверен, что он полностью соответствует стандарту OpenACC.
Я что-то здесь упускаю?
РЕДАКТИРОВАТЬ: последний цикл проверяет, если a == b и печатает неправильные значения. Ожидаемый результат (который я получаю с отключенным OpenACC):
check
end
То, что я получаю с включенным OpenACC, выглядит примерно так (изменения между запусками):
check
1 1 5 2
1 2 6 3
1 3 7 4
[...]
end