Paralleles Programmieren: Exception sinnvoll abfangen?



  • Hallo,

    ich weiß nicht wohin ich posten kann hier. Evtl. muss ich verschoben werden.

    Ich programmiere seit kurzem Parallel auf einem Cluster mit OpenMPI.
    Mir ist dabei etwas einfaches aber grundlegendes nicht ganz klar.

    Wenn ich eine exceptions (C++) über throw auslöse und diese z.B. in die main hochreiche, diese exceptions aber nur auf einem Prozess ausgelöst wurde - wie kann ich dann sicherstellen dass der Error-string nur ein einziges mal auf die shell geworfen wird. mir ist klar dass wenn jeder prozess z.B. gleichen input bekommt dann gleich prüft kann man das so machen:

    try {
     foo(); // hier drin wird eine exceptions geworfen
    } catch(std::runtime_error & ex)
    {
        if(my_id == 0)
       {
              //Irgendeine ausgabe die nur von Prozess mit ID 0 ausgegeben wird
              std::cerr << ex.what() << std::endl;
        }
        MPI_Abort(...);
    }
    

    Wenn allerdings irgendwo mitten im algorithmus bzw. auf daten die jeder prozess lokal hält nur auf z.B. prozess mit ID 4 etwas passiert. muss dieser auch ein throw machen aber dann wird in dieser obigen Excpetion nicht der error-string ausgegeben und doch das programm beendet.

    Wie erreiche ich denn eine ausgabe die nur einmal aber dann auch vom korrekten prozess ausgegeben wird?


  • Mod

    Also du willst:
    Exception wird von mehreren Prozessen geworfen -> nur eine anonyme Ausgabe
    Exception wird von einem Prozess geworfen -> Ausgabe mit Prozessnummer

    Ich würde das so machen: Einen weiteren Logprozess laufen lassen (der praktisch nichts macht, er kann also auf dem gleichen Node wie eine anderer Prozess laufen), der die ganze Zeit auf Nachrichten wartet. Im Falle einer Exception wird vom Prozess mit dem Fehler eine Meldung an den Logprozess geschickt. Dieser führt dann die nötige Entscheidung durch und gibt die passende Meldung aus.



  • Hallo SeppJ. Ja danke - Die idee ist nicht schlecht.

    Mein Problem: Ich arbeite an numerischem Code wo jeder Prozess wichtig ist und effizienz (Laufzeit) sehr maßgeblich ist. Zusätzliche Prozesse als error-handler würde ich gern vermeiden.

    Gäbe es eine Alternative?

    Meine einzige Idee bis jetzt: Ich weiß noch nicht ob es in C++ möglich ist aber evtl. über throw noch die ID des prozesses nach oben an die main durchreichen und dann dort einfach prüfen auf: if (my_id == ex.my_di) ....
    falls es möglich ist...



  • Wurzelkraut schrieb:

    Meine einzige Idee bis jetzt: Ich weiß noch nicht ob es in C++ möglich ist aber evtl. über throw noch die ID des prozesses nach oben an die main durchreichen und dann dort einfach prüfen auf: if (my_id == ex.my_di) ....
    falls es möglich ist...

    Du kannst doch alles werfen was du willst. Einen string. Oder aber eine eigene Exception die eben einen solchen zusätzlichen Member hat, der die Prozess-Id hält.


  • Mod

    Wurzelkraut schrieb:

    Mein Problem: Ich arbeite an numerischem Code wo jeder Prozess wichtig ist und effizienz (Laufzeit) sehr maßgeblich ist. Zusätzliche Prozesse als error-handler würde ich gern vermeiden.

    Da ich ja mal annehme, dass Exceptions eher die Ausnahme sind, sollte der Prozess eigentlich fast keine Last verursachen. Aber gut:

    Gäbe es eine Alternative?

    Du könntest natürlich eine komplexere Fehlerausgabe schreiben, die vor der Ausgabe in der Logdatei nachguckt, was da schon so drinsteht und entsprechend reagiert. Das dürfte ganz gut funktionieren.

    Meine einzige Idee bis jetzt: Ich weiß noch nicht ob es in C++ möglich ist aber evtl. über throw noch die ID des prozesses nach oben an die main durchreichen und dann dort einfach prüfen auf: if (my_id == ex.my_di) ....
    falls es möglich ist...

    Klar ist das möglich, aber wenn du mal darüber nachdenkst wirst du feststellen, dass (my_id == ex.my_di) ist immer true ist. Die main-Funktion gehört bei MPI schließlich zum gleichen Prozess wie der Rest des Programms.


Anmelden zum Antworten