我有3个问题,都与MPI(用C语言编写)相关。 我认为前两个问题的答案相同,但我不能确定。
问题1
使用MPI_Dims_create
创建2D网格时,返回的维度中哪个是X,哪个是Y?
例如:
int numProcs = -1, myProcID = -1;
MPI_Comm_rank(MPI_COMM_WORLD, &myProcID);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
int size[2];
size[0] = size[1] = 0;
MPI_Dims_create(numProcs, 2, size);
int numProcs_y = -1, numProcs_x = 1;
它应该是:
numProcs_y = size[0];
numProcs_x = size[1];
或者这个:
numProcs_x = size[0];
numProcs_y = size[1];
我之前尝试使用一些进程数来运行程序(例如6),使用6个进程时,MPI_Dims_create
应该会创建一个3行2列或者2行3列的网格结构(除非我误解了文档)。对于第三个进程(共有6个),我发现size[0]=1
且size[1]=0
(我相信这对应于x=0,y=1)。这似乎表明MPI_Dims_create
正在创建一个3行2列的网格结构(如果是2行3列的话,第二个进程应该会有x=2,y=0)。欢迎任何人提供确认。
问题2
在使用2D笛卡尔网格结构的MPI_Cart_coords
函数时,返回值中哪一个维度代表X轴,哪一个代表Y轴?
例如:
int periodic[2];
periodic[0] = periodic[1] = 0; // no wrap around
MPI_Comm cart_comm;
int coords[2];
// using size from question 1
MPI_Cart_create(MPI_COMM_WORLD, 2, size, periodic, 1, &cart_comm);
MPI_Cart_coords(cart_comm, myProcID, 2, coords);
和问题1类似,我的问题是,应该是这样的吗?
myProcID_y = coords[0];
myProcID_x = coords[1];
或者像这样
myProcID_x = coords[0];
myProcID_y = coords[1];
我已经查阅了文档和之前在这里提出的问题,但似乎没有直接回答这个问题。
文档似乎表明第一种方法是正确的,但它并没有明确说明。
问题三
前两个问题背后的问题是,我正在尝试将二维网格分割成行和列。但是,当我使用 MPI_Comm_rank
检查每个进程的行和列 ID 时,我得到的进程顺序与我认为上述问题的答案不匹配。
根据上述内容,我期望进程的顺序如下:
P0 P1
P2 P3
P4 P5
然而,使用以下代码(在上述代码之后出现在我的程序中,因此可以从中访问所有上述代码:我正在尝试将我的代码分离以使问题更容易隔离):
MPI_Comm row_comm, col_comm;
int row_id = -1, col_id = -1;
// ** NOTE: My use of myProcID_y and myProcID_x here are based
// on my understanding of the previous 2 questions ... if my
// understanding to one/both of those is wrong, then obviously the assignments
// here are wrong too.
// create row and column communicators based on my location in grid
MPI_Comm_split(cart_comm, myProcID_y, myProcID_x, &row_comm);
MPI_Comm_split(cart_comm, myProcID_x, myProcID_y, &col_comm);
// get row and column ID for each process
MPI_Comm_rank(row_comm, &row_id);
MPI_Comm_rank(col_comm, &col_id);
printf("Process: %d\trowID: %d\tcolID: %d\n", myProcID, row_id, col_id);
我看到了以下内容被打印出来:
Process: 0 rowID: 0 colID: 0
Process: 1 rowID: 1 colID: 0
Process: 2 rowID: 0 colID: 1
Process: 3 rowID: 1 colID: 1
Process: 4 rowID: 0 colID: 2
Process: 5 rowID: 1 colID: 2
这似乎对应以下进程的顺序:
P0 P2 P4
P1 P3 P5
这与我从MPI_Dims_create
期望的矩阵尺寸相反(2行3列)。
假设我对前两个问题的理解是正确的(即Y是这些函数返回的第一个维度),那么为什么在这一步中进程(表面上)被以不同的顺序排序了呢?
MPI_COMM_SPLIT
在笛卡尔网格上进行分区。我只是想说,特别是对于高维网格,MPI_CART_SUB
更加方便和多才多艺。使用颜色/关键字分割,您需要计算颜色,而每增加一个维度,这个过程就会变得越来越繁琐。此外,MPI_CART_SUB
创建笛卡尔子网格,而MPI_COMM_SPLIT
创建没有相关拓扑结构的简单通信器。 - Hristo Iliev