title: OpenMP SIMD vectorization of nested loop
body: <p>I am trying to vectorize a nested loop using OpenMP 4.0's <code>simd</code> feature, but I'm afraid I'm doing it wrong. My loops looks like this:</p>
  
  <pre><code>do iy = iyfirst, iylast
      do ix = ixfirst, ixlast
  
          !$omp simd
          do iz = izfirst, izlast
  
              dudx(iz,ix,iy) = ax(1)*( u(iz,ix,iy) - u(iz,ix-1,iy) )
              do ishift = 2, ophalf
                  dudx(iz,ix,iy) = dudx(iz,ix,iy) + ax(ishift)*( u(iz,ix+ishift-1,iy) - u(iz,ix-ishift,iy) )
              enddo
  
              dudx(iz,ix,iy) = dudx(iz,ix,iy)*buoy_x(iz,ix,iy)
  
          enddo
          !$omp end simd
  
      enddo
  enddo
  </code></pre>
  
  <p>Note that <code>ophalf</code> is a small integer, usually 2 or 4, so it makes sense to vectorize the <code>iz</code> loop and not the inner-most loop.</p>
  
  <p>My question is: <strong>Do I have to mark <code>ishift</code> as a private variable?</strong> </p>
  
  <p>In standard OpenMP <code>parallel do</code> loops, you certainly do need a <code>private(ishift)</code> to ensure other threads don't stomp over each other's data. Yet when I instead rewrite the first line as <code>!$omp simd private(ishift)</code>, I get the ifort compilation error:</p>
  
  <blockquote>
    <p>error #8592: Within a SIMD region, a DO-loop control-variable must not be specified in a PRIVATE SIMD clause.   [ISHIFT]</p>
  </blockquote>
  
  <p>Looking online, I couldn't find any successful resolution of this question. It seems to me that <code>ishift</code> should be private, but the compiler is not allowing it. Is an inner-loop variable automatically forced to be private?</p>
  
  <p>Follow-up question: Later, when I add an <code>omp parallel do</code> around the <code>iy</code> loop, should I include a <code>private(ishift)</code> clause in the <code>omp parallel do</code> directive, the <code>omp simd</code> directive, or both? </p>
  
  <p>Thanks for any clarifications.</p>