My parallel code is fixed

Hi All,

A follow-up to my post from last week regarding my parallel code being broke. It seems to be fixed now, and here is what I did. The basic structure is like this:

program main
!
call read_input(args1)
call read_data(args2)
!
!$omp parallel firstprivate args3
!$omp do
do iloop=1,Nloop
  call sub1(args4)
end do
!$omp end do
!$omp end parallel
end
!
subroutine sub1(args5)
!
call sub2(args6)
return
end
!
subroutine sub2(args7)
!
real*8 body01pos_x,body01pos_y,body01pos_z
real*8 body01vel_x,body01vel_y,body01vel_z
[similar for bodies 2 to 10)
!
DATA body01pos_x/Ndyn*0.0d0/,body01pos_y/Ndyn*0.0d0/
DATA body01pos_z/Ndyn*0.0d0/,body01vel_x/Ndyn*0.0d0/  
DATA body01vel_y/Ndyn*0.0d0/,body01vel_z/Ndyn*0.0d0/ 
!
[repeat for other bodies]
!
call sub3(args8)
!
return
end

Here, args1, args2, etc. represent longs list of variables, including arrays. Note that body01pos_x, etc. are not in the argument list. This code runs fine in serial mode, and also runs fine when compiled with the -mp flag and OMP_NUM_THREADS = 1. If I have more than 1 thread, it won’t run properly.

Here is how I fixed the code:

subroutine sub2(args7)
!
[comment out DATA statements]
!
do i=1,Ndyn
  body01pos_x(i)=0.0d0
  body01pos_y(i)=0.0d0
  body01pos_z(i)=0.0d0
  body01vel_x(i)=0.0d0
  body01vel_y(i)=0.0d0
  body01vel_z(i)=0.0d0
!
[repeat for bodies 2 to 10
end do

Now the code seems to run properly in parallel mode (e.g. sorted output files are the same as the output files from the serial mode).

Here is my question: What is the difference between the DATA statement to initialize the variable arrays (60 in all) and the simple loop? When I started printing out values of body01pos_x right before that final subroutine call in the version with the DATA statement, they were not zero after the first call, in either the serial code or the code compiled with the -mp flag. On the other hand, the values are always zero when using the loop to initialize the variables. Likewise, some elements in body01pos_x were not correct after the call to sub3 when running in parallel (and some were) with the version with the DATA statement.

The evidence suggests that using the DATA statements to initialize the arrays is not the same as using the loop to initialize the arrays. Is this expected FORTRAN 77/90 behavior? Note I have been using gfortran lately and the -fopenmp flag, since PGI recently expired and the new version isn’t installing properly (see my post in the other forum). However, before PGI expired, both compilers gave similar results. There does not seem to be a compiler bug, only a bug in my understanding of FORTRAN.

Jerry

Hi All,

I forgot to mention that body01pos_x, body01pos_y, etc. are arrays, each with a dimension of Ndyn, which currently has a value of 720,000.

Jerry

Hi Jerry,

The evidence suggests that using the DATA statements to initialize the arrays is not the same as using the loop to initialize the arrays. Is this expected FORTRAN 77/90 behavior?

Correct. Variables initialized with a DATA statement implicitly have the SAVE attribute. Hence, these variables are implicitly have global storage and shared amongst the OpenMP threads.

I’ll take a look at you other post regarding installation issues here in a few.

-Mat

Hi Mat,

Thanks for the response. The SAVE attribute in this case does not contribute to the routine being thread-safe.

Jerry