multithreading - To host functions within a threaded subroutine -
i encountered problem when port fortran project openmp. in original code, there 2 functions named add , mpy being passed threaded subroutine submodel throws respective function subroutine defined in module toolbox.
now, new code, wondering whether there way produce same outcome original code tiny twist moves 2 functions add , mpy hosted (i.e., contained) within subroutine submodel.
thanks.
lee
--- original code consists of 4 files: main.f90, model.f90, variable.f90, , toolbox.f90
output:
--- addition --- 3 7 11 15 --- multiplication --- 2 12 30 56 press key 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 i=1,4 thread_private=b(i) call submodel(add,a(i),c(i)) enddo !$omp end parallel write(6,'(a)') '--- addition ---' write(6,'(4(i5))') c !$omp parallel i=1,4 thread_private=b(i) call submodel(mpy,a(i),c(i)) enddo !$omp end parallel 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
is possible rearrange them in way? (i have tried , apparently failed):
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
you can make 2 procedures internal subroutine submodel
did in last code snippet. problem cannot pass these 2 subroutines actual arguments outside of subroutine, because have no access them there.
even if have procedure pointers them stored somewhere, these invalid original run of submodel
have created them ended.
i think using switch:
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
another option keep original design.
Comments
Post a Comment