OpenMPI-programma uitvoeren zonder mpirun

Ik gebruik gcc en OpenMPI . Meestal voer ik MPI-programma's uit met de mpirun -wrapper - bijvoorbeeld

mpirun -np 4 myprogram

om 4 processen te starten.

Ik vroeg me echter af of het mogelijk is om eenvoudig een binary te genereren die dat automatisch doet (misschien met sommige hardcoded opties zoals -np 4 hierboven).

Ik weet dat ik een C-wrapper kan schrijven die mijn programma oproept, zoals het volgende:

#include 
#include 

int main() {
        char *options[] = { "mpirun", "-np", "4", "myprogram" };

        execvp("mpirun", options);
        /* Ignoring return value to keep example simple */

        return EXIT_SUCCESS;
}

maar dit lijkt een beetje onhandig en ik eindig met twee uitvoerbare bestanden in plaats van één.

Ik heb geprobeerd om de MPI-bibliotheken expliciet te koppelen, zoals

gcc -o myprogram -I/usr/lib/openmpi/include/ \
    -lmpi -L/usr/lib/openmpi/lib/ myprogram.c

maar wanneer ik het resulterende uitvoerbare bestand uitvoer, stelt MPI_Comm_size nul in als de groepsgrootte (alsof ik -np 0 als argument had gegeven). Kan ik een omgevingsvariabele of iets anders gebruiken om de groepsgrootte door te geven? Of is er een andere manier om een ​​enkelvoudig uitvoerbaar MPI-programma te bouwen (met Linux en gcc )?

8
Seel ook this SO question.
toegevoegd de auteur Richard, de bron
Begrijp ik het goed - u wilt mpirun overslaan of wilt u op de een of andere manier automatisch mpirun aanroepen?
toegevoegd de auteur Hristo Iliev, de bron
Nou, je kunt het niet krijgen zonder mpirun . Het is niet alleen een launcher, maar ook een onderdeel van de MPI-runtime die fungeert als centrale coördinator voor elke MPI-taak, vooral in het geval van Open MPI ( mpirun is eigenlijk een symlink naar de van OMPI orterun ). Maar u kunt uw code laten controleren op een speciale optie, bijvoorbeeld -launchmpi en voer het uit mpirun -np argv [0] als het is ingesteld.
toegevoegd de auteur Hristo Iliev, de bron
@Hristo Iliev: Het zou leuk zijn als ik een enkel statisch binair bestand zou hebben.
toegevoegd de auteur Jay, de bron
Het kan worden gedaan, hoewel ik niet weet hoe ik het uit mijn hoofd heb. Ik ken een paar programma's die ik ben tegengekomen die dit doen. Er zit geen echte magie in, het doet gewoon een hoop dingen achter de schermen die je ook zelf kunt doen.
toegevoegd de auteur Kenneth Hoste, de bron

2 antwoord

Als ik het goed begrijp, wil je een zelfstartend MPI-bestand. Zoals ik in mijn opmerking heb geschreven, kunt u kiezen voor een speciale optie waarmee uw code mpirun wordt uitgevoerd, indien geleverd, bijvoorbeeld -launchmpi . Met Open MPI is het nog eenvoudiger omdat het speciale omgevingsvariabelen exporteert naar MPI-processen, bijvoorbeeld OMPI_COMM_WORLD_RANK . Als deze variabele in de omgeving bestaat, weet u dat het programma is gestart vanuit mpirun en niet rechtstreeks. U kunt beide methoden combineren door dit te controleren:

int main (int argc, char **argv)
{
    int perform_launch = 0;
   //Scan argv[] for special option like "-launchmpi"
   //and set perform_launch if found 

    if (perform_launch || getenv("OMPI_COMM_WORLD_RANK") == NULL)
    {
       //#args = argc + 3 ("mpirun -np 4" added) + NULL
       //#args should be reduced by one if "-launchmpi" is present
        char **args = (char **)calloc(
           argc + (perform_launch ? 3 : 4),
           sizeof(char *));
        args[0] = "mpirun";
        args[1] = "-np";
        args[2] = "4";
       //Copy the entire argv to the rest of args but skip "-launchmpi"

        execvp("mpirun", args);

        return EXIT_SUCCESS;
    }

   //Proceed as regular MPI code
    MPI_Init(&argc, &argv);
    ...
   //Magic happens here
    ...
    MPI_Finalize();

    return EXIT_SUCCESS;
}

Als u het aantal processen in de MPI-taak wilt beheren, kunt u dit als een extra arugment opgeven, bijvoorbeeld -launchmpi 12 , of in een omgevingsvariabele en gebruik de waarde in plaats van "4" in de bovenstaande code.

Merk op dat MPI-uitvoerbare bestanden niet over het algemeen kunnen worden gestart zonder mpirun . De laatste is een integraal onderdeel van de MPI-runtime en het doet veel meer dan alleen het starten van meerdere exemplaren van het MPI-bestand. Ook koppel je altijd expliciet naar de MPI-bibliotheek bij het compileren met een van de MPI-compiler-wrappers (probeer mpicc -showme ). Hoewel u MPI-bibliotheken statisch kunt koppelen (niet aanbevolen, zie hier ), hebt u nog steeds mpirun nodig om MPI-taken te kunnen uitvoeren - AFAIK er is geen manier om de functie mpirun in uw programma in te bedden, bij minst niet in Open MPI.

6
toegevoegd
Bedankt voor je reactie - dat is echt handig!
toegevoegd de auteur Jay, de bron

Je kunt dit doen met een bash-script:

# If you change this script has executable (chmod +x script_name)
# and if you have the current path in the PATH variable (add export PATH=.:$PATH in your .bashrc)
#Then, you can run this has: script_name program_args

mpirun -np 4 your_executable_name "[email protected]"
1
toegevoegd
Bedankt @ ChrisDown Ik heb mijn antwoord gecorrigeerd.
toegevoegd de auteur RSFalcon7, de bron
Ik ben vandaag een beetje slaperig xD
toegevoegd de auteur RSFalcon7, de bron
Je wilt bijna zeker "$ @" , niet $ * , anders mangle args over wordsplitting.
toegevoegd de auteur Chris Down, de bron
Je argumenten zullen nog steeds worden verminkt. De citaten zijn belangrijk.
toegevoegd de auteur Chris Down, de bron