在MPI_Bcast中排名

时间:2012-07-29 01:21:01

标签: mpi

MPI_Bcast(void *buffer,  int count,  MPI_Datatype datatype,  int root,  MPI_Comm comm)

此功能不需要rank参数。它如何知道每个过程的等级?

我们应该在广播之前调用MPI_COMM_RANK(),是否有任何数据结构(如communicator)存储进程的等级?

4 个答案:

答案 0 :(得分:5)

也许您认为不可能,但MPI库中的函数可以在内部使用相同的MPI调用来获取进程的级别或通信器的大小。这就是为什么MPI_Bcast()不需要调用进程的等级,因为它只是调用MPI_Comm_rank()的内部实现来获取它。以下是来自Open MPI中MPI_Bcast()实现之一的小样本(更具体地说,这来自tuned模块中来自coll框架的拆分二叉树实现,该框架提供了算法实现集体行动):

int
ompi_coll_tuned_bcast_intra_split_bintree ( void* buffer,
                                            int count, 
                                            struct ompi_datatype_t* datatype, 
                                            int root,
                                            struct ompi_communicator_t* comm,
                                            mca_coll_base_module_t *module,
                                            uint32_t segsize )
{
    ...
    int rank, size;
    ...

    size = ompi_comm_size(comm);
    rank = ompi_comm_rank(comm);

    ...
}

如您所见,它调用了MPI_Comm_size()MPI_Comm_rank()的内部实现。这些是Open MPI中非常便宜的调用。进程的等级存储在与通信器关联的进程组中,并被复制到通信器结构中的一个字段(以保存几个CPU周期,取消引用指向该组的指针)创建沟通者(有关更多信息,请参阅openmpi-source/ompi/communicator/communicator.hopenmpi-source/ompi/group/group.h)。

事实上,没有MPI通信原语明确地明确调用进程的等级 - 它总是在内部解决。您只需指定发送数据的位置(例如,在MPI_SEND中)或从何处接收数据(例如在MPI_RECV中)或具有一个的集合操作中的数据根。

答案 1 :(得分:2)

考虑MPI_Bcast()的三种可能实现:

  1. root 发送至root+1,然后发送至root+2,然后发送至root+3等。这是一个线性数量级
  2. root 开始,每个具有迭代N数据副本的进程都会将数据转发到rank xor 2^N。这是对数的数量级。
  3. root 使用路由器对网络上的每个进程执行多播。这是不变的数量级。
  4. 在每种情况下,MPI_Bcast()函数都知道哪个进程将获得下一条消息。在第一种和第三种情况下,任何非root 进程都将只接收数据;在第二个过程中,每个进程一旦收到数据就会继续转发过程。但是,在所有实现中,发送和接收的顺序是确定性的,基于哪个进程是 root 。 (这就是为什么所有进程都必须调用MPI_Bcast(),无论是否 root 。)

答案 2 :(得分:0)

你是对的,等级存储在通信器中,并且可以在内部实现MPI_Bcast。在创建通信器时分配等级。例如,MPI_COMM_WORLDMPI_Init创建。

MPI_Comm_rank只是从通信器获取排名值。在广播之前没有要求呼叫它。但是,了解排名通常是进行任何有意义的编程所必需的。

请注意,由于MPI_Bcast是一个集体调用,因此需要由通信器中的所有进程执行。

答案 3 :(得分:-1)

int root,是广播根的等级,基本上MPI广播从等级根发送消息到所有其他等级

在MPI_Init

之后,我也会考虑调用以下内容的“最佳做法”
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

这将为每个处理器或核心分配从0到n-1

的int rank值

MPI_Comm_size( MPI_COMM_WORLD, &Numprocs);

这将创建一个以Numproces为处理器总数的int