使用 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 通信的主要内容,如果未能解决你的问题,请参考以下文章