OpenMP in Fortran 90 produces bad results in nested loops

The following nested loops run correctly if I compile with the OpenMP directives disabled and run sequential. However if I enable OpenMP I get invalid results running either single or multi-threaded. All the arrays are dimensioned the same and the j,i loops run the full range of their dimensions.

          !$OMP PARALLEL  PRIVATE(j,i,duxdx,duzdz,duxdz,duzdx,dtx,dtz) &
          !$OMP  shared(a1,a2,a3,a4,a5)
          !$OMP do
            do j=-ntaper+1,mx+ntaper
              do i=ntaper_z0,mz+ntaper
                duxdx  = a1*(sxx(i,j+1)-  sxx(i,j))+ &
     &                   a2*(sxx(i,j+2)-sxx(i,j-1))+ &
     &                   a3*(sxx(i,j+3)-sxx(i,j-2))+ &
     &                   a4*(sxx(i,j+4)-sxx(i,j-3))+ &
     &                   a5*(sxx(i,j+5)-sxx(i,j-4))
                duxdz  = a1*(sxz(i+1,j)-sxz(i,j))  + &
     &                   a2*(sxz(i+2,j)-sxz(i-1,j))+ &
     &                   a3*(sxz(i+3,j)-sxz(i-2,j))+ &
     &                   a4*(sxz(i+4,j)-sxz(i-3,j))+ &
     &                   a5*(sxz(i+5,j)-sxz(i-4,j))
                duzdz  = a1*(szz(i,j)-  szz(i-1,j))+ &
     &                   a2*(szz(i+1,j)-szz(i-2,j))+ &
     &                   a3*(szz(i+2,j)-szz(i-3,j))+ &
     &                   a4*(szz(i+3,j)-szz(i-4,j))+ &
     &                   a5*(szz(i+4,j)-szz(i-5,j))
                duzdx  = a1*(sxz(i,j) - sxz(i,j-1))+ &
     &                   a2*(sxz(i,j+1)-sxz(i,j-2))+ &
     &                   a3*(sxz(i,j+2)-sxz(i,j-3))+ &
     &                   a4*(sxz(i,j+3)-sxz(i,j-4))+ &
     &                   a5*(sxz(i,j+4)-sxz(i,j-5))
            ux(i,j)=ux(i,j)+ (dtx*duxdx + dtz*duxdz) * rho(i,j)
            uz(i,j) = uz(i,j)+(dtx*duzdx + dtz*duzdz) * rho(i,j)

              end do
            end do
            !$OMP end do
            !$OMP END PARALLEL

This is the first time I have tried to run OpenMP in Fortran 90. Usually my code is in Fortran 77.

Do you have any suggestions?

Hi Richard,

You have “dtx” and “dtz” in the PRIVATE clause. Private variables are assumed to be uninitialized. Hence, you need to either put these into a “FIRSTPRIVATE” clause or keep them shared.

While it doesn’t hurt, loop index variables are private by default, so no need to put j and i in the private clause.

Hope this helps,


Thanks that did the trick. After posting, I noticed those two were private and did not need to be.

I now get the expected results.