MPI之虚拟进程拓扑

什么是虚拟进程拓扑

在很多并行应用进程中,进程的线性排列不能充分的反映进程间在逻辑上的通信模型,通常由问题几何和所用的算法决定,进程经常被排列成二维或者三维网络形式的拓扑模型而通常用一个图来描述逻辑进程排列,此种逻辑进程排列为虚拟拓扑。
MPI之虚拟进程拓扑_第1张图片

拓扑是组内通信域上的额外,可选属性,它不能附加在组间通信域(inter-communcator)上,拓扑能提供一种方便的命名机制,对于由特定拓扑要求的算法使用起来直接自然方便。
MPI之虚拟进程拓扑_第2张图片

拓扑还可以辅助运行时系统,将进程映射到实际的硬件结构上。

笛卡尔拓扑

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_Comm old_comm:原通讯域。
  • int ndims:拓扑结构的维度。
  • const int dims[]:每个维度上的进程数量。
  • const int periods[]:每个维度上的边界条件,非零表示周期性边界,零表示非周期性边界。
  • int reorder:是否重新排列原通讯域的进程排列方式。
  • MPI_Comm *comm_cart:新的通讯子,包含 Cartesian 拓扑。

MPI_Cart_shift参数详解

  • MPI_Comm comm:拓扑结构通讯子。
  • int direction:相邻进程的维度。
  • int displ:进程生下的偏移量,一般为 -1 或 1。
  • int *rank_source:源进程的 rank。
  • int *rank_dest:目标进程的 rank。

代码实例

#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。

扩展:

  1. 一维拓扑结构(一维链状结构)

    • 每个进程只有一个相邻进程。
    • 使用 MPI_Comm_split 函数创建。
  2. 多维拓扑结构

    • 每个进程有多个相邻进程。
    • 使用 MPI_Cart_create 函数创建。
  3. 自定义拓扑结构

    • 可以通过 MPI_Comm_create 函数创建自定义拓扑结构,满足特定应用场景的需求。

代码用例来自网络,仅供参考扫盲学习。

你可能感兴趣的:(并行计算,c++,并行计算,MPI,虚拟进程拓扑,笛卡尔拓扑)