Вызов внутренней подпрограммы внутри региона 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
своим дочерним подпрограммам.