我刚刚尝试使用MPI,并从[LLNL MPI教程] [1]的第二个代码示例中复制并运行了此代码。
#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char ** argv) {
int num_tasks, rank, next, prev, buf[2], tag1 = 1, tag2 = 2;
MPI_Request reqs[4];
MPI_Status status[2];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_tasks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
prev = rank - 1;
next = rank + 1;
if (rank == 0) prev = num_tasks - 1;
if (rank == (num_tasks - 1)) next = 0;
MPI_Irecv(&buf[0], 1, MPI_INT, prev, tag1, MPI_COMM_WORLD,
&reqs[0]);
MPI_Irecv(&buf[1], 1, MPI_INT, next, tag2, MPI_COMM_WORLD,
&reqs[1]);
MPI_Isend(&rank, 1, MPI_INT, prev, tag2, MPI_COMM_WORLD, &reqs[2]);
MPI_Isend(&rank, 1, MPI_INT, next, tag1, MPI_COMM_WORLD, &reqs[3]);
MPI_Waitall(4, reqs, status);
printf("Task %d received %d from %d and %d from %d\n",
rank, buf[0], prev, buf[1], next);
MPI_Finalize();
return EXIT_SUCCESS;
}
我本来期望这样的输出(例如,4个任务):
$ mpiexec -n 4 ./m3
Task 0 received 3 from 3 and 1 from 1
Task 1 received 0 from 0 and 2 from 2
Task 2 received 1 from 1 and 3 from 3
Task 3 received 2 from 2 and 0 from 0
然而,相反,我明白了:
$ mpiexec -n 4 ./m3
Task 0 received 0 from 3 and 1 from 1
Task 1 received 0 from 0 and 2 from 2
Task 3 received 0 from 2 and 0 from 0
Task 2 received 0 from 1 and 3 from 3
也就是说,进入缓冲区buf [0]的消息(带有标签== 1)总是得到值0.此外,如果我改变代码以便我将缓冲区声明为buf [3]而不是buf [2] ],并用buf [2]替换buf [0]的每个实例,然后我得到我预期的输出(即上面给出的第一个输出集)。由于某种原因,这看起来好像是用0覆盖buf [0]中的值。但是我看不出那可能是什么。顺便说一下,据我所知,我的代码(没有修改)与教程中的代码完全匹配,除了我的printf。
谢谢!
答案 0 :(得分:4)
状态数组的大小必须为4而不是2.在您的情况下,MPI_Waitall在写入状态时会破坏内存。