【发布时间】:2014-03-20 07:28:00
【问题描述】:
在使用序列化数据执行具有相同标签的多个 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: 以 boost::exception_detail::clone_impl 类型的未捕获异常终止 >: MPI_Unpack: MPI_ERR_TRUNCATE: 消息被截断
如果我使用本机 MPI 数据类型以便不调用序列化,那么一切似乎都有效。我在使用 OpenMPI 1.7.3 的 MacPorts boost 1.55 和使用 OpenMPI 1.4.5 的 Debian boost 1.49 上遇到了同样的错误。我尝试了直接使用 API C 接口使用相同标签进行多次传输,并且似乎可以正常工作,当然我只能传输本机 MPI 数据类型。
我的问题是,在同一个标签上有多个未完成的传输是否是对boost::mpi 的有效操作,如果是这样,我的程序中是否存在错误或boost::mpi 中的错误?
【问题讨论】: