我只是想在我的项目中使用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
的两个不同的值?
希望很清楚我想要问的是什么。谢谢你的帮助。
答案 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=1
有rrank=0
,rank=2
有rrank=1
,rank=3
有rrank=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被排除在此传播者之外。