关于MPI通信拆分

时间:2014-12-21 17:27:05

标签: mpi

我只是想在我的项目中使用mpi_comm_split。但我发现了一些很奇怪的东西。 以下是一些示例代码:

MPI_Comm topology ;
MPI_Init( &argc,&argv ) ;
MPI_Comm_size( MPI_COMM_WORLD, &size ) ;
MPI_Comm_rank( MPI_COMM_WORLD, &rank ) ;
if ( rank == 0 )
{
    cout << "check this:\t" << rrank << endl ;
}
MPI_Comm_split( MPI_COMM_WORLD,rank > 0, rank , &topology) ;
MPI_Comm_rank( topology, &rrank) ;
MPI_Comm_size ( topology, &ssize) ;
if ( rank == 0 )
{
    cout << "check this:\t" << rrank << endl ;
}

输出似乎很奇怪:

check this: 180260968
check this: 0

我不明白的是主设备(默认通信中)不在新通信(拓扑)中。那我怎么得到rrank的两个不同的值? 希望很清楚我想要问的是什么。谢谢你的帮助。

1 个答案:

答案 0 :(得分:3)

正如高性能标记所注意到的那样,rrank在调用MPI_Comm_split()之前的值是没有意义的,因为它没有被初始化。因此,该程序的输出并不奇怪:在调用MPI_Comm_split()之前,rrank可以取任何值,之后,它是新通信器topology

中的进程的等级

事实上,您提供的代码似乎完全符合您的预期。 这是一个测试代码:由mpiCC main.cpp -o main编译并由mpirun -np 4 main

运行
    #include <iostream>
#include <cstdio>
#include "mpi.h"

using namespace std;

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

    int rank,rrank,size,ssize;
    char message[1000];

    MPI_Comm topology ;
    MPI_Init( &argc,&argv ) ;
    MPI_Comm_size( MPI_COMM_WORLD, &size ) ;
    MPI_Comm_rank( MPI_COMM_WORLD, &rank ) ;

    //splitting : creating two new communicators, one with rank=0, second with rank>0
    MPI_Comm_split( MPI_COMM_WORLD,rank > 0, rank , &topology) ;

    //getting rank of current process in new communicator topology
    MPI_Comm_rank( topology, &rrank) ;
    MPI_Comm_size ( topology, &ssize) ;

    sprintf(message,"after, splited rrank : %d global rank %d\n",rrank,rank);
    cout << message; 

    if(rank==0){
        //small task on process rank=0
        cout<<"rank 0, doing nothing, not expecting any message\n";
    }else{

        int b=rrank*rrank+42;
        //MPI_Bcast() over processes concerned by the big task, using communicator topology
        MPI_Bcast( &b, 1, MPI_INT, 0,topology);

        sprintf(message,"after bcast, on rank %d having %d\n",rank,b);
        cout << message; 
    }
    MPI_Finalize();

}

输出

after, splited rrank : 0 global rank 0
after, splited rrank : 0 global rank 1
after, splited rrank : 1 global rank 2
after, splited rrank : 2 global rank 3

有两个名为topology的新传播者。一个只有进程rank=0(这是他自己的主人),另一个进程有进程rank=1,2,3。在这个新的沟通者中,rank=1rrank=0rank=2rrank=1rank=3rrank=2

这些过程分为两组,一组(排名= 0)和一组(排名> 0),准备执行任务。只需使用通信器topology和新排名rrank即可执行这些任务。类似的东西:

if(rank>0){
     ...<big task here, using topology and rrank>...
}else{
     ...<small task here, on rank=0>...
}

代码由MPI_Bcast()关于大任务相关进程的示例完成。 rank = 0被排除在此传播者之外。