Линейный поиск MPI (остановка в другом процессе) - PullRequest
0 голосов
/ 27 мая 2018

Я пытаюсь написать простую многопроцессорную программу, чтобы найти значение в массиве.

#include <mpi.h>
#include <stdio.h>

int* create_array(int num_items) {
    int* tmp = new int[num_items];
    for(int i = 0; i < num_items; i++)
        tmp[i] = i;

    return tmp;
}

int main() {

    int num_items = 1000;
    int item = 999;

    MPI_Init(NULL, NULL);
    int world_rank, world_size, num_items_per_proc;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    MPI_Request* inReq;

    int* array;
    if(world_rank == 0) {
        array = create_array(num_items);
        num_items_per_proc = (num_items / world_size) + 1;
    }

    int* sub_array = new int[num_items_per_proc];
    MPI_Scatter(array, num_items_per_proc, MPI_INT, sub_array,
                num_items_per_proc, MPI_INT, 0, MPI_COMM_WORLD);

    bool found = false;
    MPI_Irecv(&found, 1, MPI::BOOL, MPI_ANY_SOURCE, MPI_ANY_TAG,
              MPI_COMM_WORLD, inReq);

    for(int i = 0; i < num_items_per_proc && !found; i++) {
        if (sub_array[i] == item) {
            found = true;
            printf("Elemento %d trovato in posizione: %d\n", item, i);
            for(int j = 0; j < world_size; j++)
                if(j != world_rank)
                    MPI_Send(&found, 1, MPI::BOOL, j, j, MPI_COMM_WORLD);
        }
    }

    if(world_rank == 0) delete[] array;
    delete[] sub_array;

    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();

    return 0;
}

Я пытаюсь остановить все, когда один из них нашел значение в части массива, но я получил ошибку сегментации формы Irecv.Как я могу решить это?

1 Ответ

0 голосов
/ 28 мая 2018

Причина, по которой ваш код не работает, заключается в том, что вы должны указать действительное значение MPI_Request для MPI_Irecv, а не просто указатель неинициализированный !

MPI_Request inReq;
MPI_Irecv(&found, 1, MPI_CXX_BOOL, MPI_ANY_SOURCE, MPI_ANY_TAG,
          MPI_COMM_WORLD, &inReq);

То, как выручка found неверна.Вы не должны изменять переменную, данную асинхронному запросу, и вы не можете просто предполагать, что она обновляется в фоновом режиме.Неблокирующие сообщения - это , а не односторонние операции с удаленной памятью.Таким образом, вы должны вызвать тест и, если статус указывает на полученное сообщение, вы можете прервать цикл.Убедитесь, что каждый запрос выполнен, также в ранге, который нашел результат.

Далее, num_items_per_proc должен быть действительным во всех рангах (для выделения памяти и для указания recvcount в MPI_Scatter.

Барьер до MPI_Finalize является избыточным и, наконец, C ++ привязки MPI были удалены, используйте MPI_CXX_BOOL вместо MPI::BOOL.

. Вы можете найти более сложные подходы кВаша проблема в ответах на этот вопрос .

...