- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
MPI_Isend
和 MPI_Irecv
有问题。我正在研究按行分布的图的邻接矩阵。我们可以假设每个处理器包含一行。对于每对索引 (i,j)
我需要发送和接收 2 个整数。基本上,我需要从其他行接收一些其他信息才能进行计算。我是 MPI 的新手,在这里它进入了无限循环,我什至不确定它是否是在 for 循环中使用 MPI_Isend
或 MPI_Irecv
的正确方法,也是等待的地方。
举个例子,假设我们有一个有 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|
现在,每个处理器都需要更新它的 adjMatrix
部分。为此,他们需要来自矩阵 M
某些部分的信息,该部分位于其他处理器中。例如,为了 P0
更新索引 (0,1)
即 20
,它需要访问 行矩阵
即 M
的 1{1,1}
。因此:
P1
should sendMLocal[0][0]=1
andMLocal[0][1]=1
toP0
in whichP0
receives them asM_j0
andM_j1
, respectively.And
P0
should sendMLocal[0][0]=0
andMLocal[0][1]=1
toP1
in whichP1
receives them asM_j0
andM_j1
, respectively.
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(&send_request0, &status);
//MPI_Wait(&send_request1, &status);
MPI_Wait(&recv_request0, &status);
MPI_Wait(&recv_request1, &status);
// Do something ...
}
}
然后根据 GillesGouaillardet 的建议,我将 4 MPI_Isend
和 MPI_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);
但是,它仍然会进入无限循环。
UPDATE:
我更新了代码,部分问题是因为处理器排名和匹配标签。我修复了那部分,但它仍然容易死锁,我想我知道问题出在哪里。而且可能无法解决。如果我有足够数量的处理器,将每一行分配给一个处理器,即 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 send and receive to/from P1 information for (0,1):"20" and wait(done)
P1 send and receive to/from P0 information for (1,0):"20" and wait(done)
P2 send and receive to/from P1 information for (3,1):"19" and wait
P3 send and receive to/from P0 information for (4,1):"6" and wait
第二次迭代:
P0 send and receive to/from P1 information for (0,2):"16" and wait
P1 send and receive to/from P2 information for (1,3):"19" and wait(done)
P2 was wainting for P1 (3,1):"19" then just recieved it and done!
P3 is waiting for P0 for (4,1):"6" and wait
第三次迭代:
P0 is waiting for P1 for (0,2):"16"
P1 send and receive to/from P3 information for (1,5):"19" and wait
P2 send and receive to/from P3 information for (3,5):"12" and wait
P3 is waiting for P0 for (4,1):"6"
第四次迭代:
P0 is waiting for P1 for (0,2):"16"
P1 is waiting for P3 for (1,5):"19"
P2 is waiting for P3 for (3,5):"12"
P3 is waiting for P0 for (4,1):"6"
现在都是互相等待,我觉得没有办法解决。 ptb 建议的解决方案可能有效,我会尝试那个。
不过,任何其他想法表示赞赏!
最佳答案
您发布的代码存在一些问题
行
。但是在您的描述中,行分布在处理器之间,因此这可能是一个错误。j=0
的情况,MPI_Isend(...,j,...) 意味着每个级别都会向根进程发送一些内容。随后调用 MPI_IRecv(...,j,...), MPI_Wait,这意味着每个进程都将等待来自根进程的发送,但该发送永远不会到来。挑战在于您需要发送和接收调用来匹配。一种方法(不一定是最高性能的)是通过 MPI_Isend 循环发布所有发送,然后使用 MPI_Probe、MPI_Recv 处理每个等级的 recvs(因为 recvs 的数量是发送的数量,你知道如何许多)。伪代码示例:
int send_count = 0;
for (int j=0; j<n; j++) {
if (matrix_entry[j] != 0) {
call MPI_Isend(M_local, 2, MPI_INT, j, 0, ...)
send_count++;
}
}
while (send_count) {
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, comm, status)
/* get source from status and then call recv */
MPI_Recv(M_j01, 2, MPI_INTEGER, status(MPI_SOURCE), ...)
/* Do something with M_j01 */
send_count--;
}
关于c++ - 在 for 循环中使用 MPI_Irecv 和 MPI_Isend,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49642581/
在我的程序中的某个时刻,我正在使用 MPI_Isend 来通知某个事件的所有其他进程,但其中一些进程没有监听,这很好。我已经测试了这种情况,似乎可以正常完成。 我这样做可以吗?我是否应该保留每个 Is
我无法让 MPI_Isend 发送到随机目的地。如果我对目的地进行硬编码,它工作正常,但如果我尝试生成一个随机的目的地,它就不会。这是一些相关代码: MPI_Init(&argc,&argv)
我在执行 MPI 非阻塞发送时遇到问题,它会导致机器因段错误而崩溃。所有机器都正确接收数据,但是id为0的机器在MPI_Waitall()操作过程中崩溃了。任何人都可以确定导致问题的原因吗?谢谢! 这
关于 MPI_Isend,MPI 标准说“非阻塞发送调用表示系统可能开始从发送缓冲区复制数据。在调用非阻塞发送操作后,发送方不应访问发送缓冲区的任何部分,直到发送完成。 ” ( http://www.
例如, if (rank == 0) { MPI_Isend(&sendbuf, ..., 1, ..., &request); MPI_Wait(&request, ...); /
我正在尝试从左向右发送缓冲区(0->1、1->2 2->3 等...)。我非常确定进程正在从正确的合作伙伴发送和接收,但代码挂起或输出段错误。 #include "mpi.h" #include i
我正在研究异步通信并计划实现以下例程:每个进程都拥有一个必须与之通信的进程 vector ,按升序排列。它向所有较小的 rank 发送非阻塞接收,向所有较大的 rank 发送非阻塞发送。对于除进程 0
我使用 MPI 在 4 个节点上传递了总共 8 条消息。我注意到有两条消息的数组没有提供有意义的结果。我复制了下面代码的摘录?这些是我根据以下代码/结果提出的一些相关问题: MPI_Isend 是否也
我想将不同类型的数据从一个节点发送到另一个节点。例如,我有 2 个不同类型的数据:int 和 double。但是,在我将它们发送出去之后,即使我指定了类型,接收数据的节点也会收到错误的值。从下面的示例
我的程序的目的是计算内导体和外导体之间的静电势,方法是将其分成网格,然后再分成网格切片。每个处理器获取一个切片并在每个切片上运行计算。我使用 MPI_Isend 和 MPI_Irecv 在处理器之间发
对于MPI中的异步通信,以下哪个更好(在性能、可靠性、可读性等方面): MPI_Isend with buffer 然后 MPI_Iprobe & MPI_Recv 一旦接收器准备好,或者 带缓冲区的
我正在开发一个应用程序,其中每个处理器使用 MPI_Isend 向其他一些处理器发送一堆消息,然后接收一些未知数量的消息。 在我的小示例程序(下面的代码)中,我有 4 个处理器向其余 3 个处理器中的
我有以下带有 Microsoft MPI 的 c/c++ 代码 #include #include #include "mpi.h" int main (int argc, char *argv[
我已经阅读了所有 MPI 文档和教程以及我能找到的与此相关的 Stack Overflow 问题,但我仍然不完全理解 MPI_Wait 在“完成”MPI_Isend 时的行为方式。能简单概括一下吗?是
我创建了一个数组,我想用 MPI 发送它。第一部分运行良好(我认为?)但第二部分有问题。我想这是接收部分以及我如何分配数组?请看一下: if (myrank > 1) { //first pa
我是 MPI 编程新手!我尝试测量点对点通信带宽 介于实用的处理器之间。但是现在我遇到了段错误!我不明白为什么会这样。我也在 ubuntu 上尝试过 valgrind,但是不知道。所以也许有人可以帮助
我有以下代码 int main(int argc, char* argv[]) { int rank, size; MPI_Init (&argc, &argv); MP
我想了解 MPI 如何处理发送和接收。假设我分配一个 [12][50] 元素的缓冲区,如下所示: int **buf= malloc(12 * sizeof(int *)); for (i = 0;
简单问题:由于性能要求,我需要能够在发送数据的同时进行后续计算。所以我需要使用 MPI_Isend。 这安全吗? //qtasks[][] is a 2d array and Im sending
我正在创建一个程序,其中来自数组的信息被传递到不同的处理器。在下面的代码中,我尝试使用 for 循环反复向处理器发送信息或从处理器发送信息。当我在 5 核和 2 核上运行程序时,所有打印语句都按预期在
我是一名优秀的程序员,十分优秀!