MPI:多个重叠的通信器
MPI: Multiple Overlapping Communicators
我想创建 MPI 通信器,将等级为 0 的进程链接到所有其他进程。假设 n 是进程总数。那么等级为 0 的进程应该有 n-1 个通信器,而其他每个进程都有一个通信器。这可能吗,如果可能,为什么我不能使用下面的程序来实现它?
使用 mpic++ 编译器编译以下代码在我的计算机上终止,没有警告和错误。但是当我 运行 结果程序使用 3 个或更多进程 (mpiexec -n 3) 时,它永远不会终止。
我可能误解了 MPI 中通信器的概念。也许有人可以帮助我理解为什么下面的程序会卡住,以及创建这些通信器的更好方法是什么?谢谢
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include "mpi.h"
void FinalizeMPI();
void InitMPI(int argc, char** argv);
int main(int argc, char** argv) {
InitMPI(argc, argv);
int rank,comm_size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
if(comm_size<2) {
FinalizeMPI();
return 0;
}
MPI_Group GroupAll;
MPI_Comm_group(MPI_COMM_WORLD, &GroupAll);
if(rank==0) {
std::vector<MPI_Group> myGroups(comm_size-1);
std::vector<MPI_Comm> myComms(comm_size-1);
for(int k=1;k<comm_size;++k) {
int ranks[2]{0, k};
MPI_Group_incl(GroupAll, 2, ranks, &myGroups[k-1]);
int err = MPI_Comm_create(MPI_COMM_WORLD, myGroups[k-1], &myComms[k-1]);
std::cout << "Error: " << err << std::endl;
}
} else {
MPI_Group myGroup;
MPI_Comm myComm;
int ranks[2]{0,rank};
MPI_Group_incl(GroupAll, 2, ranks, &myGroup);
int err = MPI_Comm_create(MPI_COMM_WORLD, myGroup, &myComm);
std::cout << "Error: " << err << std::endl;
}
std::cout << "Communicators created: " << rank << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
FinalizeMPI();
return 0;
}
void FinalizeMPI() {
int flag;
MPI_Finalized(&flag);
if(!flag)
MPI_Finalize();
}
void InitMPI(int argc, char** argv) {
int flag;
MPI_Initialized(&flag);
if(!flag) {
int provided_Support;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided_Support);
if(provided_Support!=MPI_THREAD_MULTIPLE) {
exit(0);
}
}
}
MPI_Comm_create
是对初始通信器 (MPI_COMM_WORLD
) 的集体操作 - 您必须在所有进程上调用它。
解决此问题的最简单方法是按照您的方式使用 MPI_Comm_create_group
。它与 MPI_Comm_create
类似,只是它是集体管理的。
我想创建 MPI 通信器,将等级为 0 的进程链接到所有其他进程。假设 n 是进程总数。那么等级为 0 的进程应该有 n-1 个通信器,而其他每个进程都有一个通信器。这可能吗,如果可能,为什么我不能使用下面的程序来实现它?
使用 mpic++ 编译器编译以下代码在我的计算机上终止,没有警告和错误。但是当我 运行 结果程序使用 3 个或更多进程 (mpiexec -n 3) 时,它永远不会终止。
我可能误解了 MPI 中通信器的概念。也许有人可以帮助我理解为什么下面的程序会卡住,以及创建这些通信器的更好方法是什么?谢谢
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include "mpi.h"
void FinalizeMPI();
void InitMPI(int argc, char** argv);
int main(int argc, char** argv) {
InitMPI(argc, argv);
int rank,comm_size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
if(comm_size<2) {
FinalizeMPI();
return 0;
}
MPI_Group GroupAll;
MPI_Comm_group(MPI_COMM_WORLD, &GroupAll);
if(rank==0) {
std::vector<MPI_Group> myGroups(comm_size-1);
std::vector<MPI_Comm> myComms(comm_size-1);
for(int k=1;k<comm_size;++k) {
int ranks[2]{0, k};
MPI_Group_incl(GroupAll, 2, ranks, &myGroups[k-1]);
int err = MPI_Comm_create(MPI_COMM_WORLD, myGroups[k-1], &myComms[k-1]);
std::cout << "Error: " << err << std::endl;
}
} else {
MPI_Group myGroup;
MPI_Comm myComm;
int ranks[2]{0,rank};
MPI_Group_incl(GroupAll, 2, ranks, &myGroup);
int err = MPI_Comm_create(MPI_COMM_WORLD, myGroup, &myComm);
std::cout << "Error: " << err << std::endl;
}
std::cout << "Communicators created: " << rank << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
FinalizeMPI();
return 0;
}
void FinalizeMPI() {
int flag;
MPI_Finalized(&flag);
if(!flag)
MPI_Finalize();
}
void InitMPI(int argc, char** argv) {
int flag;
MPI_Initialized(&flag);
if(!flag) {
int provided_Support;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided_Support);
if(provided_Support!=MPI_THREAD_MULTIPLE) {
exit(0);
}
}
}
MPI_Comm_create
是对初始通信器 (MPI_COMM_WORLD
) 的集体操作 - 您必须在所有进程上调用它。
解决此问题的最简单方法是按照您的方式使用 MPI_Comm_create_group
。它与 MPI_Comm_create
类似,只是它是集体管理的。