I have a module that contains a subroutine that contains another subroutine. The outer subroutine has a parallel OpenMP region in which I call the inner subroutine. The code compiles and runs without any error but the results are not correct.
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
If I run the Intel Debugger idb
, it will show me a SIGSEGV inside subroutine b
. Now, if I manually replace the content of subroutine b
inside subroutine a
instead of calling it, and keeping the OMP clauses, it will not throw SIGSEGV error and the results are now correct.
EDIT: Full code is here: https://github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f90
It's a module containing a subroutine to solve Euler fluid equations. If I run the idb
, it will give the following:
EDIT2: Just managed to write a smaller example that reproduces this error:
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
The program should print 1.000000 1.000000 1.000000 1.000000 1.000000
. The following are different compilation flags I tried: (compiler is ifort 14.0.2)
ifort name.f90 -check bounds -traceback -O0
- works fine without OpenMP
ifort name.f90 -openmp -check bounds -traceback -O0
- gives array index out of bound.
ifort name.f90 -openmp -check bounds -traceback
- will work
So basically, the error will show when I use -O0
. However, that doesn't mean that the error is absent when I don't use -O0
(I say this because my original code will give wrong results). Also, if I pass the index i
explicitly, that is:
....
call sub1(i)
....
contains
subroutine sub1(i)
integer i
....
and then compile with -O0
, it will work again. So my suspicion is that OpenMP is having trouble inheriting the variable i
to its child subroutines.
See Question&Answers more detail:
os