我对
MPI_Isend
和
MPI_Irecv
。我正在研究图的邻接矩阵,它是按行分布的。我们可以假设每个处理器包含一行。对于每对索引
(i,j)
我需要发送和接收2个整数。基本上,为了进行计算,我需要从其他行接收一些其他信息。我是MPI新手,在这里它进入无限循环,我甚至不确定它是不是正确的使用方式
MPI\u Isend
或
MPI\U Irecv
在for循环中,也是放置等待的位置。
例如,假设我们有一个有6个顶点的图,那么邻接矩阵(
adjMatrix
)将是一个6*6的矩阵,我们还有一个6*2的矩阵用于其他一些信息,最后,我们在6个处理器之间分配数据。因此:
|0 20 16 0 6 0 | |0 1|
|20 0 0 19 0 6 | |1 1|
addMatrix=|16 0 0 0 12 0 | M=|2 1|
|0 19 0 0 0 12| |3 1|
|6 0 12 0 0 9 | |0 0|
|0 6 0 12 9 0 | |1 0|
我们将矩阵分布如下:
P0: |0 20 16 0 6 0 | |0 1|
P1: |20 0 0 19 0 6 | |1 1|
P2: |16 0 0 0 12 0 | |2 1|
P3: |0 19 0 0 0 12| |3 1|
P4: |6 0 12 0 0 9 | |0 0|
P5: |0 6 0 12 9 0 | |1 0|
现在,每个处理器都需要更新其
调整矩阵
。为此,他们需要从矩阵的某些部分获得信息
M
,它位于其他处理器中。例如,为了
P0
更新索引
(0,1)
这是
20
,它需要有权访问该行
1
矩阵的
M
这是
{1,1}
。因此:
P1
应发送
MLocal[0][0]=1
和
MLocal[0][1]=1
到
P0
其中
P0
接收它们为
M_j0
和
M_j1
分别地
和
P0
应发送
MLocal[0][0]=0
和
MLocal[0][1]=1
到
P1级
其中
P1级
接收它们为
M\u j0
和
M\U j1
分别地
for(int i=0;i<rows;i++){
for (int j=0; j<n; j++)
{
int M_j0,M_j1;
MPI_Isend(&MLocal[i][0], 1, MPI_INT, j, my_rank+i*n+j+0, MPI_COMM_WORLD, &send_request0);
MPI_Isend(&MLocal[i][1], 1, MPI_INT, j, my_rank+i*n+j+1, MPI_COMM_WORLD, &send_request1);
MPI_Irecv(&M_j0, 1, MPI_INT, j, my_rank+i*n+j+0, MPI_COMM_WORLD, &recv_request0);
MPI_Irecv(&M_j1, 1, MPI_INT, j, my_rank+i*n+j+1, MPI_COMM_WORLD, &recv_request1);
MPI_Wait(&recv_request0, &status);
MPI_Wait(&recv_request1, &status);
}
}
然后根据GillesGouaillardet的建议,我改变了4
MPI\u Isend
和
MPI\U Irecv
收件人:
MPI_Sendrecv(&MoatsLocal[i][0], 1, MPI_INT, j, my_rank+i*n+j+0, &M_j0,1, MPI_INT, my_rank, my_rank+i*n+j+0, MPI_COMM_WORLD, &status);
MPI_Sendrecv(&MoatsLocal[i][1], 1, MPI_INT, j, my_rank+i*n+j+1, &M_j1,1, MPI_INT, my_rank, my_rank+i*n+j+1, MPI_COMM_WORLD, &status);
但它仍然会进入一个无限循环。
更新时间:
我更新了代码,部分问题是因为处理器排名和匹配标签。我修复了该部分,但仍然容易出现死锁,我想我知道问题出在哪里。可能无法解决。如果我有足够多的处理器,将每一行分配给一个处理器,即n=p,那么就不会有任何问题。但问题是处理器数量少于
n
,那么流不是很好地通过主对角线,我通过示例解释它,让我们假设我们有4个处理器
n=6
。假设分布如下:
P0: |0 20 16 0 6 0 | |0 1|
P1: |20 0 0 19 0 6 | |1 1|
|16 0 0 0 12 0 | |2 1|
P2: |0 19 0 0 0 12| |3 1|
P3: |6 0 12 0 0 9 | |0 0|
|0 6 0 12 9 0 | |1 0|
这就是循环中发生的事情。
第一次迭代:
P0向P1发送和接收信息(0,1):“20”并等待(完成)
P1向P0发送和接收信息(1,0):“20”并等待(完成)
P2向P1发送和接收(3,1)的信息:“19”并等待
P3向P0发送和接收(4,1)的信息:“6”并等待
第二次迭代:
P0向P1发送和接收信息(0,2):“16”并等待
P1向P2发送和接收(1,3)的信息:“19”并等待(完成)
P2为P1(3,1)哭泣:“19”然后就收到并完成了!
P3正在等待P0(4,1):“6”,然后等待
第三次迭代:
P0正在等待P1的(0,2):“16”
P1向P3发送和接收(1,5)的信息:“19”并等待
P2向P3发送和接收(3,5)的信息:“12”并等待
P3正在等待(4,1):“6”的P0
第四次迭代:
P0正在等待P1的(0,2):“16”
P1正在等待P3的(1,5):“19”
P2正在等待P3的(3,5):“12”
P3正在等待(4,1):“6”的P0
现在,所有人都在等待对方,我认为没有任何办法解决它。ptb建议的解决方案可能会奏效,我会试试那个。
尽管如此,任何其他想法都是值得赞赏的!