【发布时间】:2014-05-29 03:00:46
【问题描述】:
我正在尝试并行生成导数矩阵。我有整个热方程求解器使用两个线程,但现在我试图找出如何将底行发送到下一个级别的 rec2,将顶行发送到前一个级别的 rec1。我试着用请求矩阵中的数字鬼混,但没有任何效果。出于某种原因,有人告诉我,使用 iSend 时,两个不同的接收是相同的请求。
任何解决此问题或帮助我更好地理解此问题的建议都会很棒。
double** change = alloc(sizeX,sizeY);
double* rec1;
double* rec2;
int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Request req[4];
if(rank != 0)
{
rec1 = calloc(sizeY,sizeof(double));
}
if(rank != size-1)
{
rec2 = calloc(sizeY,sizeof(double));
}
if ( rank == 0 )
{
MPI_Irecv(rec2, sizeY, MPI_DOUBLE, rank+1, 1244, MPI_COMM_WORLD, &req[1]);
MPI_Isend(u[sizeX-1], sizeY, MPI_DOUBLE, rank+1, 1244, MPI_COMM_WORLD, &req[0]);
}
else if ( rank == size-1 )
{
MPI_Irecv(rec1, sizeY, MPI_DOUBLE, rank - 1, 1244, MPI_COMM_WORLD, &req[2]);
MPI_Isend(u[0], sizeY, MPI_DOUBLE, rank - 1, 1244, MPI_COMM_WORLD, &req[3]);
}
else if ( rank != 0 && rank != size -1)
{
MPI_Irecv(rec1, sizeY, MPI_DOUBLE, rank-1, 1234, MPI_COMM_WORLD, &req[1]);
MPI_Isend(u[0], sizeY, MPI_DOUBLE, rank-1, 1234, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(rec2, sizeY, MPI_DOUBLE, rank+1, 1234, MPI_COMM_WORLD, &req[2]);
MPI_Isend(u[sizeX-1], sizeY, MPI_DOUBLE, rank+1, 1234, MPI_COMM_WORLD, &req[3]);
}
// setting elements of most of the points
int xStart = 1;
int xBound = sizeX-1;
for(int x = xStart; x < xBound; x++)
{
for(int y = 1; y < sizeY-1; y++)
{
change[x][y] = fpp(u[x-1][y],u[x][y],u[x+1][y],dx)
+ fpp(u[x][y-1],u[x][y],u[x][y+1],dx);
}
}
MPI_Waitall(size+1,req,MPI_STATUSES_IGNORE );
【问题讨论】:
-
观看请求数量及其开始! rank 0 和 rank
size-1处理 2 条消息,而其他处理 4。这可能会导致MPI_Waitall()出现问题。而ranksize-1没有初始化 req[0] 和 req[1] ! -
线程是指进程?他们安静不同。
-
@francis 是非常正确的 - 您在请求数组中使用的索引和元素数量不一致,因此等待已注定。我最喜欢的方法是在每个发布的请求中通过,例如,
&req[reqcnt++],最后调用MPI_Waitall(reqcnt, req...。 -
您还可以通过定义来简化代码,例如
left = (rank > 0? rank - 1 : MPI_PROC_NULL);和right = (rank < size-1? rank + 1 : MPI_PROC_NULL),然后只使用最后一个elseif 正文并使用left和right而不是@987654331 删除其余部分@。上面的 waitall 应该可以工作,但代码将被简化,以减少重复(未来错误的来源)。