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

1

6

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

Marquee answered 6/10, 2014 at 19:18 Comment(2)
Are you sure the DLL and the client using the DLL have been built the same? I'm thinking out loud - now that it is separate that the DLL is doing mallocs and frees one way and the client could be doing something else. Usually for this reason its not good practice for a client to call free on an object created in a DLL. Usually you export cleanup(ie free) routines from the DLL so that a client can call those instead of doing it directly. Same would be true for object creation.Differentiable
@MichaelPetch I'm quite certain they're built the same. Certainly the DLL and static lib are identical (I only change the one setting). Also- I'm not calling free from the client -- the code in question is DLL cleanup code. In my case, the client is Google Test, which is running unit tests on the code in the library; the breakpoint is reached at a point where a temporary Eigen matrix destructor should be called. I will update the question and clarify this for the benefit of others. I see that this was not clear before.Marquee
Z
4

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.

Zahara answered 19/8, 2016 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.