在很多并行应用进程中,进程的线性排列不能充分的反映进程间在逻辑上的通信模型,通常由问题几何和所用的算法决定,进程经常被排列成二维或者三维网络形式的拓扑模型而通常用一个图来描述逻辑进程排列,此种逻辑进程排列为虚拟拓扑。
拓扑是组内通信域上的额外,可选属性,它不能附加在组间通信域(inter-communcator)上,拓扑能提供一种方便的命名机制,对于由特定拓扑要求的算法使用起来直接自然方便。
拓扑还可以辅助运行时系统,将进程映射到实际的硬件结构上。
MPI 笛卡尔拓扑是一种二维矩形的结构,在这个结构中,每个进程都有一个唯一的坐标。这种拓扑结构通常用于实现多维分布式数组的通讯。
使用 MPI_Cart_create 函数可以创建 Cartesian 拓扑,并使用 MPI_Cart_shift 函数获取进程在对应维度上的相邻进程的 ran
函数原型
int MPI_Cart_create(MPI_Comm old_comm, int ndims,
const int dims[], const int periods[], int reorder,
MPI_Comm *comm_cart);
int MPI_Cart_shift(MPI_Comm comm, int direction, int displ,
int *rank_source, int *rank_dest);
MPI_Cart_create参数详解
MPI_Cart_shift参数详解
代码实例
#include
#include
int main(int argc, char* argv[]) {
int rank, size;
MPI_Comm comm_cart;
int dims[2], periods[2], coords[2], reorder;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// 确定每个维度的大小
dims[0] = dims[1] = 0;
MPI_Dims_create(size, 2, dims);
// 设置周期性边界条件
periods[0] = periods[1] = 1;
reorder = 1;
MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, reorder, &comm_cart);
// 获取当前进程在 Cartesian 拓扑中的坐标
MPI_Comm_rank(comm_cart, &rank);
MPI_Cart_coords(comm_cart, rank, 2, coords);
printf("Rank %d:\tCoords = (%d, %d)\n", rank, coords[0], coords[1]);
// 获取当前进程在 x 方向上相邻进程的 rank
int left, right;
MPI_Cart_shift(comm_cart, 0, 1, &left, &right);
printf("Rank %d:\tLeft = %d, Right = %d\n", rank, left, right);
// 获取当前进程在 y 方向上相邻进程的 rank
int up, down;
MPI_Cart_shift(comm_cart, 1, 1, &up, &down);
printf("Rank %d:\tUp = %d, Down = %d\n", rank, up, down);
MPI_Finalize();
return 0;
使用 MPI_Cart_create 函数创建了 Cartesian 拓扑,然后使用 MPI_Cart_coords 函数获取一个进程在 Cartesian 拓扑中的坐标。最后,使用 MPI_Cart_shift 函数获取相邻进程在 Cartesian 拓扑中的 rank。
在本示例中,我们假设拓扑是一个二维矩形,因此我们使用 MPI_Dims_create 函数以及维度数量和进程总数来计算每个维度的大小。我们还将 periods 数组设置为 {1,1},表示在每个维度的两端都设置周期性边界条件。我们还把 reorder 参数设置为 1,以便 MPI 能够以最优方式映射进程到拓扑结构中。
使用 MPI_Cart_create 函数,我们创建了一个通讯子,该子进程具有 Cartesian 拓扑。接着使用 MPI_Cart_shift 函数,以获取当前进程在 x 和 y 方向上相邻进程的 rank。
一维拓扑结构(一维链状结构)
多维拓扑结构
自定义拓扑结构
代码用例来自网络,仅供参考扫盲学习。