在线程子程序中托管函数

时间:2014-03-20 21:03:34

标签: multithreading parallel-processing fortran openmp

我将Fortran项目移植到OpenMP时遇到了问题。在我的原始代码中,有两个名为 add mpy 的函数被传递给一个线程子程序 submodel ,它将各自的函数抛出到另一个子程序中定义。模块工具箱

现在,对于我的新代码,我想知道是否有一种方法可以产生与我的原始代码完全相同的结果,但是有一个微小的扭曲,可以移动两个函数添加 mpy 在子程序子模型中托管(即包含)。

感谢。

---我的原始代码由四个文件组成:MAIN.F90,MODEL.F90,VARIABLE.F90和TOOLBOX.F90

输出:

--- addition ---
    3    7   11   15
--- multiplication ---
    2   12   30   56
Press any key to continue . . .

main.f90时

program main
    use model
    implicit none  
    call sandbox()
end program main

MODEL.F90

module model
    use omp_lib
    use variable
    implicit none
contains
    subroutine submodel(func,x,y)
        implicit none
        interface
            function func(z)
                implicit none
                integer :: z,func
            end function func
        end interface
        integer :: x,y
        call tool(func,x,y)
    end subroutine submodel

    function add(a)
        implicit none
        integer :: a,add
        add=a+thread_private
    end function add 

    function mpy(m)
        implicit none
        integer :: m,mpy
        mpy=m*thread_private
    end function mpy

    subroutine sandbox()
        implicit none
        integer :: a(4),b(4),c(4),i
        a=[((i),i=1,7,2)]
        b=[((i),i=2,8,2)]
        !$omp parallel do
        do i=1,4
            thread_private=b(i)
            call submodel(add,a(i),c(i))    
        enddo
        !$omp end parallel do
        write(6,'(a)') '--- addition ---'
        write(6,'(4(i5))') c

        !$omp parallel do
        do i=1,4
            thread_private=b(i)
            call submodel(mpy,a(i),c(i))
        enddo
        !$omp end parallel do
        write(6,'(a)') '--- multiplication ---'
        write(6,'(4(i5))') c  
    end subroutine sandbox
end module model

TOOLBOX.F90

module toolbox
    implicit none
contains
    subroutine tool(funct,input,output)
        implicit none
        interface
           function funct(x)
                implicit none
                integer :: x,funct
            end function funct
        end interface
        integer :: input,output
        output = funct(input)
    end subroutine tool
end module toolbox

VARIABLE.F90

module variable
    use toolbox
    implicit none
    integer :: thread_private
    !$omp threadprivate(thread_private)
end module variable

是否可以简单地以这种方式重新排列它们? (我已经尝试过并且显然失败了):

subroutine submodel(func,x,y)
    implicit none
    interface
        function func(z)
            implicit none
            integer :: z,func
        end function func
    end interface
    integer :: x,y
    call tool(func,x,y)
contains
    function add(a)
        implicit none
        integer :: a,add
        add=a+thread_private
    end function add 

    function mpy(m)
        implicit none
        integer :: m,mpy
        mpy=m*thread_private
    end function mpy
end subroutine submodel

1 个答案:

答案 0 :(得分:0)

您可以在子例程submodel内部完成两个过程,就像在上一个代码段中一样。问题是您无法将这两个子例程作为子例程外部的实际参数传递,因为您无法访问它们。

即使您将某些程序指针存储在某处,但只要原始运行的submodel可以创建它们,这些指针就会无效。

我会考虑使用一些开关:

subroutine submodel(switch,x,y)
    implicit none
    integer :: switch,x,y

    select case(switch)
      case(USE_ADD)
        call tool(add,x,y)
      case(USE_MPY)
        call tool(mpy,x,y)
      case default
        stop "unknown switch value"
    end select
contains
    function add(a)
        implicit none
        integer :: a,add
        add=a+thread_private
    end function add 

    function mpy(m)
        implicit none
        integer :: m,mpy
        mpy=m*thread_private
    end function mpy
end subroutine submodel

另一种选择是保留原始设计。

相关问题