Как подпрограмма 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".