【问题标题】:Is there a way of getting an unique communicator identifier in MPI?有没有办法在 MPI 中获取唯一的通信器标识符?
【发布时间】:2016-02-23 04:03:39
【问题描述】:

我希望能够获得某个通信器的唯一 ID,但是当您通过 MPI_Comm_split() 调用获得此通信器时,这似乎是一项不可能完成的任务。我知道当MPI_Comm_split() 被集体调用时,每个产生的不相交的通信器都具有相同的上下文ID 但不同的组信息。我期望通过调用MPI_Comm_group(),与某个通信器关联的组处理程序对于拆分创建的每个通信器都会有所不同,但在所有通信器中都是相同的!

[代码]

#include <mpi.h>
#include <stdio.h>

int main() {
    MPI_Init(NULL, NULL);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm split_comm;
    MPI_Comm_split(MPI_COMM_WORLD, rank / 3, rank, &split_comm);
    int split_rank;
    MPI_Group split_group;
    MPI_Comm_group(split_comm, &split_group);
    MPI_Comm_rank(split_comm, &split_rank);
    printf("rank: %d| comm: %u, group: %u\n", split_rank, split_comm, split_group);
}

如果使用mpirun -np 6 ./exec 运行上面的代码,结果是:

rank: 0| comm: 2214592516, group: 2281701376
rank: 1| comm: 2214592514, group: 2281701376
rank: 2| comm: 2214592514, group: 2281701376
rank: 0| comm: 2214592514, group: 2281701376
rank: 1| comm: 2214592514, group: 2281701376
rank: 2| comm: 2214592514, group: 2281701376

因此无法确定一个进程属于两个通信器中的哪一个。

有什么方法可以获取唯一标识通信者的 id?

【问题讨论】:

  • 贴出你的代码让我们看看
  • 我添加了一段代码,希望能澄清我的问题。
  • 你确定输出对应的代码和执行命令行?我不希望 split_rank 从 0 变为 5...
  • 是的,对不起。我错了一行。现在应该没问题了,但是组和通信器句柄的情况是一样的。
  • MPI 使用不透明的对象——它们被有意隐藏在应用程序之外。您所拥有的只是一个句柄,您不应该依赖该句柄的任何语义,除非在 API 调用中使用它。您实际上打算如何处理这些信息。您如何定义项目中所有级别的“独特沟通者”?

标签: mpi


【解决方案1】:

如 cmets 中所述,您无法控制 MPI 为其 COMM 设置的值。但是,您可以按如下方式设置通信名称,

#include <mpi.h>
#include <stdio.h>
#include <iostream>

int main() {

    MPI_Init(NULL, NULL);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm split_comm;
    int colour = rank/3;
    MPI_Comm_split(MPI_COMM_WORLD, colour, rank, &split_comm);

    // Define string from split colour and use to set comm name
    std::string name = "Comm-";
    name += std::to_string(colour);
    const char * commname = name.c_str();
    MPI_Comm_set_name(split_comm, commname);

    int split_rank;
    MPI_Group split_group;
    MPI_Comm_group(split_comm, &split_group);
    MPI_Comm_rank(split_comm, &split_rank);

    //Retrieve commname and print
    int rlen;
    char nameout[MPI_MAX_OBJECT_NAME];
    MPI_Comm_get_name(split_comm, nameout, &rlen);
    printf("rank: %d| comm: %u, comm_name: %s, group: %u\n", split_rank, split_comm, nameout, split_group);
}

mpirun -np 6 ./exec 示例的输出在哪里,

rank: 0| comm: 2214592516, comm_name: Comm-0, group: 2281701376
rank: 1| comm: 2214592514, comm_name: Comm-0, group: 2281701376
rank: 2| comm: 2214592514, comm_name: Comm-0, group: 2281701376
rank: 0| comm: 2214592514, comm_name: Comm-1, group: 2281701376
rank: 1| comm: 2214592514, comm_name: Comm-1, group: 2281701376
rank: 2| comm: 2214592514, comm_name: Comm-1, group: 2281701376

这样可以解决问题吗?

【讨论】:

    【解决方案2】:

    如前所述,没有(便携式)方法可以访问 MPI 内部。而且我什至不会指望有你需要的东西。

    为了一般性地处理这个问题,您可以使用“PMPI”分析接口封装所有 mpi 通信器管理功能(有关详细信息,请参阅 MPI 标准 14.2)。每当生成一个新的通信器时,您就会在每个进程中本地存储有关它的信息,并为其分配一个本地递增的计数器值。然后您可以使用PMPI_Comm_groupPMPI_Group_sizePMPI_Group_translate_ranks 来获取成员进程。具有最低全局等级的组成员的增量计数器和成员数组一起唯一地标识全局意义上的通信器。对于内部沟通者来说,这有点棘手。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      • 2015-09-27
      • 2020-01-22
      相关资源
      最近更新 更多