11

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

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)?

4

2 回答 2

11

如果我理解正确,您需要一个自启动的 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"在上述代码中。

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

于 2012-06-25T08:15:43.870 回答
2

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

# 如果你改变这个脚本有可执行文件(chmod +x script_name)
# 如果你在 PATH 变量中有当前路径(在你的 .bashrc 中添加 export PATH=.:$PATH)
#然后,你可以运行这个有:script_name program_args

mpirun -np 4 your_executable_name "$@"
于 2012-06-24T19:06:42.900 回答