MPI 中的重叠通信器和集体操作

问题描述 投票:0回答:1

这是 MPI 标准(版本 4.1)的示例。

我们有 3 个进程和 3 个通信器。标准规定

不可能对所有通信器执行阻塞集体操作,因为不存在调用它们的无死锁顺序。但是,可以轻松地使用非阻塞集体操作来实现此任务。

并提供此代码片段

MPI_Request reqs[2];

switch(rank) {
  case 0:
    MPI_Iallreduce(sbuf1, rbuf1, count, dtype, MPI_SUM, comm1, &reqs[0]);
    MPI_Iallreduce(sbuf3, rbuf3, count, dtype, MPI_SUM, comm3, &reqs[1]);
    break;
  case 1:
    MPI_Iallreduce(sbuf1, rbuf1, count, dtype, MPI_SUM, comm1, &reqs[0]);
    MPI_Iallreduce(sbuf2, rbuf2, count, dtype, MPI_SUM, comm2, &reqs[1]);
    break;
  case 2:
    MPI_Iallreduce(sbuf2, rbuf2, count, dtype, MPI_SUM, comm2, &reqs[0]);
    MPI_Iallreduce(sbuf3, rbuf3, count, dtype, MPI_SUM, comm3, &reqs[1]);
    break;
}
MPI_Waitall(2, reqs, MPI_STATUSES_IGNORE);

我在同一代码片段的阻塞版本中没有看到死锁,即在

switch(rank) {
  case 0:
    MPI_Allreduce(sbuf1, rbuf1, count, dtype, MPI_SUM, comm1);
    MPI_Allreduce(sbuf3, rbuf3, count, dtype, MPI_SUM, comm3);
    break;
  case 1:
    MPI_Allreduce(sbuf1, rbuf1, count, dtype, MPI_SUM, comm1);
    MPI_Allreduce(sbuf2, rbuf2, count, dtype, MPI_SUM, comm2);
    break;
  case 2:
    MPI_Allreduce(sbuf2, rbuf2, count, dtype, MPI_SUM, comm2);
    MPI_Allreduce(sbuf3, rbuf3, count, dtype, MPI_SUM, comm3);
    break;
}

所以时序图大约是

我错过了什么吗?也许“僵局”标准并不意味着完全停滞。

根据维基百科

如果一个进程保持无限期地无法更改其状态,因为它请求的资源正在被本身正在等待的另一个进程使用,则系统被认为处于死锁状态。

(我强调)

mpi
1个回答
0
投票

该标准意味着不能保证这是无死锁的,并且假设是这样是一个不正确的程序。

但是,MPI 实现可能在幕后执行非阻塞操作,这样是可行的,但假设该行为不符合标准,并且不能保证其他一些 MPI 实现将起作用或更复杂的示例将起作用。

© www.soinside.com 2019 - 2024. All rights reserved.