0

我正在尝试编写一个程序的 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”来修复上述测试用例。好吧,测试用例可以工作,但是当像我的程序一样添加实际算法时,它会死锁..

所以,我想我已经将僵局缩小到这段代码。它看起来是else下的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);
}
4

2 回答 2

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(偶数秩)和 MPI_NULL_PROC(奇数秩)。但是到 evenrank 的发送接收是 noops,并且发送到进程 1 的接收将永远不会被回答,因为进程 1 没有做同样的事情。

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

于 2012-04-07T15:26:09.477 回答
0

看起来您正在调用MPI_Sendrecv[第 113 行],但没有具有oddrank等级的进程来回答它,因为oddrank eq -1.

于 2012-04-07T05:23:37.493 回答