我正在尝试编写一个程序的 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);
}