没有mpirun运行OpenMPI程序

Jay*_*Jay 10 compilation openmpi

我正在使用gccOpenMPI.通常我使用mpirun包装器运行MPI程序- 例如,

mpirun -np 4 myprogram
Run Code Online (Sandbox Code Playgroud)

开始4个过程.

但是,我想知道是否可以轻松生成一个自动执行该操作的二进制文件(可能使用-np 4上面的一些硬编码选项).

我知道我可以编写一个调用我的程序的C包装器,如下所示:

#include <stdlib.h>
#include <unistd.h>

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

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

        return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

但这似乎有点笨拙,我最终得到两个可执行文件,而不是一个.

我试图明确地链接MPI库,比如

gcc -o myprogram -I/usr/lib/openmpi/include/ \
    -lmpi -L/usr/lib/openmpi/lib/ myprogram.c
Run Code Online (Sandbox Code Playgroud)

但是当我运行生成的可执行文件时,MPI_Comm_size将0设置为组大小(就像我-np 0作为参数一样).我可以使用环境变量或其他东西来传递组大小吗?或者,是否有另一种方法来构建单可执行MPI程序(使用Linux和gcc)?

Hri*_*iev 8

如果我正确地得到它,你想要一个自启动的MPI可执行文件.正如我在评论中所写的那样,您可以使用一个特殊选项,使您的代码mpirun在提供时执行,例如-launchmpi.使用Open MPI,它更容易,因为它将特殊环境变量导出到启动的MPI流程,例如OMPI_COMM_WORLD_RANK.如果环境中存在此变量,那么您知道程序是mpirun从而不是直接启动的.您可以在一次检查中结合使用这两种方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

如果您想控制MPI作业中的进程数,可以将其作为额外的参数提供,例如-launchmpi 12,或者在环境变量中,并使用其值而不是"4"上面的代码.

请注意,MPI可执行文件通常无法在没有的情况下启动mpirun.后者是MPI运行时的一个组成部分,它只需启动MPI可执行文件的多个副本.此外,在使用任何MPI编译器包装器(try mpicc -showme)进行编译时,您始终会显式链接到MPI库.虽然您可以静态链接MPI库(不推荐,请参见此处),但您仍然需要mpirun能够运行MPI作业 - AFAIK无法mpirun在您的程序中嵌入功能,至少不能在Open MPI中嵌入.