我试图通过MPI与不同大小的std::vector<MyClass>
进行通信。 MyClass
包含可能未初始化或大小不同的矢量的成员。为此,我写了一个serialize()
和deserialize()
函数,读写这样的std::vector<MyClass>
到std::string
,然后我通过MPI进行通信。使用MPI将对象的向量序列化为std :: string
class MyClass {
...
int some_int_member;
std::vector<float> some_vector_member;
}
std::vector<MyClass> deserialize(const std::string &in) {
std::istringstream iss(in);
size_t total_size;
iss.read(reinterpret_cast<char *>(&total_size), sizeof(total_size));
std::vector<MyClass> out_vec;
out_vec.resize(total_size);
for(MyClass &d: out_vec) {
size_t v_size;
iss.read(reinterpret_cast<char *>(&d.some_int_member), sizeof(d.some_int_member));
iss.read(reinterpret_cast<char *>(&v_size), sizeof(v_size));
d.some_vector_member.resize(v_size);
iss.read(reinterpret_cast<char *>(&d.some_vector_member[0]), v_size * sizeof(float));
}
return out_vec;
}
std::string serialize(std::vector<MyClass> &data) {
std::ostringstream os;
size_t total_size = data.size();
os.write(reinterpret_cast<char *>(&total_size), sizeof(total_size));
for(MyClass &d: data) {
size_t v_size = d.some_vector_member.size();
os.write(reinterpret_cast<char *>(&some_int_member), sizeof(some_int_member));
os.write(reinterpret_cast<char *>(&v_size), sizeof(v_size));
os.write(reinterpret_cast<char *>(&d.some_vector_member[0]), v_size * sizeof(float));
}
return os.str();
}
我工作的实施原则,但有时(并不总是!)MPI在我认为都与系列化位置进程崩溃。发送的有效载荷可以和MB的胡言乱语一样大。我怀疑使用std::string
作为容器不是一个好的选择。使用std::string
作为char[]
的容器时是否存在一些限制,我可能会在这里使用巨大的二进制数据?
(请注意,我不希望使用boost::mpi
以其系列化程序一起,我也不希望在一个巨大的图书馆拉如cereal
到我的项目)
我不确定你想从答案中得到什么。这是关于崩溃?然后我们需要一个[mcve]和你目前调试工作的描述。或者这是关于如何正确地进行序列化?或者,这是如何发送复合C++对象与MPI(序列化只是一个答案)?如果这实际上是关于“*通过MPI *实现发送序列化数据”,那么至少我们需要查看您的MPI代码。这些问题中的许多问题也很重视意见(“*更好的方法*”),请将重点放在特定目标和标准上。 – Zulan
嗨祖兰,对不起,这个问题不是很精确。我会尝试重述它。我在大型数值模拟中使用上述例程,即使许多MPI请求没有问题,也会有时会崩溃。堆栈跟踪不是很有帮助(它包含'bad_alloc',所以我猜它是一些内存事物),并且我不能轻松创建一个最小工作示例。我怀疑'std :: string'的一些限制是问题,因此我的问题。 – janoliver
你可以尝试将你的serialize方法封装在try {...} catch(std :: bad_alloc&){...}块中。此外,您可以使用内存分析器来分析内存泄漏。 –