MPI RMA操作:在MPI_Win_free和本地加载之间进行排序

时间:2014-01-28 10:14:53

标签: c locking mpi unlock

我正在尝试使用MPI_Win_lockMPI_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循环中并让等级0来确定何时停止环。当条件满足时,我尝试让等级0更新等级1中的标志(st)。我尝试将MPI_Win_free置于while循环之外,以便窗口仅在循环之后被释放。现在似乎我不能这样做,并且每次都需要在循环中创建和释放窗口?

1 个答案:

答案 0 :(得分:0)

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

问题是你遇到了竞争状态。当您执行MPI_PUT操作时,它会将等级0到等级1的数据发送到将来的某个时刻放入缓冲区。从0级的角度来看,你没有任何控制权。

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

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