MPI_Irecv和MPI_Isend操作返回一个MPI_Request,该MPI_Request稍后可以被标记为用MPI_Cancel取消。是否有类似的机制来阻止MPI_Probe和MPI_Mprobe?
问题的上下文是使用探测的Boost.MPI请求处理程序的最新实现。
编辑-下面是如何使用假想的MPI_Probecancel的示例:
#include <mpi.h>
#include <chrono>
#include <future>
using namespace std::literals::chrono_literals;
// Executed in a thread
void async_cancel(MPI_Probe *probe)
{
std::this_thread::sleep_for(1s);
int res = MPI_Probecancel(probe);
}
int main(int argc, char* argv[])
{
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
if (rank == 0)
{
// A handle to the probe (similar to a request)
MPI_Probe probe;
// Start a thread
// `probe` will be filled with the next call, pretty ugly
// Ideally, this should be done in two steps like MPI_Irecv, MPI_Wait
auto res = std::async(std::launch::async, &async_cancel, &probe);
MPI_Message message;
MPI_Status status;
MPI_MProbe(1, 123, MPI_COMM_WORLD, &message, &status, &probe);
if (!probe.cancelled)
{
int buffer;
MPI_Mrecv(&buffer, 1, MPI_INT, &message, &status);
}
}
else
std::this_thread::sleep_for(2s);
MPI_Finalize();
return 0;
}发布于 2019-11-19 19:52:18
首先,你的问题的前提/命名是错误的。这是非阻塞调用。MPI_Irecv和MPI_Isend,它们返回一个您可以取消的请求对象。对于这些调用,您将取消本地操作。
MPI_Probe和MPI_Mprobe实际上是阻塞。您不可能取消这些操作,因为只有当消息可用时,控制流才会离开。
另一方面,MPI_Iprobe和MPI_Improbe是MPI_Iprobe,这意味着它们总是立即完成,告诉您消息是否可用。
对于任何一种探测呼叫,在完成后都会有任何一种局部状态。因此,在函数返回后,没有任何东西可以在本地取消。
也就是说,如果探测器告诉您消息是可用的,那么您肯定会收到它。否则,发送操作可能会阻塞,而您将泄漏所有侧的资源。但那只是一个接收操作。
编辑:关于取消并发线程中正在进行的本地MPI_Probe的想法:这是不直接支持的。
理论上,您可以通过在MPI_THREAD_MULTIPE上运行探测,并从另一个线程向相同级别发送消息,从而在符合MPI_ANY_SOURCE的实现上进行仿真。当然,这样做的后果是,您必须对来自任何新来的级别的消息进行调查。
实际上,如果您必须这样做,您可能只需要使用像while(!cancelled) MPI_Iprobe();这样的循环。
尽管如此,我还要再次质疑这种情况:您级别的另一个线程怎么会突然知道取消本地MPI_Probe操作呢?它可能必须以从远程级别收到的信息为基础-在这种情况下,实际能够从远程级别接收信息,即实际的探测将完成。
也许对于一些高级抽象来说,提供本地取消是有意义的,但在实际情况下,我相信您可以设计一个不需要这样的习惯模式。
https://stackoverflow.com/questions/58938736
复制相似问题