【问题标题】:MPI (Asynchronous) Loop IterationMPI(异步)循环迭代
【发布时间】:2014-06-15 19:42:06
【问题描述】:

我有一个类似于下面的程序。在下面的代码中,所有进程都知道所有其他进程的当前迭代步骤。但是,我很好奇是否有一种方法可以在没有诸如 MPI_PUT 之类的集体调用的情况下做到这一点,尤其是在每个进程以不同速率迭代的情况下

#include <errno.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>


/* OUTPUT
 * $ mpirun -np 4 so00.exe
 * @[0]: p |       0       1       2       3
 * @[0]: p |       4       5       6       7
 * @[0]: p |       8       9       10      11
 * @[0]: p |       12      13      14      15
 * @[0]: p |       16      17      18      19
 * @[1]: p |       0       1       2       3
 * @[1]: p |       4       5       6       7
 * @[1]: p |       8       9       10      11
 * @[1]: p |       12      13      14      15
 * @[1]: p |       16      17      18      19
 * @[2]: p |       0       1       2       3
 * @[2]: p |       4       5       6       7
 * @[2]: p |       8       9       10      11
 * @[2]: p |       12      13      14      15
 * @[2]: p |       16      17      18      19
 * @[3]: p |       0       1       2       3
 * @[3]: p |       4       5       6       7
 * @[3]: p |       8       9       10      11
 * @[3]: p |       12      13      14      15
 * @[3]: p |       16      17      18      19
 */
int main(int argc, char *argv[])
{
    int i, n, rank, np;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &np);

    ////////////////////////////////////////////////////////////////////////////

    int *pos;
    MPI_Win win;
    MPI_Alloc_mem(sizeof(int)*np, MPI_INFO_NULL, &pos);
    MPI_Win_create(pos, np, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);

    for (i=rank; i<(np*5); i+=np)
    {
        MPI_Win_fence(MPI_MODE_NOPRECEDE, win);
        for (n = 0; n < np; n++)
        {
            MPI_Put(&i, 1, MPI_INT, n, rank, 1, MPI_INT, win);
        }
        MPI_Win_fence((MPI_MODE_NOSTORE | MPI_MODE_NOSUCCEED), win);
        printf("@[%d]: p | ", rank);
        for (n = 0; n < np; n++) printf("\t%d", pos[n]);
        printf("\n");
    }

    ////////////////////////////////////////////////////////////////////////////

    MPI_Win_free(&win);
    MPI_Free_mem(pos);

    MPI_Finalize();

    return EXIT_SUCCESS;
}

【问题讨论】:

  • MPI_Put 不是集体调用。
  • 啊,我想我把它和 MPI_Win_fence 搞混了...
  • 在使用 RMA 调用之前,您无法避免 MPI_Win_fence。它是一个要求。您可以通过将栅栏移出外部 for 循环来优化代码。现在的方式,NOPRECEDE 和 NOSUCCEED 在当前位置是不合适的。
  • 非常感谢您的帮助。我将栅栏移到了循环之外,得到了如下数字:@[0]: p | -1698087256 32723 -1698087256 32723 32。我用这篇文章stackoverflow.com/questions/6612421/… 中的解决方案解决了这种情况。不过,我很好奇是否还有其他方法可以使用 RMA 或其他技巧来做到这一点。再次感谢。
  • 如果我将进程放在一个单独的 MPI 组中,有没有办法修改窗口、组或通信器句柄或所有它们,这样,当一个完成循环时,它会删除本身来自与窗口关联的组??

标签: c asynchronous mpi


【解决方案1】:

您不必使用MPI_Win_fence 在 MPI 中同步 RMA 调用。也可以使用MPI_Lock(及其变体)来执行所谓的“被动目标”模式。这种模式的同步性要低得多,因为它不需要“活动目标”模式所做的所有集体调用。

在这里提供完整答案太复杂了,但是您可以在网络上找到许多关于该主题的论文以及文档。完整的 MPI-3 标准可在here 获得。请看第 11 章,了解片面沟通。

【讨论】:

    猜你喜欢
    • 2013-08-04
    • 2014-07-04
    • 2018-07-09
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 2018-10-17
    • 2015-08-11
    相关资源
    最近更新 更多