use*_*327 0 fortran mpi subroutine
我正在处理可多次调用子例程(依次执行迭代)的代码。我希望并行化子例程中的迭代。mpi的问题是只允许我初始化一次。因此,我无法在子例程中对其进行初始化,该子例程被多次调用。有人可以提出解决方案吗?
我的问题大致如下:
program p
...
do i=1,10000
call subroutine s(i)
end do
end program p
subroutine s(j)
...
do i=1,10000
...
end do
end subroutine s
Run Code Online (Sandbox Code Playgroud)
我希望将这一过程并行化。
非常感谢。有帮助!但是,让我重新思考一下问题:在主程序的迭代中,连同子例程s,我必须调用另一个子例程s2(不需要并行化)。我以为可以这样做:
!initialize mpi
do i=1:1000
if rank!=0
call s
else call s2
end if
end do
!finalize mpi
Run Code Online (Sandbox Code Playgroud)
但是这里的主要问题是,尽管其余进程缓慢进行,但进程0将快速进行。因此,是否有可能让进程0在每次迭代之后等待,直到另一个进程完成其迭代呢?
您需要在主程序中初始化和完成MPI。通常,然后在子例程中定义对该工作有效的负载平衡。
然后,您可以在子例程中并行执行循环,并在子例程的末尾收集(减少?)结果,以便您获得在下一步调用该子例程时所需的所有信息。
这与在主程序中执行循环的方式相同(不调用子例程)。
这是一个最小的示例:
module testMod
use mpi
implicit none
!#include "mpif.h"
!===
contains
!===
subroutine s(mysize, myrank, array)
integer,intent(in) :: mysize, myrank
integer,intent(inout) :: array(:)
integer :: i, ierror
! Do stuff
do i=1,size(array)
! Skip element that is not associated with the current process
if ( mod(i,mysize) .ne. myrank ) cycle
array(i) = array(i) + 1
enddo ! i
! MPI Allreduce
call MPI_Allreduce(MPI_IN_PLACE, array, size(array), MPI_INTEGER, &
MPI_MAX, MPI_COMM_WORLD, ierror)
end subroutine
end module
program mpiTest
use testMod
use mpi
implicit none
!#include "mpif.h"
integer :: mysize, myrank, ierror
integer,parameter :: ITER=100
integer,parameter :: arraySize=10
integer :: work(arraySize)
integer :: i
! MPI Initialization
call MPI_Init(ierror)
call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierror)
call MPI_Comm_size(MPI_COMM_WORLD, mysize, ierror)
work = 0
do i=1,ITER
call s(mysize, myrank, work)
enddo
if ( myrank .eq. 0 ) write(*,*) work
! MPI Finalize
call MPI_Finalize(ierror)
end program
Run Code Online (Sandbox Code Playgroud)