我在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 link,array_of_requests
列表可能包含空句柄或非活动句柄。
我试过了,
array_of_requests
,array_of_request
的大小以匹配MPI_isend + MPI_irecv
计数array_of_request
任何见解都会非常感激!
答案 0 :(得分:2)
您也可以将ir
的第一个增量移动到条件中。然后,您将在循环和循环中request(1:ir)
中拥有所有句柄并发出:
call MPI_Waitall(ir,request(1:ir),status(:,1:ir),ierr)
这将确保所有请求都已正确初始化。
另一件事:n(i)
中的MPI_Isend
与nsize
中的MPI_Irecv
保持相同的价值吗?
编辑:
在查阅MPI标准(3.0,Ch.3.7.3)后,我认为如果要将整个请求数组提供给MPI_REQUEST_NULL
,则需要将请求数组初始化为MPI_Waitall
。