Interesting. by intel visual fortran on windows
!$OMP DO
do i = 1, 3
f = f + i
enddo
!$OMP END DO
the above code gives f=6. Some documents say this is impossible for openmp. Your hints would be greatly appreciated.
if(mod(i,2)==0)then
!$omp critical
icnt=icnt+1
a(icnt)=c
!$omp end critical
endif
gonski wrote:Interesting. by intel visual fortran on windows
!$OMP DO
do i = 1, 3
f = f + i
enddo
!$OMP END DO
the above code gives f=6. Some documents say this is impossible for openmp. Your hints would be greatly appreciated.
ejd wrote:gonski wrote:Interesting. by intel visual fortran on windows
!$OMP DO
do i = 1, 3
f = f + i
enddo
!$OMP END DO
the above code gives f=6. Some documents say this is impossible for openmp. Your hints would be greatly appreciated.
. In which case, it could give f=6 (assuming f starts with a value of zero). If it is in a parallel region and you run this with one thread, then you most likely will get f=6. However, if this is in a parallel region and you use multiple threads then you could just as easily get f=3 or f=5.
ejd wrote:I will see if I can answer your questions.
- icnt and jcnt will be a counter in a code. It seems REDUCTION clause is not applicable to them (at least under windows). Is there any other clause available to handle this situations?
A reduction clause is not applicable because you have a data dependency and race condition between lines 20 and 21 for icnt and between lines 25 and 26 for jcnt. You can use a critical section:
- Code: Select all
if(mod(i,2)==0)then
!$omp critical
icnt=icnt+1
a(icnt)=c
!$omp end critical
endif
Note - if you decide to use critical sections in this case, then you should name them differently since they are not dependent on each other.
L=1
c.....OpenMP : Start parallel loop section
c$OMP PARALLEL DO DEFAULT(SHARED), PRIVATE(I
c$OMP* ),
c$OMP* SCHEDULE(RUNTIME)
DO 456 I=1,N-1
call FindNeighour(I)
456 CONTINUE
NINL=L-1
subroutine FindNeighour(I)
use comdemcfd
use comdem
use TmpNei
integer, intent(in):: i
LFIRST(I)=0
LLAST(I)=0
IF(.not.inside(i))return
c get zone
INX=IZONX(I)
INY=IZONY(I)
INZ=IZONZ(I)
IF(INZ.NE.0)THEN
LFIRST(I)=L
RXI=RX(I)
RYI=RY(I)
RZI=RZ(I)
IPD_X=0
IPD_Y=0
IPD_Z=0
IF(rtime.ge.real_time_loop_z)IPD_Z=1
IF(rtime.ge.real_time_loop_x)IPD_X=1
IF(rtime.ge.real_time_loop_y)IPD_Y=1
INXA=INX-1
IF((IPD_X.EQ.0.OR.NZONX.EQ.1).AND.INXA.EQ.0)INXA=1
INXB=INX+1
IF((IPD_X.EQ.0.OR.NZONX.EQ.1).AND.INXB.GT.NZONX)INXB=NZONX
INYA=INY-1
IF((IPD_Y.EQ.0.OR.NZONY.EQ.1).AND.INYA.EQ.0)INYA=1
INYB=INY+1
IF((IPD_Y.EQ.0.OR.NZONY.EQ.1).AND.INYB.GT.NZONY)INYB=NZONY
INZA=INZ-1
IF((IPD_Z.EQ.0.OR.NZONZ.EQ.1).AND.INZA.EQ.0)INZA=1
INZB=INZ+1
IF((IPD_Z.EQ.0.OR.NZONZ.EQ.1).AND.INZB.GT.NZONZ)INZB=NZONZ
DO 455 IX_T=INXA,INXB
DO 455 IY_T=INYA,INYB
DO 455 IZ_T=INZA,INZB
C-----ZONE BOUNDARY AND PERIODIC BOUNDARY
IX=IX_T
IY=IY_T
IZ=IZ_T
IF(IX.EQ.0)IX=NZONX
IF(IX.GT.NZONX)IX=1
IF(IY.EQ.0)IY=NZONY
IF(IY.GT.NZONY)IY=1
IF(IZ.EQ.0)IZ=NZONZ
IF(IZ.GT.NZONZ)IZ=1
J=IHEAD(IX,IY,IZ)
IF(J.EQ.-1)CYCLE
55 IF(J.LE.I)GOTO 454
X=RXI-RX(J)
Y=RYI-RY(J)
Z=RZI-RZ(J)
if(ipd_x.eq.1) then
if(x.gt.rec_x/2.0) then
x=x-rec_x
endif
if(x.lt.(-rec_x/2.0)) then
x=x+rec_x
endif
endif
if(ipd_y.eq.1) then
if(y.gt.rec_y/2.0) then
y=y-rec_y
endif
if(y.lt.(-rec_y/2.0)) then
y=y+rec_y
endif
endif
if(ipd_z.eq.1) then
if(z.gt.rec_z/2.0) then
z=z-rec_z
endif
if(z.lt.(-rec_z/2.0)) then
z=z+rec_z
endif
endif
c normal
RR=X*X+Y*Y+Z*Z
CUB22=(rad(i)+rad(j)+gap)**2
IF (RR.LT.CUB22) THEN
LLIST(L)=J
DISPTX(L)=0.
DISPTY(L)=0.
DISPTZ(L)=0.
FRICP(L)=0.
IF(LFIRST_O(I).NE.0)THEN
DO 66 LO=LFIRST_O(I),LLAST_O(I)
JO=LLIST_O(LO)
IF(JO.EQ.J)THEN
DISPTX(L)=DISPTX_O(LO)
DISPTY(L)=DISPTY_O(LO)
DISPTZ(L)=DISPTZ_O(LO)
FRICP(L)=FRICP_O(LO)
ENDIF
66 CONTINUE
ENDIF
L=L+1
IF (L-1>=MAXIL) THEN
ntmp=MAXIL+ntotm
call ReAllocate(ntmp)
WRITE(6,'(2x,"LIST = ",I8," MAX LIST = ",I8)')NINL,MAXIL
icallReAllocate=1
ENDIF
ENDIF
454 J=INEIG(J)
IF(J.NE.-1)GOTO 55
455 CONTINUE
ENDIF
LLAST(I)=L-1
IF(LLAST(I).LT.LFIRST(I)) LFIRST(I)=0
return
end
c--------end of neilist entry
if(mod(i,2)==0)then
!$omp atomic
icnt=icnt+1
!$omp end automic
a(icnt)=c
endif
gonski wrote:Hi, ejd
can I solve my problem in the following way? The reason is that icnt is expected to count something without any missing. So it is not necessary put a(icnt) and other vectors and scalars related to icnt in the atomic region, right?
- Code: Select all
if(mod(i,2)==0)then
!$omp atomic
icnt=icnt+1
!$omp end atomic
a(icnt)=c
endif
if(mod(i,2)==0)then
!$omp criticial
icnt=icnt+1
!$omp end critical
----------other codes
!$omp criticial
a(icnt)=c
!$omp end critical
endif
gonski wrote:Hi, Ejd
I notice you visit this website one time each day. I put my another solution here first. When you come to answer my previous questions, please help confirm this solution. As the counter icnt disperses among the code (This is the case in the code which I plan to parallelize), I add a critical clause for each line having icnt. Can this way solve my problem?
Cheers,
Gonski
- Code: Select all
if(mod(i,2)==0)then
!$omp criticial
icnt=icnt+1
!$omp end critical
----------other codes
!$omp criticial
a(icnt)=c
!$omp end critical
endif
Users browsing this forum: Google [Bot] and 4 guests