Search code examples
c++eigen

Externalizing data from an Eigen matrix


I'm trying to take ownership of the memory backing an Eigen::Matrix without copying the memory. The data() method retains ownership. The only way I've figured out how to do this is by swapping the mapped array:

Matrix<float, Dynamic, Dynamic, RowMajor> mat = m1 * m2;
// want ownership of mat's float*

float* data = mat.data(); // get the pointer
new (&mat) Eigen::Map<Matrix3f>(NULL); // swap the mapped array with anything else
// do something with data

It doesn't look like this causes a copy under the hood, but I'm not positive. I'm also not sure that this is safe.


Solution

  • Tearing memory out of the guts of Eigen is impolite, not the least of which because you don't know how it was allocated or what else the Matrix owned.

    There is, however, the Map template, which lets you wrap an unowned buffer into a Eigen-matrix-like type.

    This type isn't an actual eigen matrix, so your own custom functions may not work with it, but it should work with Eigen functions.

    In this case, you already own the data.

    using matrix_type = Matrix<float, Dynamic, Dynamic, RowMajor>;
    using mapped_matrix_type = Map<matrix_type>;
    

    Now we create a buffer, wrap it in a mapped_matrix_type, and assign:

    auto raw = std::make_unique<float[]>(m1.rows()*m2.cols()); // maybe backwards
    mapped_matrix_type bob(raw.get(), m1.rows(), m2.cols());
    bob = m1*m2;
    

    the raw data of the bob is in raw, a unique_ptr owned buffer (which can release() if you need to to make it totally unowned).

    Any raw storage mechanism (vector, raw new, whatever else) can take the place of raw.

    Code not tested.