Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is an Eigen matrix created automatically on the heap?

This question might be stupid, but I am am a beginner. When I create an Eigen::MatrixXd in a local scope like this:

    void foo(){
        Eigen::MatrixXd m(rows,cols);
        // do stuff
    }

Will the object be on the heap or the stack? I would expect it to be on the stack, since I don't use the 'new' keyword.

like image 851
bennib22 Avatar asked Mar 04 '23 01:03

bennib22


1 Answers

Instances of specializations of Eigen::Matrix can be stored either on the heap or the stack

As is mentioned in the accepted answer, m has automatic storage duration. It is important to point out, however, that the subsequent statement that

Of course Eigen::MatrixXd will manage much of its internal memory dynamically, but you do not need to concern yourself with that.

does not apply, in general, for instances of specializations of Eigen::Matrix, and important to also point out that this is indeed something you might want to concern yourself with, particularly if are working in a context where dynamic memory is disallowed (say, an embedded environment).

Dynamic-sized Eigen matrices

You are using a dynamically-sized matrix (emphasis on the X in Eigen::MatrixXd. Any Eigen::MatrixX... type is just a typedef for Eigen::Matrix< ..., Dynamic , Dynamic >, where Dynamic signifies that its size is not known at compile-time:

const int Eigen::Dynamic

This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is stored in some runtime variable.

The Eigen documenation for Eigen::Matrix, that all Eigen::MatrixX... are specializations of, makes it clear that the data of dynamic-sized matrices will be stored on the heap [emphasis mine]:

Fixed-size versus dynamic-size:

Fixed-size means that the numbers of rows and columns are known are compile-time. In this case, Eigen allocates the array of coefficients as a fixed-size array, as a class member. ...

Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime variables, and the array of coefficients is allocated dynamically on the heap.

Fixed-sized Eigen matrices

From the first paragraph quoted above it is clear, however, that if m were to have been a fixed-size Eigen::Matrix specialization, its data would be (as it has automatic storage duration) stored on the heap. This is important guarantee e.g. for projects where dynamic memory allocation is not allow (e.g. embedded).

Indeed, Eigen even offers an internal preprocessor directive, EIGEN_RUNTIME_NO_MALLOC, that can be used to ban any dynamic memory allocation within the Eigen module.

These macros are mainly meant for people developing Eigen and for testing purposes. Even though, they might be useful for power users and the curious for debugging and testing purpose, they should not be used by real-word code.

EIGEN_RUNTIME_NO_MALLOC - if defined, a new switch is introduced which can be turned on and off by calling set_is_malloc_allowed(bool). If malloc is not allowed and Eigen tries to allocate memory dynamically anyway, an assertion failure results. Not defined by default.

Emphasis, however, on "should not be used by real-word code", but it could be used by users of Eigen for testing purposes.

Fixed-size matrices may still end up on the heap!

As mentioned by @superjax in a comment:

One last thing I would add is that fixed-size matrices exceeding the EIGEN_STACK_ALLOCATION_LIMIT will also be allocated on the heap. (The default is 128kb, but that can be changed)

like image 155
dfrib Avatar answered Mar 09 '23 08:03

dfrib