MPI_Cart_Shift.Corner邻居

时间:2015-12-09 22:27:55

标签: c++ mpi topology cartesian

enter image description here

我需要使用多维数据集拓扑创建一个通信器,然后选择多维数据集的面,使用MPI_Cart_Shift在边缘处理的进程之间实现消息传递。例如,我处理等级0(R0)我的邻域是R2,R4,R6(立方体的下面)。我可以找到R2和R4,但我无法理解如何找到R6。我的代码:

#include<mpi.h>
#include<stdio.h>

int main(int argc, char *argv[])
{
int rank, k;
int size; 
int ndims = 3; 
int source, dest;
int up,down,right,left,up3, down3;

int edges[6][4] = {{0,1,5,4},
                {4,5,7,6},
                {2,3,1,0},
                {6,7,3,2},
                {1,3,7,5},
                {0,2,6,7}};

int t, incep=0;
char processor_name[MPI_MAX_PROCESSOR_NAME];

MPI_Comm comm, comm3d;
int dims[3]={0,0,0}, coords[3]={0,0,0},
    periods[3]={1,1,1}, reorder = 0;


MPI_Status status;


int user_edge;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Dims_create(size, ndims, dims);


  MPI_Cart_create(MPI_COMM_WORLD, ndims, dims, periods, reorder, &comm);


  MPI_Cart_coords(comm, rank, 3, coords);

 fflush(stdout);
     printf("Rank %d coordinates are %d %d %d\n", rank, coords[0], coords[1], coords[2]);
 MPI_Barrier(comm);

    int leftrank, rightrank;
    int downrank, uprank;

MPI_Comm_rank(comm, &rank);
    MPI_Cart_coords(comm, rank, 2, coords);
MPI_Cart_shift(comm, 0, -1, &downrank, &uprank); 
MPI_Sendrecv(buffer, 10, MPI_INT, downrank, 123, buffer2, 10, MPI_INT, uprank, 123, comm, &status);
MPI_Cart_shift(comm, 1, -1, &rightrank, &leftrank); 
    MPI_Sendrecv(buffer, 10, MPI_INT, leftrank, 123, buffer2, 10, MPI_INT, rightrank, 123, comm, &status);


printf("P:%d My neighbors are rightRank: %d downRank:%d leftRank:%d upRank:%d diagonal:%d diagonalX:%d\n", rank,rightrank,downrank,leftrank,uprank,diagonal,diagonalX);



MPI_Finalize();

return 0;

}

我会尝试添加类似这样的MPI_Cart_shift(comm,2,1,&amp; diagonal,&amp; diagonalX);但是对于R0,它向我展示了R1,我理解......我怎样才能获得角落社区?

3 个答案:

答案 0 :(得分:3)

您可以使用 MPI_Cart_rank 查找所需信息。

int MPI_Cart_rank(MPI_Comm comm, const int coords[], int *rank)

此处 comm 是具有笛卡尔拓扑的通信器。 coords 是一个整数数组(此数组的大小是笛卡尔拓扑的维数),包含进程的坐标(在您的情况下,R6为1,1,0)。然后输出 rank 将返回您可以在后续通信中使用的该进程的全局排名。

BTW, MPI_Cart_coords 执行相反的方向,即从等级到坐标。

答案 1 :(得分:1)

MPI_Cart_shift只能在任何主要方向找到邻居,但不能在对角线上找到 - 你必须自己实现它,这并不难做到。笛卡尔移位本身只是一个包含对MPI_Cart_coordsMPI_Cart_rank的调用的便利函数:

//
// The following is equivalent to
// MPI_Cart_shift(cart_comm, i, disp, &rank_source, &rank_dest);
//

// Obtain the rank of the calling process and translate it into coordinates
int rank, coords[ndims];
MPI_Comm_rank(cart_comm, &rank);
MPI_Cart_coords(cart_comm, rank, ndims, coords);

int mycoord_i = coords[i];

// Compute the coordinates of the destination in direction i and convert them into rank
coords[i] = mycoord_i + disp;
// Take care of non-periodic dimensions
if (!periods[i] && (coords[i] >= dims[i] || coords[i] < 0))
   rank_dest = MPI_PROC_NULL;
else
   MPI_Cart_rank(cart_comm, coords, &rank_dest);

// Compute the coordinates of the source in direction i and convert them into rank
coords[i] = mycoord_i - disp;
// Take care of non-periodic dimensions
if (!periods[i] && (coords[i] >= dims[i] || coords[i] < 0))
   rank_source = MPI_PROC_NULL;
else
   MPI_Cart_rank(cart_comm, coords, &rank_source);

请注意应如何针对非周期性维度明确处理越界。对于周期性的,MPI_Cart_rank本身会对坐标进行折叠。您的笛卡尔拓扑是周期性的,因此可以跳过检查(不推荐)。

您可以轻松调整上面的代码以产生两个或更多维度的移位,然后使用它来枚举位移和方向的所有可能组合,以找到位于给定面部的等级。例如:

int rank, coords[ndims];
MPI_Comm_rank(cart_comm, &rank);
MPI_Cart_coords(cart_comm, rank, ndims, coords);
int my_coord1 = coords[1];
int my_coord2 = coords[2];
coords[1] = my_coord1 + 1;
coords[2] = my_coord2 + 1;
MPI_Cart_rank(cart_comm, coords, &rank_dest);
coords[1] = my_coord1 - 1;
coords[2] = my_coord2 - 1;
MPI_Cart_rank(cart_comm, coords, &rank_source);
当由R0执行时,

将在rank_dest中给出R6的等级。如果您在单独的例程中提取代码并将其称为MyMPI_Cart_shift2

MyMPI_Cart_shift2(cart_comm, 1, 1, 2, 1, &rank_source, &rank_dest);

另一个选择是使用MPI_Cart_sub将笛卡尔拓扑分割成平行于面的平板。然后,您可以直接执行仅涉及任何给定楼板中的等级的通信。

答案 2 :(得分:0)

你忘了标记R5。我无法想到直接的方法。但这是间接的方式:

(1)对于坐标为each的任何等级,请考虑坐标:(A,y,z)(A,y+1,z+1), (A,y-1,z-1), (A,y+1,z-1) - 这些可以是4个对角线邻居。显然,考虑减去例如(A,y-1,z+1)z-1显然是z-1 >= 0,当考虑加y+1 <= (dimension_in_y - 1)。例如,考虑R5(您忘记标记)。根据MPI,R5的坐标为R5(0,1,0)。它可以有4个对角线邻居:(0,1+1,0+1), (0,1-1,0-1),(0,1+1,0-1),(0,1-1,0+1) - 其中只存在第四个邻居(这是明确的,因为没有邻居可以有负坐标并且每个坐标必须 1 less < / em>比那个方向的尺寸)。接下来只需查询MPI_coordinate_to_rank()

(2)另一种方法是查询rightleft邻居关于他们的frontback邻居(这将是性能不佳)。

(3)要将它概括为8个邻居 - 你也需要改变X坐标 - 但你的问题仅限于立方体的面。