0

我正在处理多次连续调用子例程(依次执行迭代)的代码。我希望并行化子程序内的迭代。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

我希望并行化这个过程。

非常感谢。这有帮助!但是让我重新提出我的问题,在主程序的迭代中,连同子程序 s,我必须调用另一个子程序 s2,(不需要并行化)。我想,可以这样做:

  !initialize mpi

  do i=1:1000

  if rank!=0

  call s

  else call s2

  end if

  end do

  !finalize mpi

但这里的主要问题是,当其余进程缓慢进行时,进程 0 将快速进行。(一些不可取的东西)。那么,是否可以让进程 0 在每次迭代后等待,直到另一个进程完成他们的迭代?

4

1 回答 1

5

您需要在主程序中初始化和完成 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
于 2013-09-13T12:23:52.770 回答