title: Calling an internal subroutine inside OpenMP region
body: <p>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.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>If I run the Intel Debugger <code>idb</code>, it will show me a SIGSEGV inside <code>subroutine b</code>. Now, if I manually replace the content of <code>subroutine b</code> inside <code>subroutine a</code> instead of calling it, and keeping the OMP clauses, it will not throw SIGSEGV error and the results are now correct.</p>
  
  <p><strong>EDIT:</strong> Full code is here: <a href="https://github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f90" rel="nofollow noreferrer">https://github.com/mikolchon/cfd/blob/master/cfd2/calcRHS.f90</a>
  It's a module containing a subroutine to solve Euler fluid equations. If I run the <code>idb</code>, it will give the following:</p>
  
  <p><img src="https://i.stack.imgur.com/6ScYN.png" alt="&lt;code&gt;idb&lt;/code&gt; message"></p>
  
  <p><strong>EDIT2:</strong> Just managed to write a smaller example that reproduces this error:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The program should print <code>1.000000 1.000000 1.000000 1.000000 1.000000</code>. The following are different compilation flags I tried: (compiler is ifort 14.0.2)</p>
  
  <p><code>ifort name.f90 -check bounds -traceback -O0</code> - works fine without OpenMP</p>
  
  <p><code>ifort name.f90 -openmp -check bounds -traceback -O0</code> - gives array index out of bound.</p>
  
  <p><code>ifort name.f90 -openmp -check bounds -traceback</code> - will work</p>
  
  <p>So basically, the error will show when I use <code>-O0</code>. However, that doesn't mean that the error is absent when I don't use <code>-O0</code> (I say this because my original code will give wrong results). Also, if I pass the index <code>i</code> explicitly, that is:</p>
  
  <pre><code>....
  call sub1(i) 
  ....
  contains
      subroutine sub1(i)
          integer i
  ....
  </code></pre>
  
  <p>and then compile with <code>-O0</code>, it will work again. So my suspicion is that OpenMP is having trouble inheriting the variable <code>i</code> to its child subroutines.</p>