c++ - boost::mpi 在具有相同标签的多个 isend/irecv 传输中抛出 MPI_ERR_TRUNCATE

标签 c++ boost mpi boost-mpl

当使用序列化数据对同一标签执行多个 isend/irecv 传输时,我发现 boost::mpi 出现了 MPI_ERR_TRUNCATE 错误。这些不是并发传输,即不涉及线程。同时只有不止一项未完成的转账。这是一个显示失败的简短测试程序:

#include <iostream>
#include <string>
#include <vector>
#include <boost/mpi.hpp>
#include <boost/serialization/string.hpp>

static const size_t N = 2;

int main() {
   boost::mpi::environment env;
   boost::mpi::communicator world;

#if 1
   // Serialized types fail.
   typedef std::string DataType;
#define SEND_VALUE "how now brown cow"
#else
   // Native MPI types succeed.
   typedef int DataType;
#define SEND_VALUE 42
#endif

   DataType out(SEND_VALUE);
   std::vector<DataType> in(N);
   std::vector<boost::mpi::request> sends;
   std::vector<boost::mpi::request> recvs;
   sends.reserve(N);
   recvs.reserve(N);

   std::cout << "Multiple transfers with different tags\n";
   sends.clear();
   recvs.clear();
   for (size_t i = 0; i < N; ++i) {
      sends.push_back(world.isend(0, i, out));
      recvs.push_back(world.irecv(0, i, in[i]));
   }
   boost::mpi::wait_all(sends.begin(), sends.end());
   boost::mpi::wait_all(recvs.begin(), recvs.end());

   std::cout << "Multiple transfers with same tags\n";
   sends.clear();
   recvs.clear();
   for (size_t i = 0; i < N; ++i) {
      sends.push_back(world.isend(0, 0, out));
      recvs.push_back(world.irecv(0, 0, in[i]));
   }
   boost::mpi::wait_all(sends.begin(), sends.end());
   boost::mpi::wait_all(recvs.begin(), recvs.end());

   return 0;
}

在这个程序中,我首先在不同的标签上进行了 2 次传输,效果很好。然后我尝试在同一个标​​签上进行 2 次传输,但失败了:

libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl >: MPI_Unpack: MPI_ERR_TRUNCATE: message truncated

如果我使用 native MPI 数据类型以便不调用序列化,一切似乎都有效。我在使用 OpenMPI 1.7.3 的 MacPorts boost 1.55 和使用 OpenMPI 1.4.5 的 Debian boost 1.49 上遇到了同样的错误。我直接使用 API C 接口(interface)尝试使用相同标签进行多次传输,这似乎有效,但我当然只能传输 native MPI 数据类型。

我的问题是在同一个标​​签上进行多个未完成的传输是否是 boost::mpi 的有效操作,如果是这样,我的程序是否存在错误或 boost 是否存在错误::mpi?

最佳答案

在当前的 boost 版本 1.55 中,boost::mpi 不保证非超车消息。这与底层 MPI API which does 形成对比:

Order Messages are non-overtaking: If a sender sends two messages in succession to the same destination, and both match the same receive, then this operation cannot receive the second message if the first one is still pending. If a receiver posts two receives in succession, and both match the same message, then the second receive operation cannot be satisfied by this message, if the first one is still pending. This requirement facilitates matching of sends to receives. It guarantees that message-passing code is deterministic, if processes are single-threaded and the wildcard MPI_ANY_SOURCE is not used in receives.

boost::mpi 不保证不超车的原因是序列化数据类型在两个 MPI 消息中传输,一个用于大小,一个用于负载,以及 irecv 在检查第一条消息之前,不能发布第二条消息。

正在考虑在 boost::mpi 中保证不超车的提议。进一步的讨论可以在 boost::mpi 邮件列表开始 here 找到.

关于c++ - boost::mpi 在具有相同标签的多个 isend/irecv 传输中抛出 MPI_ERR_TRUNCATE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21889426/

相关文章:

c++ - 如何在 Boost/C++ 实现中控制线程池

mpi - OpenMDAO1+ : variable trees in parallel

在eclipse juno中使用mingw和MPICH2编译MPI程序

c++ - GLFW,使用 glClear 距屏幕左上角的奇数偏移

python - 使用默认参数将特定参数传递给 Boost Python 函数

c++ - 是否有一种可移植/符合标准的方法来获取堆栈跟踪中的文件名和行号?

c++ - 使用自定义时区将 boost::posix_time::ptime 转换为字符串

parallel-processing - 如何在 MPI 中发送没有特定目的地的消息?

c++ - 尝试将 std::cerr 重定向到文件时出现访问冲突异常

c++ - 用于多线程应用程序的 GCOV