我試圖通過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&){...}塊中。此外,您可以使用內存分析器來分析內存泄漏。 –