mpich2中的mpi_waitall,在array_of_requests中具有空值

时间:2013-09-16 20:26:25

标签: fortran fortran90 mpich pgi

我在MPICH-2.1.5和PGI编译器中遇到以下错误;

Fatal error in PMPI_Waitall: Invalid MPI_Request, error stack:
PMPI_Waitall(311): MPI_Waitall(count=4, req_array=0x2ca0ae0, status_array=0x2c8d220) failed
PMPI_Waitall(288): The supplied request in array element 0 was invalid (kind=0)

在以下示例中,用于基于模板的算法的Fortran代码,

Subroutine data_exchange

! data declaration

integer request(2*neighbor),status(MPI_STATUS_SIZE,2*neighbor)
integer n(neighbor),iflag(neighbor)
integer itag(neighbor),neigh(neighbor)

! Data initialization
request = 0; n = 0; iflag = 0;

! Create data buffers to send and recv
! Define values of n,iflag,itag,neigh based on boundary values

! Isend/Irecv look like this
ir=0
do i=1,neighbor
   if(iflag(i).eq.1) then
      ir=ir+1
      call MPI_Isend(buf_send(i),n(i),MPI_REAL,neigh(i),itag(i),MPI_COMM_WORLD,request(ir),ierr)
      ir=ir+1
      call MPI_Irecv(buf_recv(i),nsize,MPI_REAL,neigh(i),MPI_ANY_TAG,MPI_COMM_WORLD,request(ir),ierr)
   endif
enddo

! Calculations

call MPI_Waitall(2*neighbor,request,status,ierr)

end subroutine

当mpi_waitall中的array_of_request获取空值(request(i)=0)时,会发生错误。当条件array_of_request不满足时,iflag(i)=1中的空值出现。直接的解决方案是注释掉条件,但这将引入发送和接收0大小的消息的开销,这对于大规模系统(1000个核心)是不可行的。

根据MPI-forum linkarray_of_requests列表可能包含空句柄或非活动句柄。

我试过了,

  1. 未初始化array_of_requests
  2. 调整array_of_request的大小以匹配MPI_isend + MPI_irecv计数
  3. 将虚拟值分配给array_of_request
  4. 我还使用MPICH-1和OpenMPI 1.4测试了相同的代码,代码也没有任何问题。
  5. 任何见解都会非常感激!

1 个答案:

答案 0 :(得分:2)

您也可以将ir的第一个增量移动到条件中。然后,您将在循环和循环中request(1:ir)中拥有所有句柄并发出:

call MPI_Waitall(ir,request(1:ir),status(:,1:ir),ierr)

这将确保所有请求都已正确初始化。

另一件事:n(i)中的MPI_Isendnsize中的MPI_Irecv保持相同的价值吗?

编辑: 在查阅MPI标准(3.0,Ch.3.7.3)后,我认为如果要将整个请求数组提供给MPI_REQUEST_NULL,则需要将请求数组初始化为MPI_Waitall