02 сент. 2014 г., 18:23 от Michael

Вызов внутренней подпрограммы внутри региона OpenMP

У меня есть модуль, который содержит подпрограмму, которая содержит другую подпрограмму. Внешняя подпрограмма имеет параллельную область OpenMP, в которой я называю внутреннюю подпрограмму. Код компилируется и запускается без ошибок, но результаты неверны.

module my_module
contains
    subroutine a(...)
        *...some variables*
        !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(...)
        *...do some work*
         call b(...)

        !$OMP END PARALLEL DO
    contains
        subroutine b(...)
            *...some variables*
            *...do some work*
        end subroutine b
   end subroutine a
end my module

Если я запускаю отладчик Intelidb, он покажет мне SIGSEGV внутриsubroutine b, Теперь, если я вручную заменю содержимоеsubroutine b внутриsubroutine a вместо того, чтобы вызывать его и сохранять предложения OMP, он не будет выдавать ошибку SIGSEGV, и результаты теперь верны.

РЕДАКТИРОВАТЬ: Полный код здесь:https://github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f90 Это модуль, содержащий подпрограмму для решения уравнений жидкости Эйлера. Если я бегуidb, это даст следующее:

EDIT2: Просто удалось написать меньший пример, который воспроизводит эту ошибку:

module some_module
    implicit none
contains 
    subroutine sub0()
        real :: a(5)
        integer :: i
        a(:) = 0
        !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(a)
        do i = 1, 5
            call sub1()
        end do
        !$OMP END PARALLEL DO
        print*, a(:)
    contains
        subroutine sub1()
            a(i) = a(i) + 1
        end subroutine sub1
    end subroutine sub0
end module some_module

program main
    use some_module
    implicit none
    call sub0()
end program main

Программа должна распечатать1.000000 1.000000 1.000000 1.000000 1.000000, Ниже приведены различные флаги компиляции, которые я пробовал: (компилятор ifort 14.0.2)

ifort name.f90 -check bounds -traceback -O0 - отлично работает без OpenMP

ifort name.f90 -openmp -check bounds -traceback -O0 - дает индекс массива вне границ.

ifort name.f90 -openmp -check bounds -traceback - буду работать

Таким образом, в основном, ошибка покажет, когда я использую-O0, Однако это не означает, что ошибка отсутствует, когда я не использую-O0 (Я говорю это, потому что мой оригинальный код даст неправильные результаты). Кроме того, если я передам индексi явно, то есть:

....
call sub1(i) 
....
contains
    subroutine sub1(i)
        integer i
....

а затем скомпилировать с-O0, это будет работать снова. Поэтому я подозреваю, что OpenMP испытывает проблемы с наследованием переменнойi своим дочерним подпрограммам.

Ответы на вопрос (0)

02 сент. 2014 г., 19:43 от 41k

https://software.intel.com/en-us/forums/topic/297424 также есть некоторые сомнения. Возможно, это просто неправильно реализовано в Intel Fortran, но нужно будет внимательно прочитать официальные спецификации.

В вашем случае я бы избежал необходимости в ассоциации хостов, вставив код процедуры непосредственно в цикл, как вы тоже пытались.

Другой вариант - передать приватные переменные в качестве фиктивных аргументов, как предлагается в ссылочном потоке, который также избегает ассоциации хоста.

Я не уверен, поможет ли использование одного достаточно высокого уровня оптимизации, вероятно, небезопасно встраивать.

Я также получаю ту же ошибку с Oracle Solaris Studio 12.4beta.

Согласно IanH:

«Ссылка на i внутри внутренней подпрограммы находится в регионе, но не в конструкции. Независимо от того, ссылается ли на i оригинал i перед конструкцией параллельного do, или частная копия вызывается как« неопределенная »в OpenMP 4.0 и раньше. "

Соответствующий раздел из спецификации (OpenMP 4.0 2.14.3.3. 14):

The corresponding original list item. Inside the construct, all references to the original
list item are replaced by references to the new list item. In the rest of the region, it is
unspecified whether references are to the new list item or the original list item.

Это означает, что такого использования следует избегать.

ВАШ ОТВЕТ НА ВОПРОС