I have used 8 threads for 8 loops. I have used 'print' to see how the parallel code works. The 0 thread creates problems!I have showed in the attached diagram (please check the attached link below) how the parallel works. I have used threadprivate but it turned out that thread 0 can not get any private threadsafe variables.
I have tried with modules as well and got same results! Any idea why the code acts this way? I would appreciate any help or suggestion. Thanks!
!$OMP PARALLEL DO
do nb=m3+1, m3a, 2
60 icall=nb
65 iad=idint(a(icall))
if(iad.eq.0) goto 100
call ford(a(iad),servo)
if(.not.dflag) goto 80
atemp=dble(nemc)
nemc=iad
a(icall)=a(iad+6)
a(iad+6) = atemp
dflag=.false.
goto 65
80 icall=iad+6
goto 65
100 continue
end do
!$OMP END PARALLEL DO
subroutine FORD(i,j)
dimension zl(3),zg(3)
common /ellip/ b1,c1,f1,g1,h1,d1,
. b2,c2,f2,g2,h2,p2,q2,r2,d2
common /root/ root1,root2
!$OMP threadprivate (/ellip/,/root/)
CALL CONDACT(genflg,lapflg)
return
end subroutine
SUBROUTINE CONDACT(genflg,lapflg)
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
!$OMP threadprivate (/ellip/)
RETURN
END
Looking at just the first few lines you have major problems.
This part is fine, each thread will have a private copy of
nb
properly initialized.This is a problem.
icall
is shared and each thread will write its private value ofnb
into the shared. Threads run concurrently and the order and timing is non-determanistic so the value oficall
in each thread cannot be known ahead of time.Now we use
icall
to calculate a value to store in the shared variableiad
. What are the problems? The value oficall
may not be the same as in the previous line if another thread wrote to it between this thread's execution. The value ofiad
is being clobbered by each thread.These lines have the same problems as above. The value of
iad
may not be the same as above and it may not be the same between these two lines depending on the execution of the other threads.The variable
dflag
has not been initialized at this point.To fix these problems you need to declare
icall
andiad
as private withYou should also initialize
dflag
before you use it.These first errors are probably responsible for a large chunk of your problem but may not fix everything. You have architected very complex (hard to maintain) thread interaction and your code is full of bad practices (implicit variables, liberal use of
goto
) which make this code hard to follow.