Eigen unaligned array assert

2019-07-14 21:05发布

问题:

I have a class that finds the convex hull of a 2D set of points. It contains a struct which has 2 Eigen::Matrix<double, 2, 1> inside. It looks like this (with many things removed):

class Foo{
public:
    Foo(Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>);

private:
    struct edge{
        unsigned int a;
        unsigned int b;
        Eigen::Matrix<double, 2, 1> slope;
        double mag;
        Eigen::Matrix<double, 2, 1> normal;
        std::vector<unsigned int> list;
    };

    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> points;
    std::vector<edge> edges
};

I am getting an assertion error when adding edges to the vector edges like this:

void Foo::DoThing(){
    edges.push_back(edge());
}

The exact error is:

Assertion failed: (reinterpret_cast(array) & 0xf) == 0 && "this assertio n is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalign edArrayAssert.html" " **** READ THIS WEB PAGE !!! ****", file \blah\blah\blah\includes\eigen\eigen-eigen-dc6cfdf9bcec\eigen\src\core\densestorage.h, line 86

I went to the webpage and read that I needed to add this macro: EIGEN_MAKE_ALIGNED_OPERATOR_NEW which I added to the struct as follows:

struct edge{
        unsigned int a;
        unsigned int b;
        Eigen::Matrix<double, 2, 1> slope;
        double mag;
        Eigen::Matrix<double, 2, 1> normal;
        std::vector<unsigned int> list;

        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    };

But the error continues. This is happening with VS 2013 and with Eigen version 3.2.9. The same code unmodified works fine with version 3.2.0. On linux with GCC version 5.3 it works fine with a beta build of Eigen. What am I doing wrong with this newer version to cause this problem?

回答1:

You have a std::vector that contains fixed-size Eigen types that are to be aligned. The issue is std::vector<edge> where edge contains fixed-size aligned Eigen::Matrix<double, 2, 1>. Here, EIGEN_MAKE_ALIGNED_OPERATOR_NEW is not sufficient, you additionally need to choose Eigen's aligned allocators as described in https://eigen.tuxfamily.org/dox/group__TopicStlContainers.html

Using STL containers on fixed-size vectorizable Eigen types, or classes >having members of such types, requires taking the following two steps: (i) A 16-byte-aligned allocator must be used. Eigen does provide one ready for use: aligned_allocator. (ii) If you want to use the std::vector container, you need to #include <Eigen/StdVector>.

You should correct your code roughly like this (not tested):

#include<Eigen/StdVector>
class Foo { 
  ...
  std::vector<edge,Eigen::aligned_allocator<edge> > edges;
}

Warning: On Linux you were just lucky it worked (maybe because 32bit/64bit), your code should really be corrected.



标签: c++ eigen3