How to parallelize this fortran code by openmp

General OpenMP discussion

Re: How to parallelize this fortran code by openmp

Postby gonski » Thu Jan 24, 2008 4:32 am

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.
gonski
 
Posts: 26
Joined: Fri Jan 18, 2008 10:58 pm

Re: How to parallelize this fortran code by openmp

Postby ejd » Thu Jan 24, 2008 6:46 am

I will see if I can answer your questions.
  • to privatize scalar in a parallelized loop is necessary or not? why?

    It is not necessary, BUT if it is not privatized then it needs to be protected in some fashion (master, single, atomic, critical, etc) or you will have a race condition.

  • do above issues depend on operating system?

    No - it depends on whether or not there are data dependencies in the code.

  • 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.
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: How to parallelize this fortran code by openmp

Postby ejd » Thu Jan 24, 2008 7:02 am

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.


It is not impossible - just not very likely. For example, you are only showing a small section of code, so maybe this is an orphaned do. 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.

There is a data dependence on f from one iteration of the loop to the next. Since you have multiple threads executing at the same time with OpenMP, you have to do something to protect f from being accessed by these threads at the same time. There are many ways of doing this in OpenMP for this example (a reduction clause, a critical section, atomic, etc).
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: How to parallelize this fortran code by openmp

Postby gonski » Thu Jan 24, 2008 1:41 pm

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.



I tested this code on my laptop having duo-cores. It seems all my tests were running with one thread although I have tried to assign more than two threads in the code. This is also the reason that all results puzzled me in my previous experiments. Later I will test it in a supper computer which will be available in a couple of days.
Cheers,
Gonski
gonski
 
Posts: 26
Joined: Fri Jan 18, 2008 10:58 pm

Re: How to parallelize this fortran code by openmp

Postby gonski » Thu Jan 24, 2008 1:55 pm

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.


This is bad news to me. Would you please have a look at my code as follows? the loop I which i want to parallelize is always very big. All its calculations except the counter L inside it are independent. Do you have a idea to handle this problem. BTW: critical section will affect computational efficiency, right?



Here, L is a counter. It can be seen in the parallelized loop everywhere. Is it possible for me to use parallelism here?
This is the part in my code which is the most time-consuming.

Code: Select all
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
gonski
 
Posts: 26
Joined: Fri Jan 18, 2008 10:58 pm

Re: How to parallelize this fortran code by openmp

Postby gonski » Thu Jan 24, 2008 2:48 pm

Hi, Edj

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 automic

  a(icnt)=c

endif
gonski
 
Posts: 26
Joined: Fri Jan 18, 2008 10:58 pm

Re: How to parallelize this fortran code by openmp

Postby ejd » Thu Jan 24, 2008 4:55 pm

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

The answer is no. The problem is not just the increment, but also the use. Say one thread executes the atomic and hasn't yet executed the update of "a". Say another thread comes along and then executes the atomic. icnt has now been updated twice and the array has not been updated yet. Now both threads execute the update of "a" and the values are overlaid. You get the wrong result.

I saw your other post, but have not had time to look at it closely. I will try and answer it tomorrow.
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: How to parallelize this fortran code by openmp

Postby gonski » Thu Jan 24, 2008 8:36 pm

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
gonski
 
Posts: 26
Joined: Fri Jan 18, 2008 10:58 pm

Re: How to parallelize this fortran code by openmp

Postby ejd » Fri Jan 25, 2008 7:04 am

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

I am actually trying to look at the web site a couple times a day, but my "day job" keeps me pretty busy.

The answer is no - this has the same problem. Think about it. This loop will be executed when i=2,4,or 6. That means that multiple threads will enter this "if section". They could both update icnt before they update the array a - giving you the same problem. The update of icnt and the update of the array a that is using icnt (and thus dependent on icnt) have to be done in the same critical region.
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: How to parallelize this fortran code by openmp

Postby gonski » Fri Jan 25, 2008 10:38 am

This means that If the counter has been used in the different places in a loop, it is impossible for to use parallelism for the loop, right? Now I really have no idea to deal with my code that I show you in the above message "on Thu Jan 24, 2008 12:55 pm".
gonski
 
Posts: 26
Joined: Fri Jan 18, 2008 10:58 pm

Previous

Return to Using OpenMP

Who is online

Users browsing this forum: Exabot [Bot], Yahoo [Bot] and 9 guests