Я пытаюсь отправить массив из одного процесса (ранга) в другой по «кругу», используя MPI в C. Я могу заставить его работать нормально, используя одиночные целые числа, но получаю ошибки сегментации, когда пытаюсь отправить массив через.
{
int rank;
int numRanks;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numRanks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int arraysize = 100;
int *array;
if (rank == 0) {
array = malloc(sizeof(int)*arrasize);
for (int i = 0; i < arraysize; i++) {
array[i] = 1;
}
double starttime = MPI_Wtime();
MPI_Send(&array, arraysize, MPI_INT, (rank+1), 0, MPI_COMM_WORLD);
MPI_Recv(&array, arraysize, MPI_INT, numRanks-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
double endtime = MPI_Wtime();
printf("Rank %d got array from Rank %d in %lf", rank, numRanks-1, endtime-starttime);
} else if (rank == (numRanks-1)) {
MPI_Recv(&array, arraysize, MPI_INT, rank-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Rank %d got array from Rank %d", rank, rank-1);
MPI_Send(&array, arraysize, MPI_INT, 0, 0, MPI_COMM_WORLD);
} else {
MPI_Recv(&array, arraysize, MPI_INT, rank-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Rank %d got array from Rank %d", rank, rank-1);
MPI_Send(&array, arraysize, MPI_INT, (rank+1), 0, MPI_COMM_WORLD);
}
free(array);
MPI_Finalize();
return 0;
}
Вот сообщение об ошибке (сейчас для простоты я использую только три ранга):
Rank 1 got array from Rank 0
[winston:42137] *** Process received signal ***
[winston:42137] Signal: Segmentation fault (11)
[winston:42137] Signal code: Address not mapped (1)
[winston:42137] Failing at address: 0x7add28
а затем еще одно и то же для каждого ранга, пытающегося отправить и получить массив
любая помощь, которую кто-либо может предоставить, будет принята с благодарностью!
Ваш array
не указывает на действительный адрес памяти в каждом процессе (ранге), кроме 0-го.
Это приведет к сбою вашей программы при попытке написать что-то по случайному (т.е. недопустимому) адресу, когда вы вызываете MPI_Recv(&array, arraysize...
.
(Спасибо Gilles Gouaillardet, указанному в комментарии) И вы должны передать array
(не &array
) функциям MPI, потому что он сам является указателем на адрес, по которому вам выделено место для хранения немногоint
.
Итак, решение будет:
array = malloc(sizeof(int)*arrasize);
для каждого процесса.MPI_Recv(&array
(и MPI_Send(&array
) на MPI_Recv(array
(и MPI_Send(array
.также буфер, который должен быть передан в MPI, равен buffer
и нет&buffer
@GillesGouaillardet да! большое спасибо. Не могу поверить, что я этого не видел. Полностью исправлено!
@GillesGouaillardet Вы правы. Я тоже не заметил... Добавлю эту информацию в ответ. (Давно не использовал C/C++.)
если вы скомпилируете программу с параметром -грамм и запустите ее под gdb, она остановится при получении ошибки сегментации, а с помощью команды бт вы увидите, где это произошло. валгринд также является еще одним инструментом, который вы должны использовать.