我一直在尝试使用MPI_Comm_split创建星形拓扑,但是当我尝试与所有进程建立链接时似乎却遇到了问题。预计这些进程将链接到MPI_COMM_WORLD的p0。问题是我排队撞车

error=MPI_Intercomm_create(  MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM );

错误是:MPI_ERR_COMM: invalid communicator

尽管我不知道如何解决问题,但我已经知道了原因。看来这是由于进程零进行的调用,该调用不属于新的communicator(NEW_COMM)。我试图放置一个if语句以在process = 0时停止执行此行,但是由于它是一个集体调用,因此这再次失败。

任何建议,将不胜感激 。
#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拓扑呢?像这样:

#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;
}

那是你所追求的吗?如果不是,您的沟通者是干什么的?

编辑:有关MPI拓扑的说明

我想澄清的是,即使以这种形式显示了图形通信器,在大多数方面它也与MPI_COMM_WORLD没有什么不同。值得注意的是,它包括最初存在于MPI_COMM_WORLD中的整个MPI进程集。确实,尽管已经定义了它的星形,并且例如,我们没有表示流程1和流程2之间的任何链接,但是并不能阻止您在这两个流程之间进行点对点通信。简单地,通过定义此图拓扑,您可以指示代码将公开的通信模式。然后,您要求库尝试重新排序物理节点上的等级,以使更好地匹配您的计算机/网络的物理布局与您表达的需求。这可以通过例如使用模拟退火方法通过使成本函数最小化的算法在内部完成,但这是昂贵的。此外,这假定网络的实际布局可在某个地方供图书馆使用(多数情况下并非如此)。因此,在一天的大部分时间结束时,都会忽略此放置优化阶段,并且最终获得与输入的索引相同的索引...我只知道一些基于网状/圆环形的网络机器实际执行MPI_Car_create()的放置阶段,但也许我已经过时了。

无论如何,最重要的是,我了解您想与传播者一起学习,但是不要期望他们太多。在这里最好的学习方法是如何以最少,最简单的方式获得想要的人,这是我希望的建议。

关于c++ - MPI虚拟拓扑设计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32820847/

10-16 05:14