MPI坚持不懈地打电话

时间:2017-07-01 17:41:54

标签: c mpi

我正在尝试实现某种形式的持久调用。不知怎的,下面的代码一直悬而未决 - 我猜想我必须引入一个僵局,但却无法真正解开它...

MPI_Request r[4];
[...]
MPI_Send_init(&Arr[1][1], 1, MPI_DOUBLE, 1, A, MPI_COMM_WORLD, &r[0]);
MPI_Recv_init(&Arr[1][0], 1, MPI_DOUBLE, 0, A, MPI_COMM_WORLD, &r[1]);

MPI_Send_init(&Arr[2][1], 1, MPI_DOUBLE, 0, B, MPI_COMM_WORLD, &r[2]);
MPI_Recv_init(&Arr[2][0], 1, MPI_DOUBLE, 1, B, MPI_COMM_WORLD, &r[3]);
[...]
MPI_Startall(4, r);
MPI_Waitall(4, r, MPI_STATUSES_IGNORE);

我认为这是死锁的完美材料 - 如果我想初始化这些发送/接收消息并稍后只使用StartallWaitall调用这些进程,那么这将是什么补救措施?

编辑:所以如果我这样做

MPI_Start(&r[0]);
MPI_Wait(&r[0], &status):

然后它不会挂起。调用类似的东西:

for (int k=0; k<1; k++)
  {
    MPI_Start(&r[k]);
    MPI_Wait(&r[k], &status);
  }

失败并挂起。如果有帮助

2 个答案:

答案 0 :(得分:1)

您的代码不匹配。

例如,排名0从标签为A的标签中收到 但它会使用标记B

发送给自己

答案 1 :(得分:0)

我必须承认我不熟悉MPI请求的概念和 MPI_Send / Recv_init 。但是,我可以通过简单的发送和接收来重现死锁。这是代码(它有一个死锁):

double someVal = 3.5;
const int MY_FIRST_TAG = 42;
MPI_Send(&someVal, 1, MPI_DOUBLE, 1, MY_FIRST_TAG, MPI_COMM_WORLD);
MPI_Recv(&someVal, 1, MPI_DOUBLE, 0, MY_FIRST_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

即使只使用两个进程运行它,问题如下:进程0和1都向进程1发送消息。然后两个进程都希望从进程0接收消息。进程1可以因为进程零实际上是向进程1发送了一条消息。但没有人发送消息进行处理0.因此,这个进程将永远等待。

如何修复:您需要指定只有进程0发送到进程1,并且只有进程1应该从进程0接收。您只需执行以下操作:

int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
    MPI_Send(&someVal, 1, MPI_DOUBLE, 1, MY_FIRST_TAG, MPI_COMM_WORLD);
else // Assumption: Only two processes
    MPI_Recv(&someVal, 1, MPI_DOUBLE, 0, MY_FIRST_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

我并非100%确定如何将此转换为请求的概念以及 MPI_Send / Recv_init ,但这可能会对您有所帮助。