Закрытое условие цикла OpenACC и условие гонки - PullRequest
1 голос
/ 25 марта 2019

Я пытаюсь использовать рабочий-приватный массив с 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

1 Ответ

1 голос
/ 25 марта 2019

Похоже на проблему компилятора, когда работники совместно используют tmp вместо того, чтобы каждый работник получал личную копию. Это в свою очередь вызывает состояние гонки в вашем коде.

Я отправил сообщение о проблеме в PGI (TPR # 27025) и отправил его нашим инженерам для дальнейшего изучения.

Обходной путь - использовать «gang» вместо «worker» во внешнем цикле или, как вы заметили, сделать «tmp» как одномерный массив.

...