4 votes

Défaut de segmentation d'un programme MPI

J'écris un programme avec c++ qui utilise MPI. La version simplifiée de mon code est

#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;
};

Le programme se compile bien, mais donne une erreur de segmentation à l'exécution. Le message est le suivant

=================================================================================
=   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)

Lorsque je réduis le RNumber le programme fonctionne bien. Quelqu'un pourrait-il m'expliquer ce qui ne va pas ? Est-ce que j'essaie d'allouer trop d'espace à un tableau ? Si c'est le cas, le problème sera-t-il résolu en stockant les résultats dans un fichier plutôt que dans un tableau ?

Si cela est possible, pourriez-vous me donner de larges commentaires sur les choses que je fais mal.

Merci pour votre temps et vos efforts !

2voto

Mike Seymour Points 130519

Quelques problèmes possibles :

long rawT[RNumber];

C'est plutôt un grand tableau à mettre sur la pile. Il y a généralement une limite à la taille de la pile (surtout dans un programme multithread), et une taille typique est d'un ou deux mégaoctets. Vous feriez mieux d'utiliser un std::vector<long> ici.

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

Vous devez vérifier que l'allocation de mémoire a réussi. Ou mieux encore, utilisez std::vector<long> ici aussi (ce qui corrigera également votre fuite de mémoire).

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

Je suppose que le else bloc devrait faire quelque chose de différent ; en particulier, quelque chose qui n'implique pas Times puisque c'est nul, à moins que my_rank == 0 .

MISE À JOUR : pour utiliser un vecteur au lieu d'un tableau brut, il suffit de l'initialiser avec la taille souhaitée, puis d'utiliser un pointeur vers le premier élément là où vous auriez utilisé un (pointeur vers) le tableau :

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);

Attention, le pointeur sera invalidé si vous redimensionnez le vecteur (bien que vous n'ayez pas besoin de le faire si vous l'utilisez simplement pour remplacer un tableau).

1voto

Claptrap Points 21299

Vous pouvez vérifier ce qui revient de

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

par exemple comm_sz==0 causerait ce problème.

0voto

Mankarse Points 22800

Vous ne vérifiez pas la valeur de retour de malloc . Étant donné que vous essayez d'allouer plus de trois millions de longs, il est tout à fait plausible que malloc échoue.

Mais ce n'est peut-être pas la cause de votre problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X