OpenMPI MPI_Gather segfault или ошибка утверждения

Я пытаюсь создать многопроцессорный трассировщик лучей для моего старшекурсника, используя OpenMPI, чтобы я мог запустить его на суперкомпьютере моей школы.

Я дошел до того, что код отлично компилируется и работает нормально, пока я не достигну строки

MPI_Gather(subscn,w*rows,MPI_BYTE,&scn,w*rows,MPI_BYTE,0,MPI_COMM_WORLD);

Мой вопрос заключается в том, в чем проблема с этой строкой, поскольку она приводит к тому, что моя программа либо segfault, либо вызывает одну из (пока что) до 5 различных ошибок утверждения в зависимости от количества процессов, с которыми я запускаю, или сцены, которую я пытаюсь отобразить. .

Рассматриваемая функция с удаленными ненужными операторами printf().

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

if (argc == 2) {
    string arg1 = argv[1];
    if (arg1 == "--help" || arg1 == "-?") print_help_message();
}

glutInit(&argc,argv);

bool OK = get_params(argc, argv);

Ray cam;
if (buildScene(scene, cam) == -1) {
    MPI_Abort(MPI_COMM_WORLD,rc);
    exit(1);
}
if (tid == MASTER) scn.initNewRGBApixmap(w,h);  /* RGBA pixel map to display */

int rows = h / numprocs;
RGBA *subscn = new RGBA[w*rows];
samples = samples > 0 ? whitted ? 1 : samples : 1;

MPI_Barrier(MPI_COMM_WORLD);            /* Synchronize all processes */
rtrace_time = 0.0 - MPI_Wtime();        /* Begin timer */

MPI_Scatter(&scn,w*rows,MPI_BYTE,subscn,w*rows,MPI_BYTE,0,MPI_COMM_WORLD);

raytrace(cam, rows, subscn);

MPI_Gather(subscn,w*rows,MPI_BYTE,&scn,w*rows,MPI_BYTE,0,MPI_COMM_WORLD);

MPI_Barrier(MPI_COMM_WORLD);            /* Synchronize all processes */
rtrace_time += MPI_Wtime();             /* End timer */

if (tid == MASTER) {
    initGlut(argc, argv);
    glutMainLoop();
}

MPI_Finalize();
return 0;
}

Функция init_MPI(argc,argv) выглядит следующим образом:

void init_MPI(int argc, char **argv) {
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&tid);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
if (numprocs < 2) {
    printf("\nError: At least two MPI tasks must be created. Exiting.\n");
    MPI_Abort(MPI_COMM_WORLD,rc);
    exit(1);
} else if (numprocs > MAX_PROCS) {
    printf("\nError: More than %d MPI tasks started. Exiting.\n",MAX_PROCS);
    MPI_Abort(MPI_COMM_WORLD,rc);
    exit(1);
}

}


person RevanProdigalKnight    schedule 07.08.2013    source источник
comment
scn — это просто пиксельная карта со значениями R, G, B, A. Извините, я забыл это прокомментировать.   -  person RevanProdigalKnight    schedule 08.08.2013
comment
scn кажется экземпляром некоторого класса. Является ли operator& переопределением, чтобы возвращать указатель на фактическую область хранения данных внутри объекта?   -  person Hristo Iliev    schedule 08.08.2013
comment
В самом деле. Кстати, спасибо, что указали на это, так как это заставило меня понять, что subscn и &scn были разными типами данных, и это решило проблему.   -  person RevanProdigalKnight    schedule 08.08.2013


Ответы (1)


Спасибо Христо Илиеву за его комментарии. Как оказалось, я использовал два разных типа данных в своем вызове MPI_Gather().

Пересмотренный код выглядит следующим образом:

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

if (argc == 2) {
    string arg1 = argv[1];
    if (arg1 == "--help" || arg1 == "-?") print_help_message();
}

glutInit(&argc,argv);

bool OK = get_params(argc, argv);

Ray cam;
if (buildScene(scene, cam) == -1) {
    MPI_Abort(MPI_COMM_WORLD,rc);
    exit(1);
}
if (pid == MASTER) scn = new RGBApixmap[w*h];

int rows = h / numprocs;
RGBApixmap *subscn = new RGBApixmap[w*rows];
samples = samples > 0 ? whitted ? 1 : samples : 1;

MPI_Barrier(MPI_COMM_WORLD);            /* Synchronize all processes */
rtrace_time = 0.0 - MPI_Wtime();        /* Begin timer */

raytrace(cam, rows, subscn);

MPI_Gather(subscn,w*rows,MPI_BYTE,scn,w*rows,MPI_BYTE,0,MPI_COMM_WORLD);

MPI_Barrier(MPI_COMM_WORLD);            /* Synchronize all processes */
rtrace_time += MPI_Wtime();             /* End timer */

if (pid == MASTER) {
    initGlut(argc, argv);
    glutMainLoop();
}

MPI_Finalize();
return 0;
}

Таким образом, урок здесь состоит в том, чтобы всегда проверять ваши типы данных и убедиться, что вы не используете разные классы в MPI Scatter and Gather.

person RevanProdigalKnight    schedule 08.08.2013