0

当满足错误条件时,我的程序可以在某些 MPI 等级上生成错误消息。但是,可能仅在某些(但不是全部)等级上满足此条件。我想从遇到错误情况的第一个等级输出一条消息,并从其他等级中丢弃类似的消息。

如果我天真地这样做(没有丢弃消息),例如

if (error) cout << "Error on rank " << rank << endl;

我会在屏幕上得到随机排序的输出。

我想为进入该if(error)块的第一个进程锁定标准输出,这很复杂,因为并非所有进程都进入该块。这意味着,一个 MPI_Barrier() 集合不会完成。仅将所有输出发送到一个处理器并不是真正的解决方案,因为这将需要在代码中可能生成错误消息的每个位置进行同步,从而减慢程序的速度。仅出于打印消息的目的而设置空闲处理器似乎也没有吸引力(这是用于社区代码)。至少,如果有许多等级,每个等级写入一个文件也不是一种选择。

我想知道 MPI 中是否有原子机制(我在 MPI3 中读过它),以便我可以原子地更新一个处理器内存中的标志,例如通过单边通信,并且仅在出现错误消息时继续打印错误消息标志尚未设置。

恐怕这不能用标准技巧轻松完成......我是对的吗?

更新:

我想我知道该怎么做了。Wesley 的回答很接近,但也可以使用标准 MPI2 RMA 来完成,该 RMA 在大多数 MPI 实现中都可用。解决方案的关键可以在 Using MPI2 一书中的 atomic example 中找到,其代码也在 MPICH2 发行版中 (test/mpi/rma/fetchandadd.c)

以下是您如何锁定和自动递增变量(存在于 0 级):

if (error)
    {
    int one = 1;
    int flag;
    MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, 0, win);
    MPI_Accumulate(&one, 1, MPI_INT, 0, 1, MPI_INT, MPI_SUM, win);
    MPI_Get(&flag, 1, MPI_INT, 0, 0, 1, MPI_INT, win);
    MPI_Win_unlock(0, win);
    if (flag ==1) cout << "Error on rank " << rank << endl;
    }

在初始化期间的某个地方:

int error_flag = 0;
MPI_Win_create(&error_flag, sizeof(int), sizeof(int), MPI_INFO_NULL, mpi_comm, &win);

...在退出之前

MPI_Win_free(&win);
4

2 回答 2

1

你可以尝试一个MPI_COMPARE_AND_SWAP.

MPI_COMPARE_AND_SWAP(origin_addr, compare_addr, result_addr, datatype, target_rank, target_disp, win)
IN  origin_addr      initial address of buffer (choice)
IN  compare_addr     initial address of compare buffer (choice)
OUT result_addr      initial address of result buffer (choice)
IN  datatype         datatype of the element in all buffers (handle)
IN  target_rank      rank of target (non-negative integer)
IN  target_disp      displacement from start of window to beginning of target buffer (non-negative integer)
IN  win              window object (handle)

它位于MPI-3.0 标准第 430 页上(没有 3.0 标准的 HTML 版本,因此我无法直接发布指向它的链接。这样,您可以将已知值与目标值进行比较,如果它们是同样,你交换它们并取回原始值。我不是一个完全的 RMA 专家,所以我不能保证它会提供你正在寻找的那种完全同步的语义(时代有一些技巧我不是100%的),但我认为它应该适合你。

于 2013-12-03T14:58:21.927 回答
0

不要在单独的空闲进程上监听错误,而是研究在进程 0 上的空闲线程上执行相同操作的可行性。这不能保证有效(MPI 标准没有说明线程安全,但您的实现文档可能) ,但是只要您的记录器线程远离主线程的内存,我会说您的机会非常好。

于 2013-12-03T17:52:30.507 回答