Zero-copy construction of an Eigen SparseMatrix
Zero-copy construction of an Eigen SparseMatrix
I have the following problem:
I have an Eigen::SparseMatrix I need to send over the network, and my network library only supports sending arrays of primitive types.
Eigen::SparseMatrix
I can retrieve the pointers to the backing arrays of my SparseMatrix by doing something like (here's the backing object's code):
// Get pointers to the indices and values, send data over the network
int num_items = sparse_matrix.nonZeros()
auto values_ptr = sparse_matrix.data().valuePtr()
auto index_ptr = sparse_matrix.data().indexPtr()
network_lib::send(values_ptr, num_items)
network_lib::send(index_ptr, 2 * num_items) // Times two b/c we have 2 indices per value
Now on the other side I have access to these two arrays. But AFAIK there is no way to create a SparseArray without copying all the data into a new SparseMatrix (see docs for construction).
I'd like to do something like:
Eigen::SparseMatrix<float> zero_copy_matrix(num_rows, num_cols);
zero_copy_matrix.data().valuePtr() = received_values_ptr;
zero_copy_matrix.data().indexPtr() = received_index_ptr;
But this throws a compiler error:
error: lvalue required as left operand of assignment zero_copy_matrix.data().valuePtr() = received_values_ptr;
Any idea on how we could zero-copy construct a sparse Eigen matrix from existing arrays of indexes and data?
Another approach I tried that didn't work (this is local, no communication):
zero_copy_matrix.reserve(num_non_zeros);
zero_copy_matrix.data().swap(original_matrix.data());
When I try to print out the zero_copy_matrix it has no values in it.
zero_copy_matrix
1 Answer
1
After digging around I think a good option for me would be to use an Eigen::Map<Eigen::SparseMatrix<float>> as such:
Eigen::Map<Eigen::SparseMatrix<float>>
Eigen::Map<Eigen::SparseMatrix<float>> sparse_map(num_rows, num_cols, num_non_zeros,
original_outer_index_ptr, original_inner_index_ptr,
original_values_ptr);
AFAIK, this should be zero-copy. Answer from here.
MapppedSparseMatrix is deprecated, better use Map<SparseMatrix<float>> (simple copy-paste replacement in your case).– ggael
Aug 21 at 21:38
MapppedSparseMatrix
Map<SparseMatrix<float>>
Thanks @ggael I'll change the answer as well.
– Bar
Aug 21 at 23:56
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
From what I understand, this is a current limitation of C++ and there are proposals for memory mapped/persistent (I don't know the right term) objects for c++20 (or later) but haven't seen any real commitment to any of them.
– xaxxon
Aug 20 at 23:35