【发布时间】:2013-02-08 05:56:30
【问题描述】:
我希望找出 MPI 程序出错的原因。该程序是一个大的 while 循环,因此对于每次迭代,一组消息在每个处理器及其邻居之间使用 ISEND 和 IRECV 完成,如下所示:
while (t
do i=1,8
if ( something that is almost always true ) then
call MPI_ISEND(A,A_buffer,inewtype,neighrank(i),2,MPI_COMM_WORLD,isend,ierr)
call MPI_WAIT(isend,istatus,ierr)
call MPI_ISEND(B,B_buffer,MPI_INTEGER4,neighrank(i),3,MPI_COMM_WORLD,isend,ierr)
call MPI_WAIT(isend,istatus,ierr)
end if
end do
do i=1,8
if ( something that is almost always true) then
call MPI_IRECV(C,C_buffer,inewtype,neighrank(i),2,MPI_COMM_WORLD,irecv,ierr)
call MPI_WAIT(irecv,istatus,ierr)
call MPI_IRECV(D,D_buffer,MPI_INTEGER4,neighrank(i),3,MPI_COMM_WORLD,irecv,ierr)
call MPI_WAIT(irecv,istatus,ierr)
end if
end do
...
程序在大量迭代后产生segmentation fault 错误。在每次迭代中,处理器之间传递的数据量相同,但对 ISEND 和 IRECV 的调用次数是可调整的(即使用 80 次调用来传递总共 80kb 或使用 40 次调用来传递总共 160kb)。如果调用次数很少,程序会提前崩溃。
我怀疑something about InfiniBand!导致此错误,但我没有收到insufficient virtual memory - 所以它不可能是 InfiniBand?什么可能导致此错误?
【问题讨论】:
-
为什么你使用
MPI_I(SEND/RECV)的组合紧跟MPI_WAIT而一个简单的MPI_SEND/RECV会完全一样?那么我会建议你编译你的程序并启用调试,然后检查核心文件以找出崩溃发生的位置。 -
谢谢;我读到 MPI_I(SEND/RECV) 通常更快。
-
MPI_ISEND和MPI_IRECV属于在后台执行的非阻塞通信操作类。它们允许您在通信发生时进行计算(例如在MPI_ISEND和MPI_WAIT之间),这通常会导致更快的整体程序执行。但操作本身与阻塞操作一样快。 -
据我了解,
MPI_ISEND/RECV还有助于防止在使用常规MPI_SEND/RECV时因缓冲区溢出而发生的死锁。
标签: segmentation-fault mpi fortran90