Ошибка сегментации MPI_Waitsome?

У меня есть что-то вроде:

int numprocs, id, arr[10], winner = -1;
bool stop = false;
MPI_Request reqs[10], winnerNotification;

MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);

srand(time(NULL) + id);

if (id == 10) {
    int completed = 0;
    int* completedIndexes;
    for (int i = 0; i < 10; i++) {
        MPI_Irecv(&arr[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]);
    }
    MPI_Waitsome(10, reqs, &completed, completedIndexes, MPI_STATUSES_IGNORE);
    cout << completed << " seems to have completed" << endl;
    for (int i = 0; i < completed; i++) {
        cout << completedIndexes[i] << " have completed!";
    }
}

while (id < 10 && winner == -1) {
    if (((rand() % 100) + 1) < 5) { // players have 5% chance of completing
        MPI_Send(&id, 1, MPI_INT, 10, 0, MPI_COMM_WORLD);
        cout << id << " completed" << endl;
        MPI_Wait(&winnerNotification, MPI_STATUS_IGNORE);
    }
}

MPI_Finalize();

Что дает ошибку сегментации, я думаю, это как-то связано с Уэйтсомом? Но что? Ошибка выглядит так:

1 completed
[JM:01317] *** Process received signal ***
[JM:01317] Signal: Segmentation fault (11)
[JM:01317] Signal code: Address not mapped (1)
[JM:01317] Failing at address: 0x646574
4 completed
5 completed
[JM:01320] *** Process received signal ***
[JM:01320] Signal: Segmentation fault (11)
[JM:01320] Signal code: Address not mapped (1)
[JM:01320] Failing at address: 0x646574
3 completed
[JM:01319] *** Process received signal ***
[JM:01319] Signal: Segmentation fault (11)
[JM:01319] Signal code: Address not mapped (1)
[JM:01319] Failing at address: 0x646574
...

person Jiew Meng    schedule 17.11.2012    source источник


Ответы (1)


MPI_Waitsome ожидает массив целых чисел, где он хранит индексы выполненных запросов, но то, что вы ему даете, является неинициализированным указателем int. Учитывая тот факт, что вы жестко запрограммировали 10 как количество запросов, следующий код должен работать:

if (id == 10) {
    int completed = 0;
    int completedIndexes[10];
    for (int i = 0; i < 10; i++) {
        MPI_Irecv(&arr[i], 1, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]);
    }
    MPI_Waitsome(10, reqs, &completed, completedIndexes, MPI_STATUSES_IGNORE);
    cout << completed << " seems to have completed" << endl;
    for (int i = 0; i < completed; i++) {
        cout << completedIndexes[i] << " have completed!";
    }
}
person Hristo Iliev    schedule 17.11.2012
comment
Похоже, что максимальное завершенное значение равно 1? Я предполагаю, что это потому, что как только 1-й процесс отправит, это приведет к возврату ожидания? - person Jiew Meng; 17.11.2012
comment
Нет, это вызвано тем, как в Open MPI реализовано продвижение (доведение незавершенного неблокирующего запроса до завершения). Вы можете получать запросы, обслуживаемые в фоновом режиме, если компилируете Open MPI с включенным потоком прогрессии. Но это влияет на задержку некоторых операций. Если вы хотите дождаться завершения ВСЕХ приемов, используйте MPI_WAITALL. - person Hristo Iliev; 17.11.2012
comment
Хм, проблема в том, что не все процессы могут завершиться. Я хочу зафиксировать только процессы, которые завершаются одновременно (по крайней мере, примерно) - person Jiew Meng; 18.11.2012