有没有办法在MPI中获取唯一的通信器标识符?

有没有办法在MPI中获取唯一的通信器标识符?,mpi,Mpi,我希望能够为某个通信器获取唯一id,但如果通过MPI\u Comm\u split()调用获取此通信器,这似乎是一项不可能完成的任务。我知道当集体调用MPI\u Comm\u split()时,每个产生的不相交的通信器具有相同的上下文ID,但组信息不同。我希望通过调用MPI\u Comm\u group(),与某个通信器关联的组处理程序对于通过拆分创建的每个通信器都是不同的,但在所有通信器中都是相同的 [守则] #include <mpi.h> #include <stdio.

我希望能够为某个通信器获取唯一id,但如果通过
MPI\u Comm\u split()
调用获取此通信器,这似乎是一项不可能完成的任务。我知道当集体调用
MPI\u Comm\u split()
时,每个产生的不相交的通信器具有相同的上下文ID,但组信息不同。我希望通过调用
MPI\u Comm\u 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);
}
因此,不可能确定一个进程属于两个通信者中的哪一个


有没有办法获得唯一标识通信器的id?

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

#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);
}
这可能会解决问题?

如上所述,没有(便携式)方式访问MPI内部。我甚至都不指望会有和你完全一样的东西


为了一般地处理此问题,您可以使用“PMPI”评测界面包装所有mpi communicator管理函数(有关详细信息,请参阅mpi标准14.2)。每当生成一个新的通信器时,您就在每个进程中本地存储关于它的信息,并为它分配一个本地递增的计数器值。然后可以使用
PMPI\u Comm\u group
PMPI\u group\u size
PMPI\u group\u translate\u ranks
来获取成员进程。同时,具有最低全局秩的组成员的增量计数器和成员数组在全局意义上唯一地标识通信器。对于通信者来说,这有点棘手。

发布您的代码以便我们可以查看我添加了一段代码,希望能够澄清我的问题。您确定输出与代码和执行命令行相对应吗?我不希望
split\u rank
从0变为5…是的,对不起。我错了一行。现在应该没问题了,但组和通信器句柄的情况也是一样。MPI使用不透明对象——它们是故意对应用程序隐藏的。您只有一个句柄,除了在API调用中使用它之外,不应该依赖该句柄的任何语义。你打算如何处理这些信息。您将如何在程序的所有级别中定义“唯一的通信器”?
#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);
}
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