关于MPI通信拆分

关于MPI通信拆分,mpi,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

我只是想在我的项目中使用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 ;
}
我不明白的是,主节点(默认通信)不在新的通信(拓扑)中。那么为什么我会得到两个不同的
rrank

希望我想问的问题很清楚。感谢您的帮助。

正如High Performance Mark所注意到的,调用
MPI\u Comm\u split()
之前的
rrank
值没有意义,因为它没有初始化。因此,该程序的输出并不奇怪:在调用
MPI\u Comm\u split()
之前,
rrank
可以接受任何值,之后是新通信器
拓扑中进程的等级

事实上,您提供的代码似乎完全符合您的期望。 下面是一个测试代码:通过
mpiCC main.cpp-o main编译,并通过
mpirun-np4 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();

}
有两个新的通讯器名为
拓扑
。一个只有进程
rank=0
(这是他自己的主进程),另一个进程
rank=1,2,3
。在这种新型通信器中,
rank=1
具有
rrank=0
rank=2
具有
rrank=1
rank=3
具有
rrank=2

流程分为两个组,一个小组(秩=0)和一个大组(秩>0),准备执行任务。只需使用通信器
拓扑
和新列组
rrank
即可执行这些任务。比如:

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

代码是通过一个例子来完成的,
MPI\u Bcast()
覆盖了与大任务相关的进程。rank=0被排除在此通信器之外。

正如High Performance Mark所注意到的,调用
MPI\u Comm\u split()
之前的
rrank
值没有意义,因为它没有初始化。因此,该程序的输出并不奇怪:在调用
MPI\u Comm\u split()
之前,
rrank
可以接受任何值,之后是新通信器
拓扑中进程的等级

事实上,您提供的代码似乎完全符合您的期望。 下面是一个测试代码:通过
mpiCC main.cpp-o main编译,并通过
mpirun-np4 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();

}
有两个新的通讯器名为
拓扑
。一个只有进程
rank=0
(这是他自己的主进程),另一个进程
rank=1,2,3
。在这种新型通信器中,
rank=1
具有
rrank=0
rank=2
具有
rrank=1
rank=3
具有
rrank=2

流程分为两个组,一个小组(秩=0)和一个大组(秩>0),准备执行任务。只需使用通信器
拓扑
和新列组
rrank
即可执行这些任务。比如:

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

代码是通过一个例子来完成的,
MPI\u Bcast()
覆盖了与大任务相关的进程。rank=0被排除在此通信器之外。

正如High Performance Mark所注意到的,调用
MPI\u Comm\u split()
之前的
rrank
值没有意义,因为它没有初始化。因此,该程序的输出并不奇怪:在调用
MPI\u Comm\u split()
之前,
rrank
可以接受任何值,之后是新通信器
拓扑中进程的等级

事实上,您提供的代码似乎完全符合您的期望。 下面是一个测试代码:通过
mpiCC main.cpp-o main编译,并通过
mpirun-np4 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();

}
有两个新的通讯器名为
拓扑
。一个只有进程
rank=0
(这是他自己的主进程),另一个进程
rank=1,2,3
。在这种新型通信器中,
rank=1
具有
rrank=0
rank=2
具有
rrank=1
rank=3
具有
rrank=2

流程分为两个组,一个小组(秩=0)和一个大组(秩>0),准备执行任务。只需使用通信器
拓扑
和新列组
rrank
即可执行这些任务。比如:

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

代码是通过一个例子来完成的,
MPI\u Bcast()
覆盖了与大任务相关的进程。rank=0被排除在此通信器之外。

正如High Performance Mark所注意到的,调用
MPI\u Comm\u split()
之前的
rrank
值没有意义,因为它没有初始化。因此,该程序的输出并不奇怪:在调用
MPI\u Comm\u split()
之前,
rrank
可以接受任何值,之后是新通信器
拓扑中进程的等级

事实上,您提供的代码似乎完全符合您的期望。 下面是一个测试代码:通过
mpiCC main.cpp-o main编译,并通过
mpirun-np4 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();

}
有两个新的通讯器名为
拓扑
。一个只有进程
rank=0
(这是他自己的主进程),另一个进程
rank=1,2,3
。在这种新型通信器中,
rank=1
具有
rrank=0
rank=2
具有
rrank=1
rank=3
具有
rrank=2

流程分为两个组,一个小组(秩=0)和一个大组(秩>0),准备执行任务。只需使用通信器
拓扑
和新列组
rrank
即可执行这些任务。比如:

if(rank>0){
     ...<big task here, using topology and rrank>...
}else{
     ...<small task here, on rank=0>...
}
if(秩>0){
......
}否则{
......
}
代码通过进程con上的
MPI\u Bcast()
示例完成