【问题标题】:MPI RMA operation: Ordering between MPI_Win_free and local loadMPI RMA 操作:在 MPI_Win_free 和本地负载之间排序
【发布时间】:2014-01-29 01:08:03
【问题描述】:

我正在尝试使用MPI_Win_lock 和MPI_Win_unlock 对MPI 的RMA 操作进行简单测试。程序只是让进程0更新进程1中的整数值并显示出来。

下面的程序运行正确(至少结果对我来说是正确的):

#include "mpi.h"
#include "stdio.h"
#define root 0

int main(int argc, char *argv[])
{
  int myrank, nprocs;
  int send, recv, err;
  MPI_Win nwin;
  int *st;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

  MPI_Alloc_mem(1*sizeof(int), MPI_INFO_NULL, &st);

  st[0] = 0;
  if (myrank != root) {
    MPI_Win_create(st, 1*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &nwin);
  }
  else {
    MPI_Win_create(NULL, 0, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &nwin);
  }

  if (myrank == root) {
    st[0] = 1;
    MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 1, 0, nwin);
    MPI_Put(st, 1, MPI_INT, 1, 0, 1, MPI_INT, nwin);
    MPI_Win_unlock(1, nwin);
    MPI_Win_free(&nwin);
  }
  else { // rank 1
    MPI_Win_free(&nwin);
    printf("Rank %d, st = %d\n", myrank, st[0]);
  }

  MPI_Free_mem(st);
  MPI_Finalize();
  return 0;
}

我得到的输出是Rank 1, st = 1。但奇怪的是,如果我将 else 块中 1 级的行切换到

  else { // rank 1
    printf("Rank %d, st = %d\n", myrank, st[0]);
    MPI_Win_free(&nwin);
  }

输出为Rank 1, st = 0。

我找不到它背后的原因,以及为什么我需要在加载数据后放入MPI_Win_free,原来我需要将所有东西放在一个while循环中,让rank 0来确定何时停止循环。当条件满足时,我尝试让 rank 0 更新 rank 1 中的标志 (st)。我尝试将 MPI_Win_free 放在 while 循环之外,这样窗口只会在循环后被释放。现在看来我无法做到这一点,需要每次在循环中创建和释放窗口?

【问题讨论】:

标签: c locking mpi unlock


【解决方案1】:

说实话,MPI RMA 不是我的专长,但我会试一试:

问题是您遇到了竞争状况。当您执行MPI_PUT 操作时,它会将数据从 rank 0 发送到 rank 1,以便在将来的某个时间点放入缓冲区。从 0 级的角度来看,你无法控制它。

一个等级1的一方,你没有做任何事情来完成操作。我知道 RMA(或单方面操作)听起来好像它们不需要对目标方进行任何干预,但确实需要一点。当您使用单面操作时,您必须在接收端有一些东西来同步数据。在这种情况下,您尝试将 MPI put/get 操作与非 MPI 加载存储操作结合使用。这是错误的,会导致您看到的竞争条件。当您将MPI_WIN_FREE 切换为第一个时,您完成了所有未完成的操作,因此您的数据是正确的。

您可以通过以下问题了解更多关于被动目标同步(这就是您在这里所做的)的信息:MPI with C: Passive RMA synchronization。

【讨论】:

  • 根据MPI标准(§11.4.3, p.357),Put操作应该在MPI_Win_lock返回时完成,所以原因可能不在窗口上。 Example 11.12 Rule 6 (p.367) 实际上显示了类似的情况。 “棘手”的一点是 MPI_Barrier 的使用,它试图保证执行顺序。我在下面修改了我的代码,它以某种方式工作:
  • 对,但问题是排名 1 的时间不够长,无法接收在打印值时已经输出的数据。当您首先获得空闲时,您强制它同步,因为它是对窗口中所有进程的集体调用。
猜你喜欢
  • 1970-01-01
  • 2021-09-29
  • 2022-07-06
  • 2021-06-28
  • 2013-09-15
  • 1970-01-01
  • 2016-11-19
  • 2022-01-01
  • 2023-02-06
相关资源
最近更新 更多