c++ - MPI虚拟拓扑设计

标签 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;


}

最佳答案

不如使用 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/

相关文章:

c++ - const func (const scalar& a) const 中的三个 "const",为什么?

c# - Parallel.ForEach仅在未运行代码时才在启动时执行两次吗?

mpi - 一个简单的MPI程序

c++ - 友元函数中的类型不完整

c++ - 在 C++ 代码中执行 Linux 终端命令

c++ - std::strftime 的返回值

parallel-processing - 为什么 OpenMP 原子指令不支持赋值?

javascript - 锁定同时 JavaScript 调用

python - 如何在 Windows 8 中正确安装 mpi4py?

mpirun : token slots not supported