有没有办法在 MPI 中获取唯一的通信器标识符?
Is there a way of getting an unique communicator identifier in MPI?
我希望能够获得某个通信器的唯一 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吗?
如评论中所述,您无法控制 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
这可能会解决问题?
如前所述,没有(可移植的)方式访问 MPI 内部结构。而且我什至不指望有完全符合您需要的东西。
为了一般地处理这个问题,您可以使用 "PMPI" 分析接口包装所有 mpi 通信器管理函数(有关详细信息,请参见 MPI 标准 14.2)。每当生成一个新的通信器时,您就将有关它的信息存储在每个进程的本地,并为其分配一个本地递增的计数器值。然后,您可以使用 PMPI_Comm_group
、PMPI_Group_size
和 PMPI_Group_translate_ranks
来获取成员进程。具有最低全局等级的组成员的增量计数器和成员数组一起在全局意义上唯一地标识通信者。对于相互沟通者来说,这有点棘手。
我希望能够获得某个通信器的唯一 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吗?
如评论中所述,您无法控制 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
这可能会解决问题?
如前所述,没有(可移植的)方式访问 MPI 内部结构。而且我什至不指望有完全符合您需要的东西。
为了一般地处理这个问题,您可以使用 "PMPI" 分析接口包装所有 mpi 通信器管理函数(有关详细信息,请参见 MPI 标准 14.2)。每当生成一个新的通信器时,您就将有关它的信息存储在每个进程的本地,并为其分配一个本地递增的计数器值。然后,您可以使用 PMPI_Comm_group
、PMPI_Group_size
和 PMPI_Group_translate_ranks
来获取成员进程。具有最低全局等级的组成员的增量计数器和成员数组一起在全局意义上唯一地标识通信者。对于相互沟通者来说,这有点棘手。