当满足错误条件时,我的程序可以在某些 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);