Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory alignment errors using Eigen with a dynamic library with Visual Studio 2013

I've been using Eigen in my software, and I've run into an issue today, caused by changing my code from building a static library to dynamic library in Windows, using Visual Studio 2013. The reason for this switch was not related to Eigen.

I am embedding Eigen in my own library file, which itself is then linked into my application(s). As mentioned before, this library had been a static library until today; I have just updated my codebase to generate a DLL file instead.

Since making this change, I am now getting the following error message from Visual Studio:

The Block at -------------------- was allocated by aligned routines, use _aligned_free()

(that this message pops up numerous times with different addresses each time; I've used dashes above, as I don't believe that the specific addresses are relevant to this issue).

choosing "retry" opens the debugger to line 255 on Memory.h

Visual studio IntelliSense (when not debugging) suggests that EIGEN_ALIGN and EIGEN_HAS_MM_MALLOC are both defined as 1, EIGEN_MALLOC_ALREADY_ALIGNED and EIGEN_HAS_POSIX_MEMALIGN are both undefined. Accordingly, it should be running _mm_free(ptr), which (again-based from IntelliSense) is an alias for _aligned_free(a). As such, it appears that this code should be running the correct function, but it isn't.

When I change the code back to a static library, this issue goes away.

The only thing remotely relevant that I found from numerous Google searches was an article from Intel Fortran Compiler saying that this error message might come from a library which was compiled in an earlier version that is called by code compiled with the latest version. Aside from the fact that I am using Visual Studio C++ 2013, I have rebuilt the code numerous times to be sure that it is all fully recompiled from a clean state and this error message persists.

I have downloaded the latest code from the mercurial repo (default branch), but this did not solve the problem.

I've tried to be as thorough as I could be. If you need any more information, please let me know.

Edit:

Further context:

The 'client code' which utilizes the DLL in this case is Google Test; the error message is raised after testing an expectation -- i.e. the class in the DLL file is running the destructor to cleanup a temporary object. I am not attempting to do evil things like allocate memory in the DLL file and then de-allocate it in the driver app -- that's partly why I find this to be so confusing....

like image 762
Shmuel Levine Avatar asked Oct 06 '14 19:10

Shmuel Levine


1 Answers

I had this exact issue. I converted my static library which uses Eigen to a DLL and started getting these errors when unit testing with gtest. As there's no solution, I'll provide what I did to resolve the issue. Essentially the problem will be that you've created a new interface to the class containing Eigen matrices/vectors as member variables, and that interface creates a pointer to the class with your Eigen member variables.

Firstly, if you've got member variables which are Eigen matrices or vectors then you should read this. In summary you need to add

public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW

to your class definitions where you use Eigen as member variables. Presumably you'll also be getting warnings about warning C4316: object allocated on the heap may not be aligned 16 if you're using the Visual Studio compiler.

Now, I still had issues after I used the EIGEN_MAKE_ALIGNED_OPERATOR_NEW, this was due to using atomic with an Eigen matrix class; boost::atomic<Eigen::MatrixXf> as a member variable. I imagine alignment is quite important when guaranteeing atomicity.

like image 142
Alex Avatar answered Oct 24 '22 05:10

Alex