MPI_Waitall的“死锁”

时间:2013-05-17 15:05:43

标签: c++ mpi deadlock

我正在尝试将每个进程的一些数据发送到它的邻居(按排名)。为此,我尝试使用非阻止发送和接收调用MPI_Isend / MPI_Irecv以及对MPI_Waitall的相应调用,以确保在使用数据之前已完成传输。< / p>

以下是我正在尝试做的最小例子

#include <mpi.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    MPI_Init(&argc,&argv);
    int rank,comm_size;

    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size);

    MPI_Request reqs[4];

    int sbuff1[10];
    int sbuff2[10];
    int rbuff1[10];
    int rbuff2[10];

    int count = 0;

    if(rank>0)
    {
        MPI_Irecv(rbuff1,10,MPI_INT,rank-1,0,MPI_COMM_WORLD,&reqs[count]);
        count++;
        MPI_Isend(sbuff1,10,MPI_INT,rank-1,1,MPI_COMM_WORLD,&reqs[count]);
        count++;
    }

    if(rank<comm_size-1)
    {
        MPI_Irecv(rbuff2,10,MPI_INT,rank+1,2,MPI_COMM_WORLD,&reqs[count]);
        count++;
        MPI_Isend(sbuff2,10,MPI_INT,rank+1,3,MPI_COMM_WORLD,&reqs[count]);
        count++;
    }

    MPI_Waitall(count,reqs,MPI_STATUS_IGNORE);

    if(rank==0)
            cout << "Successfully exchanged data." << endl;

    MPI_Finalize();

    return 0;
}

不幸的是,这段代码永远不会在最后打印出来。

我的问题是:数据是否正确发送,但我对MPI_Waitall的调用有些不对?如果是这样,我需要更改什么才能使这个简单的代码运行,如果不是,那么还有什么不妥?

1 个答案:

答案 0 :(得分:1)

您设置的发送/接收标签永远不会匹配。

这个小修补

#include <mpi.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    MPI_Init(&argc,&argv);
    int rank,comm_size;

    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size);

    MPI_Request reqs[4];

    int sbuff1[10];
    int sbuff2[10];
    int rbuff1[10];
    int rbuff2[10];

    int count = 0;

    if(rank>0)
    {

        MPI_Irecv(rbuff1,10,MPI_INT,rank-1,0,MPI_COMM_WORLD,&reqs[count]);
        count++;
        MPI_Isend(sbuff1,10,MPI_INT,rank-1,1,MPI_COMM_WORLD,&reqs[count]);
        count++;
    }

    if(rank<comm_size-1)
    {
        /// changed tag 2 -> 1 
        // MPI_Irecv(rbuff2,10,MPI_INT,rank+1,2,MPI_COMM_WORLD,&reqs[count]);
        MPI_Irecv(rbuff2,10,MPI_INT,rank+1,1,MPI_COMM_WORLD,&reqs[count]);
        count++;

        /// changed tag 3 -> 0 
        // MPI_Isend(sbuff2,10,MPI_INT,rank+1,3,MPI_COMM_WORLD,&reqs[count]);
        MPI_Isend(sbuff2,10,MPI_INT,rank+1,0,MPI_COMM_WORLD,&reqs[count]);
        count++;
    }

    MPI_Waitall(count,reqs,MPI_STATUS_IGNORE);

    if(rank==0)
            cout << "Successfully exchanged data." << endl;

    MPI_Finalize();

    return 0;
}

让它发挥作用

$> mpirun -n 5 ./testling 
Successfully exchanged data.

使用mpich2 v1.5(Hydra)在x86_84 Linux上运行