MPI_Comm_split与MPI_Send / MPI_Recv之间的关系

时间:2017-12-15 00:20:36

标签: parallel-processing mpi

假设有3个进程,此代码可以正常工作:

#include <iostream>
#include <mpi.h>
using namespace std;

int main(){

    MPI_Init(NULL, NULL);

    int rank; MPI_Comm SubWorld; int buf;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if (rank == 0){
        MPI_Comm_split(MPI_COMM_WORLD, rank, rank, &SubWorld);
        MPI_Send(&buf, 1, MPI_INT, 1, 55, MPI_COMM_WORLD);
    }
    else if (rank == 1){
        MPI_Comm_split(MPI_COMM_WORLD, rank, rank, &SubWorld);
        MPI_Recv(&buf, 1, MPI_INT, 0, 55, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    }
    else MPI_Comm_split(MPI_COMM_WORLD, rank, rank, &SubWorld);

    cout << "Done" << endl;

    MPI_Finalize();

    return 0;
}

按预期输出“完成”三次。

但是这段代码有问题(也有3个进程):

#include <iostream>
#include <mpi.h>
using namespace std;

int main(){

    MPI_Init(NULL, NULL);

    int rank; MPI_Comm SubWorld; int buf;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if (rank == 0){
        MPI_Comm_split(MPI_COMM_WORLD, rank, rank, &SubWorld);
        MPI_Send(&buf, 1, MPI_INT, 1, 55, MPI_COMM_WORLD);
    }
    else if (rank == 1){
        MPI_Recv(&buf, 1, MPI_INT, 0, 55, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        MPI_Comm_split(MPI_COMM_WORLD, rank, rank, &SubWorld);
    }
    else MPI_Comm_split(MPI_COMM_WORLD, rank, rank, &SubWorld);

    cout << "Done" << endl;

    MPI_Finalize();

    return 0;
}

没有输出!!

导致此问题的MPI_Comm_split和MPI_Send / MPI_Recv之间究竟有什么关系?

1 个答案:

答案 0 :(得分:0)

MPI_Comm_split()是一个集体操作,这意味着来自初始通信器的所有MPI任务(例如此处MPI_COMM_WORLD)必须同时调用它。

在您的示例中,排名1会在MPI_Recv()中挂起,因此排名MPI_Comm_split()上的0无法完成(并且永远不会调用MPI_Send())因此僵局。

您可能会考虑padb以便可视化MPI程序的状态,这样可以很容易地看到堆栈停留在哪里。