MPI虚拟拓扑设计

时间:2015-09-28 10:30:31

标签: 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_ERR_COMM: invalid communicator

虽然我不知道如何修复它,但我已经了解了原因。这似乎是由于进程零的调用,它不属于新的通信器(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;


}

1 个答案:

答案 0 :(得分:1)

如何使用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()的放置阶段,但也许我已经过时了。

无论如何,最重要的是,我知道你想要与传播者一起学习,但不要期望太多。这里要学习的最好的事情是如何以最少和最简单的方式调用你想要的那些,我希望我提出的建议。