Ошибка сегментации программы MPI - PullRequest
4 голосов
/ 08 ноября 2011

Я пишу программу на C ++, которая использует MPI.Упрощенная версия моего кода:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <mpi.h>
#define RNumber 3000000 //Number of loops to go

using namespace std;

class LObject {
        /*Something here*/
    public:
        void FillArray(long * RawT){
            /*Does something*/
            for (int i = 0; i < RNumber; i++){
                RawT[i] = i;
            }
        }
};

int main() {
    int     my_rank;
    int     comm_sz;
    MPI_Init(NULL, NULL);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);

    LObject System;

    long rawT[RNumber];
    long * Times = NULL;
    if (my_rank == 0) Times = (long*) malloc(comm_sz*RNumber*sizeof(long));

    System.FillArray(rawT);

    if (my_rank == 0) {
        MPI_Gather(rawT, RNumber, MPI_LONG, Times, RNumber,
                MPI_LONG, 0, MPI_COMM_WORLD);
    }
    else {
        MPI_Gather(rawT, RNumber, MPI_LONG, Times, RNumber,
                MPI_LONG, 0, MPI_COMM_WORLD);
    }

    MPI_Finalize();
    return 0;
};

Программа прекрасно компилируется, но выдает ошибку ошибки сегментации при выполнении.Сообщение

=================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   EXIT CODE: 11
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
=================================================================================
APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)

Когда я уменьшаю RNumber, программа работает нормально.Может, кто-нибудь может объяснить, что именно идет не так?Я пытаюсь выделить слишком много места для массива?Если это так, решится ли эта проблема путем сохранения результатов в файле, а не в массиве?

Если это возможно, не могли бы вы дать широкие комментарии о том, что я делаю неправильно.

Спасибо за ваше время и усилия!

Ответы [ 3 ]

2 голосов
/ 08 ноября 2011

Пара возможных проблем:

long rawT[RNumber];

Это довольно большой массив для размещения в стеке. Размер стека обычно ограничен (особенно в многопоточной программе), а типичный размер составляет один или два мегабайта. Вам было бы лучше с std::vector<long> здесь.

Times = (long*) malloc(comm_sz*RNumber*sizeof(long));

Вы должны убедиться, что выделение памяти прошло успешно. Или, что еще лучше, используйте здесь std::vector<long> (что также исправит утечку памяти).

if (my_rank == 0) {
    // do stuff
} else {
    // do exactly the same stuff
}

Я предполагаю, что блок else должен делать что-то другое; в частности, то, что не включает Times, так как это ноль, если my_rank == 0.

ОБНОВЛЕНИЕ: чтобы использовать вектор вместо необработанного массива, просто инициализируйте его с нужным вам размером, а затем используйте указатель на первый элемент, где вы будете использовать (указатель на) массив:

std::vector<long> rawT(RNumber);
System.FillArray(&rawT[0]);

std::vector<long> Times(comm_sz*RNumber);
MPI_Gather(&rawT[0], RNumber, MPI_LONG, &Times[0], RNumber,
           MPI_LONG, 0, MPI_COMM_WORLD);

Остерегайтесь того, что указатель станет недействительным, если вы измените размер вектора (хотя вам не нужно этого делать, если вы просто используете его в качестве замены для массива).

1 голос
/ 08 ноября 2011

Вы можете проверить, что возвращается с

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);

например. comm_sz==0 может вызвать эту проблему.

0 голосов
/ 08 ноября 2011

Вы не проверяете возвращаемое значение из malloc. Учитывая, что вы пытаетесь выделить более трех миллионов long, вполне вероятно, что malloc потерпит неудачу.

Хотя это может и не быть причиной вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...