FORTRAN Subroutines and openMP

General OpenMP discussion

FORTRAN Subroutines and openMP

Postby ikingrma » Wed Sep 28, 2011 8:52 pm

I am an experience FORTRAN programmer (more than 40 years) and have developed some large simulation models and am now trying to convert sections of these codes to multithreading using openMP (where I am a novice).

My objective is to multithread a loop that calls complex subroutine that has as an end product a matrix and a vector. I have set this routine to generate unique copies of these arrays by an adding an extra degree of freedom. Each call to this subroutine uses values from allocatable arrays plus one value from the calling sequence to create its unique result.

My problem is how do ensure that local working variables in this routine stay private to the thread when the parallel openMP specification is in the calling calling program around a DO loop. It is possible to collect these variables and put them in some form of COMMON if that would help. I am able to parallelize the process successfully if I use OMP SECTIONS and clone the routines but that is clumsy/bulky and limits the degree of parallelization that I could achieve. :roll:
ikingrma
 
Posts: 7
Joined: Wed Sep 28, 2011 8:37 pm

Re: FORTRAN Subroutines and openMP

Postby ftinetti » Thu Sep 29, 2011 3:33 am

Hi,

I do not get the situation... please tell me if you are working on this (kind of pseudocode):

Code: Select all
program
   ...
   ! Loop which you want to parallelize
   DO I = 1, N
      ...
      call complex_subroutine(..., i, ...)
      ...
   END DO
en program

Maybe this is over-simplified, but if this is the case, complex_subroutine() local working variables are made private (usually) when you compile with OpenMP compiler switch (in the worst case, check your compiler documentation). However, remember that there are other issues/exceptions: complex_subroutine() saved variables are shared as well as common block variables. But I guess I'm missing something, since I can't see the relationship of my understanding with
when the parallel openMP specification is in the calling calling program around a DO loop. It is possible to collect these variables and put them in some form of COMMON if that would help. I am able to parallelize the process successfully if I use OMP SECTIONS and clone the routines but that is clumsy/bulky and limits the degree of parallelization that I could achieve.

Just curious: computer hardware and OS? compiler and compiler options?
ftinetti
 
Posts: 558
Joined: Wed Feb 10, 2010 2:44 pm

Re: FORTRAN Subroutines and openMP

Postby ikingrma » Thu Sep 29, 2011 3:41 pm

Thank you, your comments have given me some clues and ideas. In particular, I do have SAVE statements.

The system is WINDOWS 7 64 bit. My FORTRAN is INTEL VISUAL FORTRAN COMPOSER XE 12.1 and I use VISUAL STUDIO 2005 PROFESSIONAL My compile line is

/nologo /QxHost /Qunroll:3 /assume:buffered_io /Qip /module:"Release\\" /object:"Release\\" /libs:qwin /Qmkl:parallel /c
with additional options /Qopenmp /Qopenmp-report:1

I do have more questions. My logic is a little more embedded (CALLS within CALLS but no reentrant code)


program
...
! Loop which you want to parallelize
DO I = 1, N
...
call complex_subroutine(..., i, ...)
...
END DO
en program

subroutine complex_subroutine(..., i, ...)

use allocated arrays

do loops etc
CALL AMF(DUM1,HS,AKP(N),ADT(N),ADB(N),AME2(M),DAME2(M),ISWT)

plus other calls that use allocated arrays to get further coefficients used in the building process

end loops
return
end subroutine

SUBROUTINE AMF(H,HSIG,AKAPM,ATM,ABM,AM,DAMH,ISWT)
cipk apr97
common /epor/ efpor
C
IF(ISWT .EQ. 0) THEN
C
C...... Convert HSIG to H
C
IF(AKAPM .GT. 0.9999) THEN
H=HSIG
AM=0.
DAMH=0.
cipk apr97
efpor=akapm
ELSEIF(HSIG .LT. AKAPM*ABM) THEN
H=HSIG/AKAPM
AM=H-HSIG
DAMH=1.0/AKAPM-1.
cipk apr97
efpor=akapm
ELSEIF( HSIG .GT. ATM-(ABM+ATM)/2.*(1.-AKAPM) ) THEN
H=HSIG+(1.-AKAPM)/2.*(ABM+ATM)
AM=H-HSIG
DAMH=0.0
cipk apr97
efpor=1.0
ELSE
SQ=SQRT((ATM-ABM)*(AKAPM*(AKAPM*(ATM+ABM)-2.*ABM)
+ +2.*HSIG*(1.-AKAPM)))
H=(ABM-AKAPM*ATM+SQ)/(1.-AKAPM)
AM=H-HSIG
DAMH=-1.+(ATM-ABM)/SQ
cipk apr97
efpor=akapm+(h-abm)/(atm-abm)*(1.-akapm)
ENDIF
C*******************
C TEST MODIFICATION OF DERIVATIVES
C*******************
C IF (HSIG .LT. 2.+ ATM-(ABM+ATM)/2.*(1.-AKAPM)) THEN
C DAMH=AM/HSIG
C ENDIF
C*******************
C END CHANGE
C*******************
ELSE
C
C...... Convert H to HSIG
C
IF(AKAPM .GT. 0.9999) THEN
HSIG=H
ELSEIF(H .LT. ABM) THEN
HSIG=H*AKAPM
ELSEIF(H .GT. ATM) THEN
HSIG=AKAPM*H+(1.-AKAPM)*((ATM-ABM)/2.+(H-ATM))
ELSE
HSIG=AKAPM*H+(1.-AKAPM)/2.*(H-ABM)**2/(ATM-ABM)
ENDIF
ENDIF
RETURN
END


Finally, my questions.
1 Are variables like SQ private to a given thread in routines at the AMF level?
2 Is there any potential problem with the local variable SQ in AMF. I assume that I need to move EFPOR out of COMMON?

Thanks again for any guidance - confidence building.
ikingrma
 
Posts: 7
Joined: Wed Sep 28, 2011 8:37 pm

Re: FORTRAN Subroutines and openMP

Postby ftinetti » Fri Sep 30, 2011 3:28 am

Hi,

Questions first:

1 Are variables like SQ private to a given thread in routines at the AMF level?

I would start by using IMPLICIT NONE and explicit declaration of every variable. Having said that, SQ is a local variable so yes, every thread has its own (private) SQ.

2 Is there any potential problem with the local variable SQ in AMF...?

I think there is no problem on SQ unless you declare it as saved (which is not the case with the current code, I think).

2... I assume that I need to move EFPOR out of COMMON?

In general, I would suggest avoiding COMMON in parallel code, so if you are able "to move EFPOR out of COMMON" I think you avoid a lot of trouble. If COMMON blocks are not possible to avoid, then you should see the how to synchronize the writes on shared data to avoid race conditions.

Other questions/comments:
a) AMF is the "complex_subroutine" called in parallel by different threads, right?
b) take care with dummy arguments, e.g. H in AMF is assigned a value inside the function, so you should make sure that H is private to the thread calling AMF...

HTH.
ftinetti
 
Posts: 558
Joined: Wed Feb 10, 2010 2:44 pm

Re: FORTRAN Subroutines and openMP

Postby ikingrma » Sat Oct 01, 2011 3:55 pm

Thanks for your guidance. Unfortunately the subroutine that I posted is at a second level and is called by the complex subroutine along with a number of other subroutines, but your advice still helps.

I have now implemented this advice without any real luck. The model goes into execution and simly stalls with no diagnostic either in debug or release mode. It works fine if I take out the OMP instructions. It also fails the same way if I clone and use the SECTIONS approach. Can you suggest a way to extract how the model hangs ups.

My next step will be to go back and simplify on a test basis.

I might note that earlier, I have successfully parallelized another and very similar code with a clone and sections approach. I noticed that for this case I did use the SAVE line. I now realize that this would not work for for true parallel options, but is it significant for the sections options.

Thanks again for your help
ikingrma
 
Posts: 7
Joined: Wed Sep 28, 2011 8:37 pm

Re: FORTRAN Subroutines and openMP

Postby ftinetti » Tue Oct 04, 2011 3:46 am

Hi again,

In general, I would stick to my own previous "guidelines":
1) IMPLICIT NONE.
2) Avoid COMMONs or review/control access to data in COMMONs.
3) Review/control access to dummy arguments (e.g. H,HSIG,AKAPM,ATM,ABM,AM,DAMH,ISWT in AMF routine).
4) Review avoid/review SAVE data.
Usually in a bottom-up fashion... and I know this is pretty hard work, since sometimes it's possible to conclude that code is not parallelizable unless a complete restructuring or recoding is made.

HTH.
ftinetti
 
Posts: 558
Joined: Wed Feb 10, 2010 2:44 pm


Return to Using OpenMP

Who is online

Users browsing this forum: Yahoo [Bot] and 6 guests