Problem mit Open-MPI



  • Hallo an alle
    Das ist evtl. ein etwas ausführliches Problem, aber es treten bei mir nur sporadisch Fehler auf, die ich mir nicht erklären kann.

    Die Problemstellung ist: Die Funktion MPI_Bcast() soll nur mit Hilfe der Funktionen MPI_Send() und MPI_Recv() realisiert werden. Dabei soll das nur logarithmische Laufzeit haben, also der Wurzelprozess soll die Sendearbeit aufteilen. Ich habe das in dem Sinne gemacht, dass der Wurzelprozess (der Einfachkeit halber bei mir immer 0) an Prozess 1 schickt. Danach schickt Prozess 0 an Prozess 2 und Prozess 1 an Prozess 3 usw. Prozess 0 schickt also an Prozess 1, 2, 4, 8... Prozess 1 schickt an 3, 5, 9 ... Prozess 2 schickt an 6, 10...
    Hier ist der Code:

    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <math.h>
    #include <string.h>
    #include "mpi.h"
    
    //At compiling: add -lm at the end for log2() to work
    int MPI_MyBcast(void * message, int count, MPI_Datatype type, int root, MPI_Comm comm) {
        int my_rank, new_rank, p, tag = 0;
        MPI_Status status;
    
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &p);
    
        int exponent = 0;
        int sender = 0;
    
        if (my_rank != root) {
            exponent = (int) log2((double) my_rank) + 1;
            sender = my_rank - pow(2, (double) (exponent - 1));
        }
    
        if (my_rank != root) {
            //printf("Process %i: Waiting for message from %i\n", my_rank, sender);
            MPI_Recv(message, count, type, sender, 1, comm, &status);
    
            int k;
            int receiver = my_rank + (int) pow(2, exponent);
            for (k = receiver; k < p; k += (int) pow(2, exponent++)) {
                //printf("Process %i: Sending message to %i\n", my_rank, k);
                MPI_Send(message, strlen(message)+1, type, k, 1, comm);
            }
        }
        else {
            int k;
            int receiver = my_rank + (int) pow(2, exponent);
            for (k = receiver; k < p; k += (int) pow(2, exponent++)) {
                //printf("Process %i: Sending message to %i\n", my_rank, k);
                MPI_Send(message, strlen(message)+1, type, k, 1, comm);
            }
        }
    
        return 0;
    }
    
    int main (int argc, char * argv[]) {
        const int root = 0;    //atoi(argv[1]);
    
        int my_rank, p;
        char msg[6];
    
    	MPI_Init(&argc, &argv);
    	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    	MPI_Comm_size(MPI_COMM_WORLD, &p);
    
        if (my_rank == 0) {
            strcpy(msg, "Hello");
        }
    
    	MPI_MyBcast(msg, strlen(msg)+1, MPI_CHAR, root, MPI_COMM_WORLD);
    
        printf("Process %i: Got message: %s\n", my_rank, msg);
    
    	MPI_Finalize ();
    
    	return 0;
    }
    

    Jetzt tritt ab und zu die Fehlermeldung auf (Kompiliert wurde es mit mpicc dateiname.c -lm, und aufgerufen mit mpirun -np 4 a.out wobei ich es auch mit einer unterschiedlichen Anzahl an Prozessen ausprobiert habe)

    [xyz-desktop:3800] *** An error occurred in MPI_Recv
    [txyz-desktop:3800] *** on communicator MPI_COMM_WORLD
    [xyz-desktop:3800] *** MPI_ERR_TRUNCATE: message truncated
    [xyz-desktop:3800] *** MPI_ERRORS_ARE_FATAL: your MPI job will now abort

    mpirun has exited due to process rank 3 with PID 3800 on
    node xyz-desktop exiting improperly. There are two reasons this could occur:

    mpirun has exited due to process rank 3 with PID 3800 on
    node xyz-desktop exiting improperly. There are two reasons this could occur:

    1. this process did not call "init" before exiting, but others in
    the job did. This can cause a job to hang indefinitely while it waits
    for all processes to call "init". By rule, if one process calls "init",
    then ALL processes must call "init" prior to termination.

    2. this process called "init", but exited without calling "finalize".
    By rule, all processes that call "init" MUST call "finalize" prior to
    exiting or it will be considered an "abnormal termination"

    This may have caused other processes in the application to be
    terminated by signals sent by mpirun (as reported here).

    Ich habe zum einen herausgefunden, dass es öfters die Fehlermeldung gibt wenn ich zB char msg[20]; statt msg[6]; nehme, was mir nicht wirklich klar ist. Ich denke es muss irgendwie damit zusammenhängen, weil wenn ich einfach char msg[0] nehme und nichts darin kopiere scheint es immer zu funktionieren.



  • Zähl ma deine sends und recives mit selben tag. Ausserdem solltest du nicht einmal 'count' und einmal 'strlen()' als Buffergröße verwenden! Warum überhaupt strlen innerhalb der Bcast-funktion?


Anmelden zum Antworten