我有一个MPI程序,其中worker rank(rank!= 0)进行一堆MPI_Send调用,并且master rank(rank == 0)接收所有这些消息。但是,我在MPI_Recv中遇到致命错误 - MPI_Recv(...)失败,内存不足。
以下是我在Visual Studio 2010中编译的代码。 我像这样运行可执行文件:
mpiexec -n 3 MPIHelloWorld.exe
int main(int argc, char* argv[]){
int numprocs, rank, namelen, num_threads, thread_id;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Get_processor_name(processor_name, &namelen);
if(rank == 0){
for(int k=1; k<numprocs; k++){
for(int i=0; i<1000000; i++){
double x;
MPI_Recv(&x, 1, MPI_DOUBLE, k, i, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
}
else{
for(int i=0; i<1000000; i++){
double x = 5;
MPI_Send(&x, 1, MPI_DOUBLE, 0, i, MPI_COMM_WORLD);
}
}
}
如果我只运行2个进程,程序不会崩溃。所以似乎问题是当从第三级(也称为第二个工作节点)累积MPI_Send调用时。
如果我将迭代次数减少到100,000,那么我可以运行3个进程而不会崩溃。但是,一百万次迭代发送的数据量大约为8 MB(双倍* 1000000次迭代时为8个字节),因此我认为“内存不足”指的是任何物理内存,如RAM。
感谢任何见解,谢谢!
答案 0 :(得分:1)
MPI_send
操作将数据存储在准备发送的system buffer上。此缓冲区的大小及其存储位置为implementation specific(我记得听说这甚至可以在互连中)。在我的情况下(linux与mpich)我没有得到内存错误。明确更改此缓冲区的一种方法是将MPI_buffer_attach
与MPI_Bsend
一起使用。可能还有一种方法可以更改系统缓冲区大小(例如IBM系统上的MP_BUFFER_MEM
系统变量)。
然而,在实践中可能不会发生这种无回复消息的情况。在上面的示例中,可以交换k
和i
循环的顺序,以防止此消息的累积。