Parallel processing MPI奇偶比较分割死锁

Parallel processing MPI奇偶比较分割死锁,parallel-processing,deadlock,mpi,Parallel Processing,Deadlock,Mpi,我正在尝试编写一个程序的MPI版本,该程序在n个随机生成的元素上运行奇偶比较拆分操作 进程0应生成元素并将元素的nlocal发送给其他进程(保留第一个nlocal)。从这里开始,进程0应在运行CompareSplit算法后打印其结果。然后,从算法运行的其他进程接收结果。最后,打印出刚刚收到的结果 我已经做了大量的工作,但是我遇到了一个似乎无法解决的僵局。如果人们能给我任何提示,我将不胜感激 这是我的密码 现在我很确定死锁来自第134行和第151行的Send/Recv。我尝试将发送更改为使用“ta

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

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

我已经做了大量的工作,但是我遇到了一个似乎无法解决的僵局。如果人们能给我任何提示,我将不胜感激

这是我的密码

现在我很确定死锁来自第134行和第151行的Send/Recv。我尝试将发送更改为使用“tag”而不是myrank作为标记参数。但是,当我这样做时,出于某种原因,我一直得到一个“MPI\u ERR\u tag:invalid tag”

显然,我也会在处理器>0的范围内运行算法,但我现在就把这部分去掉了,直到我弄清楚出了什么问题

感谢您的帮助

EDIT:我编写了一个较小的测试用例,它不包含任何CompareSplit操作,但仍然是死锁

通过将第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);
}

for(i=1;i看起来您正在调用
MPI\u Sendrecv
[第113行],但没有进程使用
oddrank
rank来回答它,因为
oddrank eq-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的接收是NOOP,发送到进程1的接收将永远不会被应答,因为进程1没有执行相同的操作


我认为您需要将算法的这一部分移到if(rank==0)之外
test.

感谢您花时间查看我的程序。我知道处理器0的oddrank将比时间早-1,我已经添加了一些时间来解决这个问题。请看第109行,oddrank=MPI\u PROC\u NULL;这已经停止了您所指的问题。我很抱歉没有更好地评论这一行。同样,请注意e在原始Post中编辑所以它看起来是evenrank MPI_Sendrecv,知道为什么吗?好的,我希望进程0也参与到算法中,这就是为什么我在if中有那个块(rank==0)。所以我希望每个进程在它们的nlocal元素上运行CompareSplit。我将尝试将算法移到if之外(rank==0)按照您所说的进行测试,看看会发生什么。谢谢。您是说这样的吗?因为这对我来说没有意义,因为我们应该在运行CompareSplit之后将结果发送回进程0。另外,进程0不必自己发送/接收。