我正在尝试使用MPI实现加农炮算法,我使用以下示例代码:
http://siber.cankaya.edu.tr/ozdogan/GraduateParallelComputing.old/ceng505/node133.html
有一部分我不明白下面是示例代码。
37 /* Perform the initial matrix alignment. First for A and then for B */
38 MPI_Cart_shift(comm_2d, 0, -mycoords[0], &shiftsource, &shiftdest);
39 MPI_Sendrecv_replace(a, nlocal*nlocal, MPI_DOUBLE, shiftdest,
40 1, shiftsource, 1, comm_2d, &status);
41
42 MPI_Cart_shift(comm_2d, 1, -mycoords[1], &shiftsource, &shiftdest);
43 MPI_Sendrecv_replace(b, nlocal*nlocal, MPI_DOUBLE,
44 shiftdest, 1, shiftsource, 1, comm_2d, &status);
这是我现在的密码。
MPI_Comm_size(comm, &size);
MPI_Comm_rank(comm, &rank);
MPI_Cart_coords(comm, rank, 2, coordinates);
MPI_Cart_shift(comm, 0, -1, &rightrank, &leftrank);
MPI_Cart_shift(comm, 1, -1, &downrank, &uprank);
MPI_Cart_shift(comm, 0, -coordinates[0], &shiftsource, &shiftdest);
printf("coordinates[0] = %d for a shiftsource = %d, shiftdest = %d\n", coordinates[0], shiftsource, shiftdest);
//MPI_Sendrecv_replace(a, a->rowNum * a->colNum, MPI_INT, shiftdest,
//1, shiftsource, 1, comm, &status);
MPI_Cart_shift(comm, 1, -coordinates[1], &shiftsource, &shiftdest);
printf("coordinates[1] = %d for b shiftsource = %d, shiftdest = %d\n", coordinates[1], shiftsource, shiftdest);
//MPI_Sendrecv_replace(b, b->rowNum * b->colNum, MPI_INT,
// shiftdest, 1, shiftsource, 1, comm, &status);
我在另一个函数中调用mpi_cart_create,但它与示例代码中的基本调用相同。
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
.
.
.
if(is_perfect_square(size)) dim_size[0] = dim_size[1] = (int) sqrt(size);
else
{ //if size = 2 then dims = 2, 1; size = 4 then 2,2; 8 = 4, 2...
dim_size[0] = (int) sqrt(size + size);
dim_size[1] = dim_size[0] / 2;
}
MPI_Cart_create(MPI_COMM_WORLD, 2, dim_size, periods, 1, &CannonsCart);
现在我只想了解shiftsource和shiftdest的意义。我假设是初始移位,但是当我运行这段代码时,printf语句会这样说。
coordinates[0] = 0 for a shiftsource = 0, shiftdest = 0
coordinates[1] = 0 for b shiftsource = 0, shiftdest = 0
coordinates[0] = 1 for a shiftsource = 1, shiftdest = 1
coordinates[1] = 1 for b shiftsource = 2, shiftdest = 2
coordinates[0] = 1 for a shiftsource = 0, shiftdest = 0
coordinates[1] = 0 for b shiftsource = 2, shiftdest = 2
coordinates[0] = 0 for a shiftsource = 1, shiftdest = 1
coordinates[1] = 1 for b shiftsource = 0, shiftdest = 0
我不明白为什么shiftsource和shiftdest是一样的矩阵A和矩阵B应该是左一上一。
对于此测试用例,此调用的进程数(即大小)为4。如果需要的话,我会把我所有的代码都托管起来。
最佳答案
MPI_Cart_shift
的第三个参数是沿第二个参数指定的维度(方向)的位移。对于沿指定维度具有坐标0
的所有进程,位移也将0
(因为它被指定为-coordinate[i]
),因此源和目标列组将与调用进程的列组匹配。
当位移shiftsource
时,也会得到相同的shiftdest
和1
,因为拓扑是2x2,并且在两个维度上都有周期性边界条件。沿着上一个秩的选定维度的坐标将是(coordinates[i] - 1 + 2) % 2
(这里(a - m + k) % k
计算a - m
模k
)。但这等于(coordinate[i] + 1) % 2
,它正好是下一个秩的坐标。因此,上一个和下一个进程的坐标是圆锥曲线,因此列组最终是相同的。