没有mpirun运行OpenMPI程序

时间:2012-06-24 10:21:47

标签: compilation openmpi

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

mpirun -np 4 myprogram

启动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;
}

但这看起来有点笨拙,我最终得到了两个可执行文件而不是一个。

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

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

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

2 个答案:

答案 0 :(得分:7)

如果我能正确理解,你需要一个自启动的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;
}

如果您想控制MPI作业中的处理数量,您可以将其作为额外的控制提供,例如: -launchmpi 12,或在环境变量中使用其值代替上述代码中的"4"

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

答案 1 :(得分:1)

您可以使用bash脚本执行此操作:

# 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 "$@"