문제

The purpose of the example below is to parallelize a do loop over a subroutine named "sub1" that invokes a function in which a simple addition operation is executed.

The problem that troubles me is that, in my mathematical model, the invoked function has two input arguments, (a,e), but for some reason in my code, I am restricted to pass a single-argument function to the subroutine "sub1." The solution I figured out is to set the second variable "e" to be inherited by the invoked function from the module it resides. The outcome looks good to me.

I am wondering whether using heritage to pass more than one arguments---identically defined in the module where the invoked function resides---to the invoked function in the parallel region will lead to any racing problem.

Thanks.

Lee

---- There are two files in this example: main.f90 and model.f90.

MAIN.f90

program main
! The definition of sub1 is:
! taking function_1,input_2,input_3 as inputs and
! returning output_4 as output
use omp_lib
use model
implicit none
integer :: j
real :: m(1000),k(1000)

m=[(real(j),j=1,1000)]

!$omp parallel do private(j) shared(m,k)
do j=1,1000
   call sub1(fun1,m(j),2.,k(j)) 
enddo
!$omp end parallel do

end program main

MODEL.F90

module model
    implicit none
    real :: e
contains
    subroutine sub1(func,a,c,d)
    implicit none
    real, intent(in) :: a,c
    real, intent(out) :: d
    interface
        real function func(a)
        implicit none
        real :: a
        end function func            
    end interface
    e=c
    d=func(a)
    end subroutine sub1

    real function fun1(a)
    implicit none
    real :: a
    fun1=a**e
    end function fun1
end module model
도움이 되었습니까?

해결책

Yes, more threads will try to write to the variable e in this line

e=c

and that is a race condition. You can make it threadprivate. That way every thread will have its private copy that will persist during the calls.

In Fortran 2008 you could also do something along the lines of the program below, but the principle is the same.

module model
    implicit none
    real :: e
contains
    subroutine sub2(func,a,d)
    implicit none
    real, intent(in) :: a
    real, intent(out) :: d
    interface
        real function func(a)
        implicit none
        real :: a
        end function func            
    end interface

    d=func(a)
    end subroutine

end module model



program main
    ! The definition of sub1 is:
    ! taking function_1,input_2,input_3 as inputs and
    ! returning output_4 as output
    use omp_lib
    use model
    implicit none
    integer :: j
    real :: c
    real :: m(1000),k(1000)

    m=[(real(j),j=1,1000)]

    !$omp parallel do private(j,c) shared(m,k)
    do j=1,1000
       c = i
       call sub2(fun1,m(j),k(j)) 
    enddo
    !$omp end parallel do

    contains

      real function fun1(a)
        implicit none
        real :: a
        fun1=a**c
      end function fun1

end program main
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top