【问题标题】:MPI_ALLGATHER error parallelizing codeMPI_ALLGATHER 错误并行化代码
【发布时间】:2013-07-31 14:06:07
【问题描述】:

我正在尝试并行化以下代码。

subroutine log_likelihood(y, theta, lli, ll)
    doubleprecision, allocatable, intent(in)    :: y(:) 
    doubleprecision, intent(in)                 :: theta(2)
    doubleprecision, allocatable, intent(out)   :: lli(:)
    doubleprecision, intent(out)                :: ll
    integer                                     :: i
ALLOCATE (lli(size(y)))
lli = 0.0d0
ll = 0.0d0
do i = 1, size(y)
    lli(i) = -log(sqrt(theta(2))) - 0.5*log(2.0d0*pi) &
           - (1.0d0/(2.0d0*theta(2)))*((y(i)-theta(1))**2)
end do
ll = sum(lli)
end subroutine log_likelihood

为此,我尝试使用 MPI_ALLGATHER。这是我写的代码

subroutine log_likelihood(y, theta, lli, ll)
    doubleprecision, allocatable, intent(in)    :: y(:) 
    doubleprecision, intent(in)                 :: theta(2)
    doubleprecision, allocatable, intent(out)   :: lli(:)
    doubleprecision, intent(out)                :: ll
    integer                                     :: i, size_y, diff
size_y=size(y)
ALLOCATE (lli(size_y))
!Broadcasting
call MPI_BCAST(theta, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(y, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)

! Determine how many points to handle with each proc
points_per_proc = (size_y + numprocs - 1)/numprocs
! Determine start and end index for this proc's points
istart = proc_num * points_per_proc + 1
iend = min((proc_num + 1)*points_per_proc, size_y)
diff = iend-istart+1
allocate(proc_contrib(istart:iend))
do i = istart, iend
    proc_contrib(i) = -log(sqrt(theta(2))) - 0.5*log(2.0d0*pi) &
                    - (1.0d0/(2.0d0*theta(2)))*((y(i)-theta(1))**2)
end do
call MPI_ALLGATHER(proc_contrib, diff, MPI_DOUBLE_PRECISION, &
                   lli, diff, MPI_DOUBLE_PRECISION, &
                   MPI_COMM_WORLD, ierr)
ll = sum(lli)
end subroutine log_likelihood

当我尝试运行我的程序时,我收到以下错误。

$ mpiexec -n 2 ./mle.X 
Fatal error in PMPI_Allgather: Internal MPI error!, error stack:
PMPI_Allgather(961)......: MPI_Allgather(sbuf=0x7ff2f251b860, scount=1500000, MPI_DOUBLE_PRECISION, rbuf=0x7ff2f2ad5650, rcount=3000000, MPI_DOUBLE_PRECISION, MPI_COMM_WORLD) failed
MPIR_Allgather_impl(807).: 
MPIR_Allgather(766)......: 
MPIR_Allgather_intra(560): 
MPIR_Localcopy(357)......: memcpy arguments alias each other, dst=0x7ff2f2ad5650 src=0x7ff2f251b860 len=12000000

===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   EXIT CODE: 1
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================

有人可以向我解释我做错了什么吗?

谢谢!

【问题讨论】:

  • 您正在写入proc_contrib(istart:iend),但您已将其分配为从 1:diff;排名 1 及以上将覆盖 proc_contrib 的末尾,这可能会导致问题。 (还有一堆缺失的变量;numproc 等)。此外,allgather 尝试读取数组边界之外的内容。您可以allocate(proc_contrib(istart:iend)) 并将调用更改为 allgatherv 等。此外,您实际上不需要进行 allgather; MPI_Allreduce 将为您计算总和,这就是您所需要的。
  • 事实上,我建议不要修改例程,而是在外面进行求和。理想情况下,您不会让每个处理器“知道”所有y(i)s;他们只是有自己的本地问题,调用log_likelihood 例程,然后全部减少部分和(或者如果对数可能性是最终结果并且只需要打印出来,则只减少)。跨度>
  • 1.缺少的变量都被声明为该子例程之外的全局变量。 2. 我明白我的第一个错误,我改为 allocate(proc_contrib(istart:iend)) 3. 你能解释一下如何修复 Allgather 吗?我需要一个 Allgather,因为在我的真实程序中我需要 lli 作为输出。谢谢!
  • 正如 Jonathan Dursi 上面指出的那样,您的“差异”参数可能会因排名而异,即最后一个参数的值可能与其他所有参数的值不同。要解决这个问题,您需要使用 allgatherv 例程。

标签: fortran mpi


【解决方案1】:

我终于能够解决我的问题。我的代码的串行和并行版本可以在https://bitbucket.org/ignacio82/bhhh获得。

subroutine log_likelihood(y, n, theta, lli, ll)
    integer, intent(in)                         :: n
    doubleprecision, intent(in)                 :: y(n) 
    doubleprecision, intent(in)                 :: theta(2)
    doubleprecision, intent(out)                :: lli(n)
    doubleprecision, intent(out)                :: ll
    integer                                     :: i

do i = istart, iend
    proc_contrib(i-istart+1) = -log(sqrt(theta(2))) - 0.5*log(2.0d0*pi) &
                    - (1.0d0/(2.0d0*theta(2)))*((y(i)-theta(1))**2)
end do
 if ( mod(n,numprocs)==0 ) then
    call MPI_ALLGATHER(proc_contrib, points_per_proc, MPI_DOUBLE_PRECISION, &
                       lli, points_per_proc, MPI_DOUBLE_PRECISION, &
                       MPI_COMM_WORLD, ierr)
    else if (numprocs-1 == proc_num ) then 
    recvcounts(numprocs) = iend-istart+1
    call MPI_ALLGATHERV(proc_contrib, points_per_proc, MPI_DOUBLE_PRECISION, &
                        lli, recvcounts, displs, MPI_DOUBLE_PRECISION, &
                        MPI_COMM_WORLD, ierr)
 end if
 ll = sum(lli)
end subroutine log_likelihood

【讨论】:

    猜你喜欢
    • 2017-10-10
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 2023-03-19
    相关资源
    最近更新 更多