2011-09-25 16 views
2

我刚刚尝试过使用MPI,并复制并运行了代码,取自第二代代码示例[LLNL MPI教程] [1]。MPI Irecv无法正确接收缓冲区的第一个元素?

#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 

也就是说,消息(带有标签== 1)进入缓冲区buf [0]总是得到值0.此外,如果我改变代码,以便声明缓冲区为buf [3]而不是buf [2],并将每个实例buf [0]和buf [2],那么我就可以精确地得到我的输出结果预期的(即,上面给出的第一组输出)。这看起来好像出于某种原因,某些东西是用0覆盖buf [0]中的值。但是我看不出可能是什么。顺便说一句,据我所知,我的代码(没有修改)完全符合教程中的代码,除了我的printf。

谢谢!

回答

4

状态数组的大小必须是4而不是2.在你的情况下,MPI_Waitall在写入状态时会破坏内存。

+0

就是这样!非常感谢!错误在于原始的教程代码,所以我会给他们写一个错误报告。 –