【问题标题】:Openmpi mpmd get communication sizeOpenmpi mpmd 获取通信大小
【发布时间】:2016-06-25 18:06:00
【问题描述】:

我有两个 openmpi 程序,我是这样开始的

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

现在我如何使用MPI_Comm_size(MPI_COMM_WORLD, &size) 以便获得大小值

prog1 size=4
prog2 size=2.

到目前为止,我在两个程序中都得到“6”。

【问题讨论】:

    标签: c++ c parallel-processing mpi openmpi


    【解决方案1】:

    这是可行的,尽管获得它有点麻烦。其原理是根据argv[0]的值将MPI_COMM_WORLD拆分为通信器,其中包含可执行文件的名称。

    可能是这样的:

    #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,用于在同一共享内存计算节点上运行的进程之间进行排序......太糟糕了!下一版本的标准可能需要考虑什么?

    【讨论】:

      【解决方案2】:

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

      您可以使用 MPI 参数 MPI_APPNUM 的值作为“颜色”,每个可执行文件都不同,并将 MPI_COMM_WORLD 拆分为单独的通信器,然后打印这些子通信器的大小。使用 MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_APPNUM, &val, &flag);获取 MPI_APPNUM 的值。

      【讨论】:

        【解决方案3】:

        由于您使用的是 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 通信器。

        【讨论】:

          猜你喜欢
          • 2017-05-12
          • 2013-05-21
          • 1970-01-01
          • 2015-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-28
          • 1970-01-01
          相关资源
          最近更新 更多