C++ MPI虚拟拓扑设计
我一直在尝试使用MPI_Comm_split创建星形拓扑,但当我尝试与所有进程建立链接时,我似乎遇到了问题。所有流程都将链接到MPI_COMM_WORLD的p0。问题是我在排队时撞车了C++ MPI虚拟拓扑设计,c++,parallel-processing,mpi,topology,C++,Parallel Processing,Mpi,Topology,我一直在尝试使用MPI_Comm_split创建星形拓扑,但当我尝试与所有进程建立链接时,我似乎遇到了问题。所有流程都将链接到MPI_COMM_WORLD的p0。问题是我在排队时撞车了 error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM ); 错误是:MPI\u ERR\u COMM:invalid communicator 虽然我不知道如何修复它,但我已经知道了原因和想
error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM );
错误是:MPI\u ERR\u COMM:invalid communicator
虽然我不知道如何修复它,但我已经知道了原因和想法。这似乎是由于进程zero调用的,它不属于新的通信器(new_COMM)。我曾试图在process=0时放置一个if语句来停止这一行的执行,但由于它是一个集体调用,所以再次失败
如有任何建议,将不胜感激
#include <iostream>
#include "mpi.h"
using namespace std;
int main(){
MPI_Comm NEW_COMM , INTERCOMM;
MPI_Init(NULL,NULL);
int world_rank , world_size,new_size, error;
error = MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
error = MPI_Comm_size(MPI_COMM_WORLD,&world_size);
int color = MPI_UNDEFINED;
if ( world_rank > 0 )
color = world_rank ;
error = MPI_Comm_split(MPI_COMM_WORLD, color , world_rank, &NEW_COMM);
int new_rank;
if ( world_rank > 0 ) {
error = MPI_Comm_rank( NEW_COMM , &new_rank);
error = MPI_Comm_size(NEW_COMM, &new_size);
}
int create_tag = 99;
error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM );
if ( world_rank > 0 )
cout<<" My Rank in WORLD = "<< world_rank <<" New rank = "<<new_rank << " size of NEWCOMM = "<<new_size <<endl;
else
cout<<" Am centre "<<endl;
MPI_Finalize();
return 0;
}
#包括
#包括“mpi.h”
使用名称空间std;
int main(){
MPI_通信新通信、内部通信;
MPI_Init(NULL,NULL);
int世界排名、世界大小、新大小、错误;
错误=MPI通信等级(MPI通信等级世界和世界等级);
错误=MPI\U Comm\U大小(MPI\U Comm\U世界和世界大小);
int color=MPI_未定义;
如果(世界排名>0)
颜色=世界排名;
错误=MPI通信分割(MPI通信世界、颜色、世界排名和新通信);
int新职等;
如果(世界排名>0){
错误=MPI通信等级(新通信和新等级);
错误=MPI\U通信大小(新通信和新通信大小);
}
int create_tag=99;
错误=MPI\U内部通信创建(MPI\U通信世界,0,新通信,0,创建标记和内部通信);
如果(世界排名>0)
cout不如使用MPI拓扑呢?类似这样:
#include <mpi.h>
#include <iostream>
int main( int argc, char *argv[] ) {
MPI_Init( &argc, &argv );
int rank, size;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
int indegree, outdegree, *sources, *sourceweights, *destinations, *destweights;
if ( rank == 0 ) { //centre of the star
indegree = outdegree = size - 1;
sources = new int[size - 1];
sourceweights = new int[size - 1];
destinations = new int[size - 1];
destweights = new int[size - 1];
for ( int i = 0; i < size - 1; i++ ) {
sources[i] = destinations[i] = i + 1;
sourceweights[i] = destweights[i] = 1;
}
}
else { // tips of the star
indegree = outdegree = 1;
sources = new int[1];
sourceweights = new int[1];
destinations = new int[1];
destweights = new int[1];
sources[0] = destinations[0] = 0;
sourceweights[0] = destweights[0] = 1;
}
MPI_Comm star;
MPI_Dist_graph_create_adjacent( MPI_COMM_WORLD, indegree, sources, sourceweights,
outdegree, destinations, destweights, MPI_INFO_NULL,
true, &star );
delete[] sources;
delete[] sourceweights;
delete[] destinations;
delete[] destweights;
int starrank;
MPI_Comm_rank( star, &starrank );
std::cout << "Process #" << rank << " of MPI_COMM_WORLD is process #" << starrank << " of the star\n";
MPI_Comm_free( &star);
MPI_Finalize();
return 0;
}
#包括
#包括
int main(int argc,char*argv[]){
MPI_Init(&argc,&argv);
int等级、大小;
MPI通信等级(MPI通信世界和等级);
MPI_通信大小(MPI_通信世界和大小);
int indegree、outdegree、*源、*源权重、*目的地、*目的地权重;
如果(秩==0){//星的中心
indegree=outdegree=大小-1;
sources=新整数[size-1];
sourceweights=newint[size-1];
目的地=新整数[size-1];
destweights=新整数[大小-1];
对于(int i=0;i std::我可能错了,但我相信MPI\u Intercomm\u create
接受两个内部通讯器作为输入。按原样,你给它MPI\u COMM\u WORLD和NEW\u COMM;一个通讯器是另一个的子集。我相信你应该创建第二个通讯器,它只是WORLD\u rank==0
进程:ROOT\u COMM
正在调用MPI\U内部通信创建(根通信,0,新通信,0,创建标记和内部通信)
可能会按预期工作。是的,谢谢。这看起来像是我正在寻找的拓扑类型,因为我只需要一个中心进程来分发信息。您的解决方案非常简洁。不过,我正在考虑一种更明确的方法,即将进程添加到自己的通信器中,然后告诉它根/中心进程是谁。我之所以考虑这个问题,是因为我想巩固我在将来创建任何其他拓扑的技能。