使用 MPI_Bcast 进行 MPI 通信

Posted

技术标签:

【中文标题】使用 MPI_Bcast 进行 MPI 通信【英文标题】:Using MPI_Bcast for MPI communication 【发布时间】:2011-12-13 10:13:10 【问题描述】:

我正在尝试使用 MPI_Bcast 从根节点向所有其他节点广播消息。但是,每当我运行这个程序时,它总是在开始时挂起。有人知道这是怎么回事吗?

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) 
        int rank;
        int buf;
        MPI_Status status;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        if(rank == 0) 
                buf = 777;
                MPI_Bcast(&buf, 1, MPI_INT, 0, MPI_COMM_WORLD);
        
        else 
                MPI_Recv(&buf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
                printf("rank %d receiving received %d\n", rank, buf);
        

        MPI_Finalize();
        return 0;

【问题讨论】:

【参考方案1】:

对于刚接触 MPI 的人来说,这是一个常见的困惑来源。您不使用MPI_Recv() 接收广播发送的数据;你用MPI_Bcast()

例如,你想要的是这样的:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) 
        int rank;
        int buf;
        const int root=0;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        if(rank == root) 
           buf = 777;
        

        printf("[%d]: Before Bcast, buf is %d\n", rank, buf);

        /* everyone calls bcast, data is taken from root and ends up in everyone's buf */
        MPI_Bcast(&buf, 1, MPI_INT, root, MPI_COMM_WORLD);

        printf("[%d]: After Bcast, buf is %d\n", rank, buf);

        MPI_Finalize();
        return 0;

对于 MPI 集体沟通,每个人都必须参与;每个人都必须打电话给 Bcast,或 Allreduce,或者你有什么。 (这就是为什么 Bcast 例程有一个参数来指定“根”,或者谁在进行发送;如果只有发送者调用 bcast,你就不需要这个了。)每个人都调用广播,包括接收者;接收者不只是发布接收。

这样做的原因是集体操作可以让每个人都参与到通信中,因此您可以陈述您想要发生的事情(每个人都获得一个进程的数据)而不是如何发生它发生(例如,根处理器循环所有其他等级并进行发送),因此存在优化通信模式的空间(例如,基于树的分层通信采用log(P) 步骤而不是P 步骤用于P 进程)。

【讨论】:

感谢您这样解释。但是,我仍然对如何让每个节点使用 MPI_Recv 接收消息感到困惑。我尝试将 MPI_Recv 调用包装在 if(rank != 0) 块中并且没有,但我的程序仍然不打印任何内容。你知道如何在每个节点上也接收消息吗? 你没有。 MPI_Bcast 不像发送;这是一个每个人都参与的集体操作,发送者和接收者,在通话结束时,接收者拥有发送者拥有的价值。如果rank == root(此处为0),则相同的函数调用(类似于)发送,否则(类似于)接收。我已经更新了上面的代码,所以你可以看到每个人都得到了相同的结果。 @David:如果您认为MPI_Bcast 的意思是“参加广播活动”,那可能更有意义。 这条评论是天赐之物...我发誓 MPI 的设计意图是不直观或模棱两可的...【参考方案2】:

MPI_Bcast是一个集体操作,必须被所有进程调用才能完成。

并且使用MPI_Bcast时无需调用MPI_Recv。有一个帖子可能对你有帮助,click here

【讨论】:

以上是关于使用 MPI_Bcast 进行 MPI 通信的主要内容,如果未能解决你的问题,请参考以下文章

MPI学习四-集合通信

使用 MPI_Bcast 时出现 MPI 分段错误

MPI_Bcast对应的接收程序

探测 MPI_Bcast 或 MPI_Send

MPI_Bcast 动态二维数组

创建 MPI 结构时出现问题,调用 MPI_Bcast 时出现错误 11