与 MPI_SEND 在循环中排名和在 MPI 中不循环发送有什么不同
What is different from MPI_SEND with rank in a loop and sending without loop in MPI
我正在尝试这些逻辑代码,但我不知道它们之间有什么不同。我正在尝试在我的程序中使用 MPI_Send()
和 MPI_Recv()
。据我了解,在 MPI 中,进程通过每个处理器的等级和每条消息的标签进行通信。那么,如果我尝试
有什么不同
逻辑 1:
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
逻辑 2:
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
int i =0;
for(i = 1 ; i< world_size;i++){
MPI_Send(&number, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}else{
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
我试试:mpirun -np 100 ./test <arguments>
- 逻辑 1:几分钟后,我的计算机挂起。
- 逻辑 2:有效,打印 100 行:
Process kali received number -1 from process 0
我认为这两种逻辑都会获得进程的等级,并将其解析为 MPI_Send 上的参数。有什么不同???
我正在使用 OpenMPI 1.8 开发 Debian Kali Linux。
我是 MPI 的新手。感谢您的帮助。
这是非常不同的。
一方面,在逻辑 1 中,单个消息从进程 0 发送到进程 1。另一方面,在逻辑 2 中,world_size-1
条消息由进程 0 和每个剩余进程发送从 0 收到一条消息。第二种情况可以通过调用 MPI_Bcast()
.
来代替
如果您尝试过 mpirun -np 2 ./test <arguments>
这些代码会做同样的事情...但这是唯一的情况!
两个代码摘要似乎都是正确的。第一种情况的失败可能是因为整数number
没有在进程2到world_size
上初始化。例如,如果 number
是数组的长度,它会触发分段错误。如果 number
是 for
循环中停止条件的一部分,它可以触发无限循环(或非常长的循环)。
已编辑
由于我们缺少完整的源代码,因此无法确定 initialization/finalization 函数是否被正确使用。
这里我们有与初始答案相同的源代码 + 正确 运行 mpi 应用程序所需的内容:
#include <stdio.h>
#include <mpi.h>
int
main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
MPI_Finalize();
}
编译:
> mpicc -std=c99 -O2 -g -Wall -I. -o app app.c -lm
运行:
> mpirun -n 10 app
Process 1 received number -1 from process 0
>
基本上一切正常,所以我猜问题可能与 initialization/finalization.
有关
初步反应
您的应用程序以逻辑 1 挂起,因为有 99 个进程在等待一条消息,但主进程只将消息发送给排名为 1 的进程。
当您使用阻塞函数时(即 MPI_Send 与 MPI_Isend),有 98 个进程永远等待直到消息来自排名为 0、标记=0 且通讯器 MPI_COMM_WORLD.
我正在尝试这些逻辑代码,但我不知道它们之间有什么不同。我正在尝试在我的程序中使用 MPI_Send()
和 MPI_Recv()
。据我了解,在 MPI 中,进程通过每个处理器的等级和每条消息的标签进行通信。那么,如果我尝试
逻辑 1:
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
逻辑 2:
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
int i =0;
for(i = 1 ; i< world_size;i++){
MPI_Send(&number, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}else{
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
我试试:mpirun -np 100 ./test <arguments>
- 逻辑 1:几分钟后,我的计算机挂起。
- 逻辑 2:有效,打印 100 行:
Process kali received number -1 from process 0
我认为这两种逻辑都会获得进程的等级,并将其解析为 MPI_Send 上的参数。有什么不同???
我正在使用 OpenMPI 1.8 开发 Debian Kali Linux。 我是 MPI 的新手。感谢您的帮助。
这是非常不同的。
一方面,在逻辑 1 中,单个消息从进程 0 发送到进程 1。另一方面,在逻辑 2 中,world_size-1
条消息由进程 0 和每个剩余进程发送从 0 收到一条消息。第二种情况可以通过调用 MPI_Bcast()
.
如果您尝试过 mpirun -np 2 ./test <arguments>
这些代码会做同样的事情...但这是唯一的情况!
两个代码摘要似乎都是正确的。第一种情况的失败可能是因为整数number
没有在进程2到world_size
上初始化。例如,如果 number
是数组的长度,它会触发分段错误。如果 number
是 for
循环中停止条件的一部分,它可以触发无限循环(或非常长的循环)。
已编辑
由于我们缺少完整的源代码,因此无法确定 initialization/finalization 函数是否被正确使用。
这里我们有与初始答案相同的源代码 + 正确 运行 mpi 应用程序所需的内容:
#include <stdio.h>
#include <mpi.h>
int
main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
MPI_Finalize();
}
编译:
> mpicc -std=c99 -O2 -g -Wall -I. -o app app.c -lm
运行:
> mpirun -n 10 app
Process 1 received number -1 from process 0
>
基本上一切正常,所以我猜问题可能与 initialization/finalization.
有关初步反应
您的应用程序以逻辑 1 挂起,因为有 99 个进程在等待一条消息,但主进程只将消息发送给排名为 1 的进程。
当您使用阻塞函数时(即 MPI_Send 与 MPI_Isend),有 98 个进程永远等待直到消息来自排名为 0、标记=0 且通讯器 MPI_COMM_WORLD.