MPI 异步发送和接收未按预期工作
MPI Asynchoronous Send and Receive not working as expected
我对使用 C 中的 MPI 库进行通信有疑问。这是我的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main (int argc, char **argv) {
// Initialize the MPI Environment
MPI_Init (&argc, &argv);
int world_size;
MPI_Comm_size (MPI_COMM_WORLD, &world_size);
int world_rank;
MPI_Comm_rank (MPI_COMM_WORLD, &world_rank);
int workers = world_size - 1;
if (world_rank == 0) {
}
else if (world_rank == 1) {
int to_recv;
int to_send = world_rank;
MPI_Request request1, request2;
MPI_Irecv (&to_recv, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request1);
MPI_Isend (&to_send, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request2);
MPI_Wait (&request1, MPI_STATUS_IGNORE);
MPI_Wait (&request2, MPI_STATUS_IGNORE);
printf("I am %d\n", world_rank);
printf("I received rank %d\n", to_recv);
}
else if (world_rank == workers) {
int to_recv;
int to_send = world_rank;
MPI_Request request1, request2;
MPI_Irecv (&to_recv, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request1);
MPI_Isend (&to_send, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request2);
MPI_Wait (&request1, MPI_STATUS_IGNORE);
MPI_Wait (&request2, MPI_STATUS_IGNORE);
printf("I am %d\n", world_rank);
printf("I received rank %d\n", to_recv);
}
else {
int to_recvl, to_recvr;
int to_send1 = world_rank, to_send2 = world_rank;
MPI_Request request1, request2, request3, request4;
MPI_Irecv (&to_recvl, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request1);
MPI_Isend (&to_send1, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request2);
MPI_Irecv (&to_recvr, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request3);
MPI_Isend (&to_send2, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request4);
MPI_Wait (&request1, MPI_STATUS_IGNORE);
MPI_Wait (&request2, MPI_STATUS_IGNORE);
MPI_Wait (&request3, MPI_STATUS_IGNORE);
MPI_Wait (&request4, MPI_STATUS_IGNORE);
printf("I am %d\n", world_rank);
printf("I received ranks %d and %d\n", to_recvl, to_recvr);
}
MPI_Finalize ();
return 0;
}
所以这就是我基本上想要完成的:
假设我产生了 11 个进程(0 个是主进程,进程 1-10 个工作进程)。那么,
- 进程 1 将其排名发送给进程 2
- 进程 1 从进程 2 获得排名
- 进程 10 将其排名发送给进程 9
- 进程 10 从进程 9 获得排名
- 进程 i 将其排名发送给进程 i+1 和 i-1 (1 < i < 10)
- 进程 i 从进程 i+1 和 i-1 接收排名 (1 < i < 10)
虽然 运行 程序,但在某些情况下我会得到垃圾值,例如下面添加的那个:
I am 2
I received ranks 1 and 3
I am 3
I received ranks 2 and 4
I am 4
I received ranks 1499161032 and 5
I am 6
I received ranks 1488867784 and 7
I am 9
I received rank 8
I am 32767
I received rank 2
I am 5
I received ranks 1507000776 and 6
I am 7
I received ranks 6 and 8
I am 8
I received ranks 7 and 9
我不知道是什么导致了这个问题。任何帮助将不胜感激。
谢谢!
一个非常简单的问题,MPI_Isend()
和 MPI_Irecv()
中的第二个参数应该是您希望发送或接收的元素的 count
。您使用的 sizeof(int)
在大多数系统中是 4
,而您只想 send/receive 1 个元素,因此计数应该是 1。
我对使用 C 中的 MPI 库进行通信有疑问。这是我的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main (int argc, char **argv) {
// Initialize the MPI Environment
MPI_Init (&argc, &argv);
int world_size;
MPI_Comm_size (MPI_COMM_WORLD, &world_size);
int world_rank;
MPI_Comm_rank (MPI_COMM_WORLD, &world_rank);
int workers = world_size - 1;
if (world_rank == 0) {
}
else if (world_rank == 1) {
int to_recv;
int to_send = world_rank;
MPI_Request request1, request2;
MPI_Irecv (&to_recv, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request1);
MPI_Isend (&to_send, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request2);
MPI_Wait (&request1, MPI_STATUS_IGNORE);
MPI_Wait (&request2, MPI_STATUS_IGNORE);
printf("I am %d\n", world_rank);
printf("I received rank %d\n", to_recv);
}
else if (world_rank == workers) {
int to_recv;
int to_send = world_rank;
MPI_Request request1, request2;
MPI_Irecv (&to_recv, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request1);
MPI_Isend (&to_send, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request2);
MPI_Wait (&request1, MPI_STATUS_IGNORE);
MPI_Wait (&request2, MPI_STATUS_IGNORE);
printf("I am %d\n", world_rank);
printf("I received rank %d\n", to_recv);
}
else {
int to_recvl, to_recvr;
int to_send1 = world_rank, to_send2 = world_rank;
MPI_Request request1, request2, request3, request4;
MPI_Irecv (&to_recvl, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request1);
MPI_Isend (&to_send1, sizeof (int), MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, &request2);
MPI_Irecv (&to_recvr, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request3);
MPI_Isend (&to_send2, sizeof (int), MPI_INT, world_rank + 1, 0, MPI_COMM_WORLD, &request4);
MPI_Wait (&request1, MPI_STATUS_IGNORE);
MPI_Wait (&request2, MPI_STATUS_IGNORE);
MPI_Wait (&request3, MPI_STATUS_IGNORE);
MPI_Wait (&request4, MPI_STATUS_IGNORE);
printf("I am %d\n", world_rank);
printf("I received ranks %d and %d\n", to_recvl, to_recvr);
}
MPI_Finalize ();
return 0;
}
所以这就是我基本上想要完成的:
假设我产生了 11 个进程(0 个是主进程,进程 1-10 个工作进程)。那么,
- 进程 1 将其排名发送给进程 2
- 进程 1 从进程 2 获得排名
- 进程 10 将其排名发送给进程 9
- 进程 10 从进程 9 获得排名
- 进程 i 将其排名发送给进程 i+1 和 i-1 (1 < i < 10)
- 进程 i 从进程 i+1 和 i-1 接收排名 (1 < i < 10)
虽然 运行 程序,但在某些情况下我会得到垃圾值,例如下面添加的那个:
I am 2
I received ranks 1 and 3
I am 3
I received ranks 2 and 4
I am 4
I received ranks 1499161032 and 5
I am 6
I received ranks 1488867784 and 7
I am 9
I received rank 8
I am 32767
I received rank 2
I am 5
I received ranks 1507000776 and 6
I am 7
I received ranks 6 and 8
I am 8
I received ranks 7 and 9
我不知道是什么导致了这个问题。任何帮助将不胜感激。
谢谢!
一个非常简单的问题,MPI_Isend()
和 MPI_Irecv()
中的第二个参数应该是您希望发送或接收的元素的 count
。您使用的 sizeof(int)
在大多数系统中是 4
,而您只想 send/receive 1 个元素,因此计数应该是 1。