【问题标题】:The relation between MPI_Comm_split and MPI_Send / MPI_RecvMPI_Comm_split 与 MPI_Send / MPI_Recv 的关系
【发布时间】:2018-05-29 04:15:54
【问题描述】:

假设有 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 究竟是什么关系?

【问题讨论】:

    标签: parallel-processing mpi


    【解决方案1】:

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

    在您的示例中,等级1 挂在MPI_Recv() 中,因此等级0 上的MPI_Comm_split() 无法完成(并且永远不会调用MPI_Send())并因此出现死锁。

    您可以考虑使用padb 来可视化 MPI 程序的状态,这样可以很容易地看到堆栈卡在哪里。

    【讨论】:

    • 再一次,你给了我想要的答案。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2011-11-11
    • 2016-04-22
    • 2014-04-17
    • 2011-01-24
    • 2016-09-09
    • 2017-10-25
    • 2018-03-05
    • 2015-05-14
    相关资源
    最近更新 更多