MPI Irecv не может правильно получить первый элемент буфера? - PullRequest
2 голосов
/ 25 сентября 2011

Я только что экспериментировал с 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

То есть сообщение (с тегом == 1)вход в буфер buf [0] всегда получает значение 0. Более того, если я изменю код так, чтобы я объявил буфер как buf [3], а не buf [2], и заменил каждый экземпляр buf [0] на buf [2], тогда я получаю именно тот результат, который ожидал (т. е. первый набор выходных данных, указанный выше).Это выглядит так, как будто по какой-то причине что-то перезаписывает значение в buf [0] на 0. Но я не вижу, что это может быть.Кстати, насколько я могу судить, мой код (без модификации) точно соответствует коду в учебнике, за исключением моего printf.

Спасибо!

1 Ответ

4 голосов
/ 25 сентября 2011

Массив статусов должен иметь размер 4, а не 2. В вашем случае MPI_Waitall портит память при записи статусов.

...