openmpi mpmd 获取通信大小

Openmpi mpmd get communication size

我有两个 openmpi 程序,我是这样启动的

mpirun -n 4 ./prog1 : -n 2 ./prog2

现在我该如何使用 MPI_Comm_size(MPI_COMM_WORLD, &size) 才能得到尺寸值

prog1 size=4
prog2 size=2.

截至目前,我在两个项目中都获得了“6”分。

这是可行的,尽管实现起来有点麻烦。原理是根据 argv[0] 的值将 MPI_COMM_WORLD 拆分为 communicators,其中包含可执行文件的名称。

可能是这样的:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mpi.h>

int main( int argc, char *argv[] ) {

    MPI_Init( &argc, &argv );

    int wRank, wSize;
    MPI_Comm_rank( MPI_COMM_WORLD, &wRank );
    MPI_Comm_size( MPI_COMM_WORLD, &wSize );

    int myLen = strlen( argv[0] ) + 1;
    int maxLen;
    // Gathering the maximum length of the executable' name
    MPI_Allreduce( &myLen, &maxLen, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD );

    // Allocating memory for all of them
    char *names = malloc( wSize * maxLen );
    // and copying my name at its place in the array
    strcpy( names + ( wRank * maxLen ), argv[0] );

    // Now collecting all executable' names
    MPI_Allgather( MPI_IN_PLACE, 0, MPI_DATATYPE_NULL,
                   names, maxLen, MPI_CHAR, MPI_COMM_WORLD );

    // With that, I can sort-out who is executing the same binary as me
    int binIdx = 0;
    while( strcmp( argv[0], names + binIdx * maxLen ) != 0 ) {
        binIdx++;
    }
    free( names );

    // Now, all processes with the same binIdx value are running the same binary
    // I can split MPI_COMM_WORLD accordingly
    MPI_Comm binComm;
    MPI_Comm_split( MPI_COMM_WORLD, binIdx, wRank, &binComm );

    int bRank, bSize;
    MPI_Comm_rank( binComm, &bRank );
    MPI_Comm_size( binComm, &bSize );

    printf( "Hello from process WORLD %d/%d running %d/%d %s binary\n",
            wRank, wSize, bRank, bSize, argv[0] );

    MPI_Comm_free( &binComm );

    MPI_Finalize();

    return 0;
}

在我的机器上,我编译运行它如下:

~> mpicc mpmd.c
~> cp a.out b.out
~> mpirun -n 3 ./a.out : -n 2 ./b.out
Hello from process WORLD 0/5 running 0/3 ./a.out binary
Hello from process WORLD 1/5 running 1/3 ./a.out binary
Hello from process WORLD 4/5 running 1/2 ./b.out binary
Hello from process WORLD 2/5 running 2/3 ./a.out binary
Hello from process WORLD 3/5 running 0/2 ./b.out binary

理想情况下,如果存在用于按二进制分类的相应类型,则可以使用 MPI_Comm_split_type() 大大简化此操作。不幸的是,3.1 MPI 标准中没有这样的 MPI_COMM_TYPE_ 预定义。唯一的预定义是 MPI_COMM_TYPE_SHARED,用于在同一共享内存计算节点上的进程 运行 之间进行排序……太糟糕了!也许下一版标准需要考虑什么?

由于您使用的是 Open MPI,因此有一个非常简单的 OMPI 特定解决方案:

#include <stdlib.h>

MPI_Comm appcomm;
int app_id = atoi(getenv("OMPI_MCA_orte_app_num"));
MPI_Comm_split(MPI_COMM_WORLD, app_id, 0, &appcomm);

现在将有与应用程序上下文一样多的不同 appcomm 通信器。

我知道这个问题已经过时了,但我想补充一下 Hristo Lliev 的回答,让它不仅适用于 OpenMPI:

您可以使用 MPI 参数 MPI_APPNUM 的值,它对于每个可执行文件都是不同的 "color" 并将 MPI_COMM_WORLD 拆分为单独的通信器,然后打印它们的大小子传播者。使用 MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_APPNUM, &val, &flag );获取 MPI_APPNUM 的值。