【问题标题】:Wrong synchronization of RMA calls in MPIMPI 中 RMA 调用的错误同步
【发布时间】:2021-05-01 12:29:16
【问题描述】:

我正在尝试使用 Fences 进行 MPI RMA 计划。在某些情况下它可以正常工作,但对于具有多个节点的系统,我会收到以下错误:

Error message: MPI failed with Error_code = 71950898
Wrong synchronization of RMA calls , error stack:
MPI_Rget(176): MPI_Rget(origin_addr=0x2ac7b10, origin_count=1, MPI_INTEGER, target_rank=0, target_disp=0, target_count=1, MPI_INTEGER, win=0xa0000000, request=0x7ffdc1efe634) failed
(unknown)(): Wrong synchronization of RMA calls
Error from PE:0/4

这是我如何设置代码的示意图:

call MPI_init(..)
CALL MPI_WIN_CREATE(..)
do i =1,10
   MPI_Win_fence(0, handle, err)

   calc_values()
   MPI_Put(values)
   MPI_Put(values)
   MPI_Put(values)

   MPI_Win_fence(0, handle, err)

   MPI_Rget(values, req)
   MPI_WAIT(req)
   do_something(values)

   MPI_Rget(values, req)
   MPI_WAIT(req)
   do_something(values)
enddo
call MPI_finalize()

我知道MPI_Put 是非阻塞的。是否保证 MPI_Put 在 MPI_Win_fence(0, handle, err) 之后完成,还是我必须使用 MPI_RPUT?

这个错误甚至意味着什么:Wrong synchronization of RMA calls?

如何修复我的通信方案?

【问题讨论】:

  • 我从来没有在愤怒中使用过 Rput / Rget 函数,所以这是一个猜测。但是,我认为这可能是因为标准规定在等待“如果 origin_addr 指向附加到窗口的内存,则数据在此窗口的私有副本中可用”。这意味着公共副本可能不会更新,这可能会导致后续调用 Rget 出现问题。您是将 get 的结果放入窗口还是仅放入本地内存?我认为像使用 Put 一样使用 Get 并完成调用会简单得多,即使用栅栏。
  • 我不认为我之前的评论是正确的 - 同步问题实际上是私有副本中可能无法提供对公共副本的更新,但这正是 i> 由等待保证。我仍然认为使用 MPI_Get 和栅栏可能值得一试。
  • 不要将基于请求的 RMA 与被动目标同步以外的任何内容一起使用。否则没有任何意义。我是这些函数在 MPI-3 中的原因,所以我知道它们的预期用途;-)

标签: mpi


【解决方案1】:

确保根据需要添加以下调用以确保同步(您需要确保在将数据放入窗口之前创建窗口):

MPI_Win_fence(0, window);

请查看下面的示例 (source) 并注意他们正在进行两次围栏调用。

    // Create the window
    int window_buffer = 0;
    MPI_Win window;
    MPI_Win_create(&window_buffer, sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &window);
    if(my_rank == 1)
    {
        printf("[MPI process 1] Value in my window_buffer before MPI_Put: %d.\n", window_buffer);
    }
    MPI_Win_fence(0, window);
 
    if(my_rank == 0)
    {
        // Push my value into the first integer in MPI process 1 window
        int my_value = 12345;
        MPI_Put(&my_value, 1, MPI_INT, 1, 0, 1, MPI_INT, window);
        printf("[MPI process 0] I put data %d in MPI process 1 window via MPI_Put.\n", my_value);
    }
 
    // Wait for the MPI_Put issued to complete before going any further
    MPI_Win_fence(0, window);
 
    if(my_rank == 1)
    {
        printf("[MPI process 1] Value in my window_buffer after MPI_Put: %d.\n", window_buffer);
    }
 
    // Destroy the window
    MPI_Win_free(&window);

【讨论】:

    猜你喜欢
    • 2013-09-15
    • 2021-09-29
    • 2012-06-18
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2010-12-03
    • 2012-05-11
    相关资源
    最近更新 更多