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.
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.
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>> 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.