【发布时间】:2021-07-19 20:56:59
【问题描述】:
我一直在尝试从armadillo cpp 库中序列化稀疏矩阵。我正在做一些大规模的数值计算,其中数据存储在一个稀疏矩阵中,我想使用 mpi(Boost 实现)收集它并对来自不同节点的矩阵求和。我现在陷入困境的是如何将稀疏矩阵从一个节点发送到其他节点。 Boost 建议发送用户定义的对象(在这种情况下为SpMat),它需要被序列化。
Boost 的documentation 提供了一个关于如何序列化用户定义类型的很好的教程,我可以序列化一些基本类。现在,犰狳的 SpMat 类对我来说理解和序列化非常复杂。
我遇到了几个问题和他们非常优雅的答案
-
This answer 作者:Ryan Curtin,Armadillo 的合著者和 mlpack 的作者,展示了一种非常优雅的方式来序列化
Mat类。 - This answer by sehe 展示了一种序列化稀疏矩阵的非常简单的方法。
使用第一个我可以 mpi::send 一个 Mat 类到通信器中的另一个节点,但使用后者我不能做到 mpi::send。
这是改编自第二个链接的答案
#include <iostream>
#include <boost/serialization/complex.hpp>
#include <boost/serialization/split_member.hpp>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <armadillo>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
using namespace std;
using namespace arma;
namespace boost {
namespace serialization {
template<class Archive>
void save(Archive & ar, const arma::sp_mat &t, unsigned) {
ar & t.n_rows;
ar & t.n_cols;
for (auto it = t.begin(); it != t.end(); ++it) {
ar & it.row() & it.col() & *it;
}
}
template<class Archive>
void load(Archive & ar, arma::sp_mat &t, unsigned) {
uint64_t r, c;
ar & r;
ar & c;
t.set_size(r, c);
for (auto it = t.begin(); it != t.end(); ++it) {
double v;
ar & r & c & v;
t(r, c) = v;
}
}
}}
BOOST_SERIALIZATION_SPLIT_FREE(arma::sp_mat)
int main(int argc, char *argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
arma::mat C(3,3, arma::fill::randu);
C(1,1) = 0; //example so that a few of the components are u
C(1,2) = 0;
C(0,0) = 0;
C(2,1) = 0;
C(2,0) = 0;
sp_mat A;
if(world.rank() == 0)
{
A = arma::sp_mat(C);
}
broadcast(world,A,0);
if(world.rank() ==1 ) cout << A << endl;
return 0;
}
我是这样编译的
$ mpicxx -L ~/boost_1_73_0/stage/lib -lboost_mpi -lboost_serialization -I ~/armadillo-9.900.1/include -DARMA_DONT_USE_WRAPPER -lblas -llapack serialize_arma_spmat.cpp -o serialize_arma_spmat
$ mpirun -np 2 serialize_arma_spmat
[matrix size: 3x3; n_nonzero: 0; density: 0%]
作为进程号。 2 没有打印出预期的A 矩阵。所以广播没有工作。
我无法尝试以 Ryan 的回答为基础,因为我无法理解 Armadillo 中“SpMat_Meat.hpp”中的稀疏矩阵实现,这与 Mat 类非常不同。
如何序列化boost中的稀疏矩阵,以便在boost::mpi中使用?
【问题讨论】:
标签: c++ boost sparse-matrix armadillo