Chamando uma sub-rotina interna na região do OpenMP
Eu tenho um módulo que contém uma sub-rotina que contém outra sub-rotina. A sub-rotina externa possui uma região OpenMP paralela na qual chamo de sub-rotina interna. O código compila e executa sem nenhum erro, mas os resultados não estão corretos.
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
Se eu executar o Intel Debuggeridb
, ele me mostrará um SIGSEGV dentrosubroutine b
. Agora, se eu substituir manualmente o conteúdo desubroutine b
dentrosubroutine a
em vez de chamá-lo e manter as cláusulas OMP, ele não emitirá erro SIGSEGV e os resultados agora estão corretos.
EDITAR: O código completo está aqui:https://github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f90 É um módulo que contém uma sub-rotina para resolver equações de fluido de Euler. Se eu executar oidb
, fornecerá o seguinte:
EDIT2: Acabei de escrever um exemplo menor que reproduz esse erro:
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
O programa deve imprimir1.000000 1.000000 1.000000 1.000000 1.000000
. A seguir, tentei diferentes sinalizadores de compilação: (o compilador é ifort 14.0.2)
ifort name.f90 -check bounds -traceback -O0
- funciona bem sem o OpenMP
ifort name.f90 -openmp -check bounds -traceback -O0
- dá o índice da matriz fora do limite.
ifort name.f90 -openmp -check bounds -traceback
- vai funcionar
Então, basicamente, o erro será exibido quando eu uso-O0
. No entanto, isso não significa que o erro esteja ausente quando eu não uso-O0
(Eu digo isso porque meu código original dará resultados incorretos). Além disso, se eu passar o índicei
explicitamente, isto é:
....
call sub1(i)
....
contains
subroutine sub1(i)
integer i
....
e depois compile com-O0
, funcionará novamente. Então, minha suspeita é que o OpenMP esteja tendo problemas para herdar a variáveli
às suas sub-rotinas filho.