Как подпрограмма Fortran-OpenACC может вызвать другую подпрограмму Fortran-OpenACC?

В настоящее время я пытаюсь ускорить анализатор жидкостей спектрального элемента, перенося большинство подпрограмм на GPGPU с использованием OpenACC с компилятором PGI (15.10). Исходный код написан на OO-Fortran. Это программное обеспечение имеет "слои" подпрограмм, которые вызывают другие функции и подпрограммы. Чтобы перенести код в графический процессор с помощью openacc, я сначала попытался поместить директивы "$acc рутина" в каждую подпрограмму, которую нужно перенести. Во время компиляции, используя "pgf90 -acc -Minfo=accel", я получаю следующую ошибку:

Ошибка nvvmCompileProgram: 9.

Ошибка: /tmp/pgacc2lMnIf9lMqx8.gpu (146, 24): проанализировать недопустимую прямую ссылку на функцию 'innerroutine_' с неверным типом!

PGF90-S-0155-Compiler не удалось преобразовать область акселератора (см. Сообщения -Minfo): Компилятор устройства завершил работу с кодом ошибки (Test.f90: 1)

Эта же проблема может быть воспроизведена с помощью следующей простой программы на Фортране:

PROGRAM Test
IMPLICIT NONE

CONTAINS

 SUBROUTINE OuterRoutine( sol, xF, N )
 !$acc routine
   IMPLICIT NONE
   INTEGER :: N
   REAL(KIND=8) :: sol(0:N,1:3)
   REAL(KIND=8) :: xF(0:N,1:3)
   ! LOCAL
   INTEGER :: i

      DO i = 0, N
         xF(i,1:3) = InnerRoutine( sol(i,1:3) )
      ENDDO

 END SUBROUTINE OuterRoutine
 FUNCTION InnerRoutine( sol ) RESULT( xF )
 !$acc routine
   IMPLICIT NONE
   REAL(KIND=8) :: sol(1:3)
   REAL(KIND=8) :: xF(1:3)

      xF(1) = sol(1)*sol(2)
      xF(2) = sol(1)*sol(3)
      xF(3) = sol(1)*sol(1)

 END FUNCTION InnerRoutine

END PROGRAM Test

Снова, компиляция вышеупомянутой программы с "pgf90 -acc -Minfo = accel" приводит к проблеме.

Поддерживает ли openacc подпрограммы с поддержкой acc, вызывая другие подпрограммы с поддержкой acc?

Если так, что я делаю не так?

1 ответ

Решение

Вы правильно используете директиву "рутины" OpenACC. Проблема здесь в том, что мы (PGI) еще не поддерживаем использование "рутины" с массивными функциями. Проблема в том, что эта поддержка требует, чтобы компилятор создал временный массив для хранения возвращаемого значения. Это означает, что каждый поток должен будет выделить этот временный массив, что приведет к серьезному снижению производительности. Хуже всего то, как справиться с совместным использованием временного массива, если это бригада или подпрограмма рабочего уровня.

У нас есть открытые запросы на эту функцию, но может пройти некоторое время, прежде чем мы сможем ее решить. В то же время, вы можете попробовать включить рутину? т.е. компилировать с "-Minline".

Другие вопросы по тегам