MPI奇数/偶数比较 - 分裂死锁

时间:2012-04-07 03:19:45

标签: parallel-processing deadlock mpi

我正在尝试编写一个程序的MPI版本,该程序在n个随机生成的元素上运行奇数/偶数比较分割操作。

进程0应该生成元素并将它们的nlocal发送给其他进程,(保留第一个nlocal本身)。从这里开始,进程0应该在运行CompareSplit算法后打印出它的结果。然后,从算法运行的其他进程接收结果。最后,打印出刚刚收到的结果。

我已经完成了很大一部分工作,但是我遇到了一个我似乎无法修复的僵局。我非常感谢人们给我的任何暗示。

这是我的代码http://pastie.org/3742474

现在我很确定死锁来自第134和151行的发送/接收。我已经尝试将标记参数更改为发送使用“标记”而不是myrank。但是当我这样做我只是因为某种原因继续得到“MPI_ERR_TAG:无效标签”。

显然我也会在处理器中运行算法> 0但我暂时把这部分拿出来,直到我弄清楚出了什么问题。

感谢任何帮助。

编辑:我编写了一个较小的测试用例,它不包含任何CompareSplit操作,但仍然是死锁。 http://pastie.org/3744691

我通过将第83行的标记从“myrank”更改为“tag”来修复上述测试用例。 那么测试用例是可行的,但是当我的程序中添加了实际的算法时,它会死锁..

所以,我认为我已经将僵局缩小到这段代码。 它看起来像是其他的Sendrecv。

for (i = 1; i <= npes; i++) {
    if (i % 2 == 1) // odd phase
      MPI_Sendrecv(elmnts, nlocal, MPI_INT, oddrank, 1, relmnts,
                           nlocal, MPI_INT, oddrank, 1, MPI_COMM_WORLD, &status);
    else
      MPI_Sendrecv(elmnts, nlocal, MPI_INT, evenrank, 1, relmnts,
                           nlocal, MPI_INT, evenrank, 1, MPI_COMM_WORLD, &status);

    CompareSplit(nlocal, elmnts, relmnts, wspace,
                 myrank < status.MPI_SOURCE);
}

2 个答案:

答案 0 :(得分:1)

标记错误是因为标记必须是正整数,范围从1到某个依赖于实现的最大值,保证至少为32k。

僵局很容易理解;看看非等级零流程在做什么:

  else {
    // The rest of the processes
    // Receive nlocal randomly generated elements from process 0
    MPI_Recv(elmnts, nlocal, MPI_INT, 0, tag, comm, &status);

    qsort(elmnts, nlocal, sizeof(int), IncOrder); // does it matter where we sort at?

    // Send results back to process 0
    MPI_Send(elmnts, nlocal, MPI_INT, 0, myrank, comm);
  }

所以他们正在做一次接收,一次发回。但处理器0的功能远不止于此;它向每个人发送他们的数据,然后执行一堆发送 - 接收到进程1(evenrank)和MPI_NULL_PROC(oddrank)。但是发送 - 接收到evenrank是noops,并且进程1的发送 - 接收将永远不会被回答,因为进程1没有做同样的事情。

我认为你需要将算法的那部分移到if (rank == 0)测试之外。

答案 1 :(得分:0)

看起来您正在调用MPI_Sendrecv [第113行],但没有oddrank排名的流程可以回答它,因为oddrank eq -1