Ошибка сегментации при использовании MPI_File_read_at

Я пытаюсь написать простой метод для параллельного чтения файла, где каждый процесс будет читать несколько целых чисел из файла, чтобы разделить данные на каждый процесс, но я получаю ошибку сегментации, и я не могу понять, почему и как почини это. Вот код, который я написал:

#include <stdio.h>
#include <stdlib.h>

#include "mpi.h"

#define NUM_INTS 5

int main (int argc, char** argv) {

MPI_Init(&argc, &argv);

int i;
int rank,processes,name_len;
const int root=0;
int *buf;
char *filename = "file.txt";

MPI_File fh;
MPI_Status status;
MPI_Offset offset;

char processor_name[MPI_MAX_PROCESSOR_NAME];

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &processes);
MPI_Get_processor_name(processor_name, &name_len);

MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);

buf = malloc(NUM_INTS * sizeof(int));

MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, (char *)NULL, MPI_INFO_NULL);

offset = rank * NUM_INTS;

MPI_File_read_at(fh, offset, buf, NUM_INTS, MPI_INT, &status);
MPI_Barrier(MPI_COMM_WORLD);

MPI_File_close(&fh);

for (i=0;i<NUM_INTS;i++)
    printf("rank %d data[%d] = %d\n", rank, i, buf[i]);

free(buf);

MPI_Finalize();
return 0;
}

Файл содержит 10 целых чисел, которые я пытался разделить на 2 процесса. Я думаю, что проблема в MPI_File_read_at, потому что все отпечатки работают до этой строки

заранее спасибо


person Thanos Gourgiotis    schedule 24.10.2014    source источник


Ответы (2)


Почему вы передаете «ноль» своему представлению типа данных? (собственно, зачем вы вообще настраиваете просмотр файла?)

Если бы вы последовали совету @Colin Cassidy, ваша обратная трассировка указывала бы прямо на проблему: это не MPI_File_read_at, это MPI_File_set_view.

Либо удалите эту строку, либо измените (char *)NULL на "native"

Кроме того, вы должны проверить возвращаемые значения, но здесь это вам не поможет. См. мой ответ на этот вопрос: Как использовать и интерпретировать коды ошибок MPI-IO?

MPICH (точнее ROMIO) не должен segfault на вашем мусорном вводе. У меня есть патч для этого на рассмотрении. Это имеет забавный побочный эффект: ваш вызов MPI_File_set_view возвращает ошибку, которую вы игнорируете, а затем остальная часть вашего кода ведет себя так, как вы этого хотели.

person Rob Latham    schedule 24.10.2014
comment
Я не совсем понял, как использовать MPI_File_set_view, так что спасибо, что указали на это. Хотя я пытался закомментировать эту строку и использовать нативную, но она все еще не работает должным образом. Я получаю вывод от buf в процессе 0, но это мусор, а затем он зависает, я ничего не получаю от процесса 1, и мне приходится прерывать его вручную. Я также пытался использовать gdb, и он показывает только данные о buf из процесса 0. Я не очень опытен, поэтому простите меня, если я упустил что-то очевидное. Спасибо за ваше время в любом случае - person Thanos Gourgiotis; 27.10.2014
comment
Забыл упомянуть, что я тоже запускаю его на одном процессе и он не зависает, но у меня все равно такая же фигня в buf - person Thanos Gourgiotis; 27.10.2014
comment
потому что ваш файл содержит текстовые числа? Если вы читаете текст, ваша обработка будет немного другой (и, вероятно, более сложной). - person Rob Latham; 27.10.2014

Не зная полностью о функциональности MPI, я не уверен на 100%, в чем ваша проблема, однако вот несколько общих советов по отладке, которые вы можете использовать, чтобы попытаться отследить проблему.

1) Используйте отладчик. GDB или что-то подобное — ваш друг здесь, вы должны иметь возможность использовать его для пошагового выполнения вашей программы построчно, наблюдая за всеми переменными по мере продвижения, и это должно помочь вам отследить, где именно он генерирует ошибку сегментации, и вы должны знать значения переменных на данный момент. Это должно очень помочь отследить, в чем проблема.

2) Если у вас есть дамп ядра, вы можете снова использовать gdb для выполнения посмертной отладки и получить трассировку стека с момента сбоя, это может пролить свет на проблему.

3) В противном случае вы всегда можете использовать метод отладки «printf()», отлаживать/сбрасывать все по мере расчета, это может помочь, но в прошлом я обнаружил, что это может привести к изменению расположения вещей в памяти. а иногда и убрать краш... Обратите внимание, что это не решает вашу проблему, вы просто перераспределили память так, чтобы он не крашился при текущих обстоятельствах.

person Colin Cassidy    schedule 24.10.2014
comment
Я уже использовал несколько отпечатков и знаю, что указатель файла не равен NULL, выделен buf, а смещение имеет правильные значения в каждом процессе (0 в корне, 5 в процессе 1). - person Thanos Gourgiotis; 24.10.2014
comment
хорошо, начнем с самого простого случая, работает ли файл с 1 целым числом, прочитанным одним процессом? затем попробуйте 2 целых числа с одним процессом, затем 2 целых числа с двумя процессами, каждый из которых читает по одному файлу. Затем определите, какой процесс работает, 0 начальных процессов или смещенный. - person Colin Cassidy; 24.10.2014