版权声明:码字不易,欢迎点赞。 https://blog.csdn.net/weixin_40255793/article/details/84999495
int MPI_Cart_shift(MPI_Comm comm, int direction, int disp,
int *rank_source, int *rank_dest)
- direction:指定维度
- disp:指定通信的方向和距离,负数表示负方向
- rank_source:通信的源进程的等级
- rank_dest:通信的目的进程的等级
假定我们建立两个维度,x 维度和y 维度,大小分别为 3 和 2,x 维度有环,y 维度无环。我们给 6 个进程构建成笛卡尔拓扑结构,如下:
坐标(x,y)对应的进程等级为 x*2 + y
,和我们平时用一维数组保存多维坐标数据的方式一样。可以类推,如果三个维度分别为 x,y,z,维度大小分别为 nx,ny,nz,那么坐标(x,y,z)对应的进程等级为 x*ny*nz + y*nz + z
。
MPI_Cart_shift
可以获得进程节点在 direction 这个维度方向上的邻居进程的等级。如下,第一个函数获得了 x 轴方向的邻居进程,第二个函数获得了 y 轴方向的邻居进程。(上下左右的概念是相对于你画的图形的,建议以维度的方向为准)
MPI_Cart_shift(comm_cart, 0, 1, &nbrs[0], &nbrs[1]);
MPI_Cart_shift(comm_cart, 1, 1, &nbrs[2], &nbrs[3]);
进程 4 (2,0),沿 x 轴正方向,源进程和目的进程分别为图中的左邻居和右邻居,因为 x 轴是有环的,所以进程 4 的右邻居就是进程 0;进程 4,沿 y 轴正方向,源进程和目的进程分别为图中的上邻居和下邻居,因为 y 轴无环,所以进程 4 的上邻居是进程 MPI_PROC_NULL
,即 -1。所以对于进程 4 而言,执行完上面代码框之后,nbrs[] 数组的元素为 {2,0,-1,5}。
(上下左右的概念是相对于你画的图形的,建议以维度的方向为准)
附录:测试代码
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main() {
#define NPROCS 6
#define LEFT 0
#define RIGHT 1
#define UP 2
#define DOWN 3
MPI_Init(NULL, NULL);
int world_size, world_rank;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int nbrs[4], dims[2] = { 3, 2 },
periods[2] = { 1, 0 }, reorder = 1, coords[2];
MPI_Comm comm_cart;
if (world_size != NPROCS) {
printf("Must specify MP_PROCS= %d. Terminating.\n", NPROCS);
MPI_Finalize();
exit(0);
}
MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, reorder, &comm_cart);
MPI_Comm_rank(comm_cart, &world_rank);
MPI_Cart_coords(comm_cart, world_rank, 2, coords);
MPI_Cart_shift(comm_cart, 0, 1, &nbrs[LEFT], &nbrs[RIGHT]);
MPI_Cart_shift(comm_cart, 1, 1, &nbrs[UP], &nbrs[DOWN]);
printf("rank= %d coords= %d %d neighbors{l,r,u,d}= %d %d %d %d\n",
world_rank, coords[0], coords[1], nbrs[LEFT], nbrs[RIGHT], nbrs[UP], nbrs[DOWN]);
MPI_Finalize();
return 0;
}
输出:
$ mpiexec -n 6 a.out
rank= 0 coords= 0 0 neighbors{l,r,u,d}= 4 2 -1 1
rank= 1 coords= 0 1 neighbors{l,r,u,d}= 5 3 0 -1
rank= 2 coords= 1 0 neighbors{l,r,u,d}= 0 4 -1 3
rank= 3 coords= 1 1 neighbors{l,r,u,d}= 1 5 2 -1
rank= 4 coords= 2 0 neighbors{l,r,u,d}= 2 0 -1 5
rank= 5 coords= 2 1 neighbors{l,r,u,d}= 3 1 4 -1