如何检查非阻塞减少的完成?

蟒蛇152

我不清楚如何在 MPI 中正确使用非阻塞集合,特别是MPI_Ireduce()在这种情况下:

假设我想从根等级收集总和:

int local_cnt;
int total_cnt;
MPI_Request request;
MPI_Ireduce(&local_cnt, &total_cnt, 1, MPI_INT, MPI_SUM, 0, MPI_WORLD_COMM, &request);

/* now I want to check if the reduce is finished */

if (rank == 0) {
    int flag = 0;
    MPI_Status status;
    MPI_Test(&request, &flag, &status);
    if (flag) {
        /* reduce is finished? */
    }
}

这是检查非阻塞减少是否完成的正确方法吗?我的困惑来自两个方面:一,可以还是应该只使用 root 进程检查它,MPI_Test()因为这仅对 root 有意义?第二,既然MPI_Test()是local op,这个local op怎么知道操作完成了?它确实需要完成所有过程,对吗?

Zulan

您必须检查所有参与等级的完成情况,而不仅仅是根。

从用户的角度来看,您需要了解通信的完成情况,因为您不得对提供给非阻塞操作的内存进行任何操作。即,如果您发送一个局部作用域变量,如local_cnt,则在确认操作完成之前,您不能写入它或离开它的作用域。

确保完成的一种选择是调用MPI_Test直到它最终返回flag==true仅当您可以在调用之间做一些有用的事情时才使用它MPI_Test

{
    int local_cnt;
    int total_cnt;

    // fill local_cnt on all ranks

    MPI_Request request;
    MPI_Ireduce(&local_cnt, &total_cnt, 1, MPI_INT, MPI_SUM, 0, MPI_WORLD_COMM, &request);

    int flag;
    do {

        // perform some useful computation
        MPI_Status status;
        MPI_Test(&request, &flag, &status);
    } while (!flag)
}

MPI_Test如果在调用之间没有任何有用的事情可做,请不要循环调用。而是使用MPI_Wait, 阻塞直到完成。

{
    int local_cnt;
    int total_cnt;

    // fill local_cnt on all ranks

    MPI_Request request;
    MPI_Ireduce(&local_cnt, &total_cnt, 1, MPI_INT, MPI_SUM, 0, MPI_WORLD_COMM, &request);

    // perform some useful computation
    MPI_Status status;
    MPI_Wait(&request, &status);
}

请记住,如果您根本没有有用的计算,并且由于死锁原因不需要非阻塞,请首先使用阻塞通信。如果您有多个正在进行的非阻塞通信,有MPI_WaitanyMPI_WaitsomeMPI_Waitall和他们的测试变种的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章