OpenMP and subroutines

General OpenMP discussion

OpenMP and subroutines

Postby vsbgonzalez » Wed Jul 25, 2012 10:00 am

Hi all,

I want to parallelize with OpenMP a code that I wrote. This code uses some subroutines made by me and others made by someone (I called Black_box). I work in Fortran 95 and I know nothing about C. The Black_box is written in C and its real name is Cuba – a library for multidimensional numerical integration.

I put some clauses, THREADPRIVATE, in my subroutines to make them thread-safe. If I work with only 1 thread the code works but If I work with more thread the code doesn't work.

The structure of my code is this:

Code: Select all
PROGRAM TESTE
USE FUNC
IMPLICIT NONE
INTEGER,PARAMETER :: A1 = ....
REAL,PARAMETER :: A2 = ....
REAL,PARAMETER :: A3 = ...
REAL,PARAMETER :: A4 = ....
REAL :: EX

!$OMP PARRALLEL SECTIONS

   !$OMP SECTION DEFAULT(NONE) SHARED(a0) PRIVATE(EX)
      A0 = 11111111111111.0000000000
      CALL BLACK_BOX(a1,INTEGRAND,a2,a3,a4,EX)

   !$OMP SECTION
      A0 = 222222222222222.000000000
      CALL BLACK_BOX(a1,INTEGRAND,a2,a3,a4,EX)

!$OMP END PARALLEL SECTION

END PROGRAM TESTE


MODULE pasar
   IMPLICIT NONE
   REAL (KIND = nkind), PUBLIC :: A0
   !$OMP THREADPRIVATE(A0)
END MODULE pasar


MODULE FUC
CONTAINS
   INTEGER FUNCTION INTEGRAND(B1,B2,B3)
      USE pasar
      USE PROBABILIDAD
      IMPLICIT NONE

      REAL (KIND =DouPre), DIMENSION(NDIM), INTENT(IN) :: B1,B2
      REAL (KIND =DouPre), DIMENSION(NDIM), INTENT(INOUT) :: B3
            
      REAL (KIND =DouPre), DIMENSION(NDIM) :: Z1,Z2,Z3
      !$OMP THREADPRIVATE(Z1,Z2,Z3)

      Z1 = ......
      Z2 = .......
      B3 = PROBABI2fami(A0,B2,Z3)
      INTEGRAND = 0

   END FUNCTION INTEGRAND
END MODULE FUC


MODULE PROBABILIDAD
CONTAINS
   REAL  FUNCTION PROBABI2fami (C1,C2,C3)
      REAL (KIND =DouPre), INTENT(IN) :: C1,C2,C3
      
      REAL (KIND =DouPre) :: Z1,Z2,Z3
      !$OMP THREADPRIVATE(Z1,Z2,Z3)      
      
      PROBABI2fami =Z1*Z2*Z3*C1*C2*C3

   END FUNCTION PROBABI2fami
END MODULE PROBABILIDAD




Could someone tell me if this code is correct ?
Is it necessary to make the Black_Box subroutine thread-safe?

Thanks
Victor
vsbgonzalez
 
Posts: 5
Joined: Thu Oct 20, 2011 12:03 pm

Re: OpenMP and subroutines

Postby MarkB » Fri Jul 27, 2012 4:50 am

I can see a couple of possible problems with your code:

a0 is threadprivate and cannot be declared as shared (I presume the DEFAULT, SHARED and PRIVATE clauses are meant to belong on the PARALLEL SECTIONS directive, and I am surprised the compiler does not complain).

z1,z2 and z3 are local variables in the functions without a static qualifier, so cannot be declared threadprivate (again I am surprised the compiler does not complain).

Having said that, a quick look at the Cuba documentation suggests that most of its routines rely on pseudo-random number generation, and there is a good chance that these routines are not thread-safe.
MarkB
 
Posts: 450
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: OpenMP and subroutines

Postby vsbgonzalez » Tue Jul 31, 2012 6:14 am

Thank MarkB,

yes MarkB, that code has a lot of mistakes both in fortran and OPENMP.
a new code is this one

Code: Select all
MODULE PrecisionTra
   IMPLICIT NONE
   INTEGER, PARAMETER :: p_p = 17, r_p = 200
        INTEGER, PARAMETER :: DouPre=SELECTED_REAL_KIND(p = p_D, r = r_D)
END MODULE PrecisionTra

MODULE pasar
   USE PrecisionTra
   IMPLICIT NONE
      REAL (KIND = DouPre), PUBLIC :: A0
      !$OMP THREADPRIVATE(A0)
END MODULE pasar


MODULE PROBABILIDAD
CONTAINS
   REAL  FUNCTION PROBABI2fami (C1,C2,C3)
      USE PrecisionTra
      REAL (KIND =DouPre), INTENT(IN) :: C1,C2,C3
     
            REAL (KIND =DouPre), SAVE :: W1,W2,W3
            !$OMP THREADPRIVATE(W1,W2,W3)     
     
      W1=1.0
      W2=1.0
      W3=1.0
            PROBABI2fami =W1*W2*W3*C1*C2*C3

   END FUNCTION PROBABI2fami
END MODULE PROBABILIDAD


MODULE FUNC
CONTAINS
   INTEGER FUNCTION INTEGRAND(NDIM,B1,B2,B3)
      USE pasar
      USE PROBABILIDAD
      USE PrecisionTra
      IMPLICIT NONE

      INTEGER, INTENT(IN) :: NDIM
      REAL (KIND =DouPre), DIMENSION(NDIM), INTENT(IN) :: B1,B2
      REAL (KIND =DouPre), DIMENSION(NDIM), INTENT(INOUT) :: B3
           
      REAL (KIND =DouPre), ALLOCATABLE, SAVE :: Z1(:),Z2(:),Z3(:)
      !$OMP THREADPRIVATE(Z1,Z2,Z3)
      REAL (KIND =DouPre) :: Q1,Q2,Q3

      if (.not. allocated(Z1)) allocate(Z1(NDIM))
      if (.not. allocated(Z2)) allocate(Z2(NDIM))
      if (.not. allocated(Z3)) allocate(Z3(NDIM))

      Z1 = 2.0
      Z2 = 2.0
      Z3 = 3.0
      Q1 = Z3(1)
      Q2 = B2(1)*B3(1)
      B3 = PROBABI2fami(A0,Q2,Q1)
      INTEGRAND = 0

   END FUNCTION INTEGRAND
END MODULE FUNC




PROGRAM TESTE
USE FUNC
USE pasar
IMPLICIT NONE
INTEGER,PARAMETER :: A1 = 2
REAL,PARAMETER :: A2 = 4.0
REAL,PARAMETER :: A3 = 4.0
REAL,PARAMETER :: A4 = 4.0
REAL :: EX

EX = 3.0

!$OMP PARALLEL DEFAULT(NONE) PRIVATE(EX)
   !$OMP SECTIONS
      !$OMP SECTION
         EX = 2.0
         A0 = 1111.0000000000
         CALL BLACK_BOX(a1,INTEGRAND,a2,a3,a4,EX)

      !$OMP SECTION
         EX = 3.0
         A0 = 2222.000000000
         CALL BLACK_BOX(a1,INTEGRAND,a2,a3,a4,EX)
   !$OMP END SECTIONS

!$OMP END PARALLEL
END PROGRAM TESTE




I don't understand why a pseudo-random number generation is not possible parallelizable

victor
vsbgonzalez
 
Posts: 5
Joined: Thu Oct 20, 2011 12:03 pm

Re: OpenMP and subroutines

Postby MarkB » Tue Jul 31, 2012 6:51 am

vsbgonzalez wrote:I don't understand why a pseudo-random number generation is not possible parallelizable


The usual problem is that the implementations of pseudo-random number generators preserve some state between calls (for example using static/SAVEd variables or some type of global variables). If called from more than one thread inside an OpenMP parallel region, such variables are by default shared between threads, and therefore race conditions occur with catastrophic effects. Thread-safe pseudo-random number generators are a well studied subject, but if your black-box does not employ such a thing, then you are out of luck!
MarkB
 
Posts: 450
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: OpenMP and subroutines

Postby baddylover » Wed Aug 15, 2012 6:25 am

I'm using gfortran's random_number() in my code. Is it safe?
baddylover
 
Posts: 25
Joined: Thu Apr 07, 2011 6:17 am

Re: OpenMP and subroutines

Postby MarkB » Wed Aug 15, 2012 7:28 am

baddylover wrote:I'm using gfortran's random_number() in my code. Is it safe?


Yes it is, though I would guess that he implementation uses a lock to sequentialise the threads' access to the internal state, so although you will get a valid sequence of random numbers, performance may suffer.

From http://gcc.gnu.org/onlinedocs/gfortran/ ... UMBER.html

"Please note, this RNG is thread safe if used within OpenMP directives, i.e., its state will be consistent while called from multiple threads. However, the KISS generator does not create random numbers in parallel from multiple sources, but in sequence from a single source. If an OpenMP-enabled application heavily relies on random numbers, one should consider employing a dedicated parallel random number generator instead."
MarkB
 
Posts: 450
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh


Return to Using OpenMP

Who is online

Users browsing this forum: No registered users and 15 guests