【问题标题】:Eigen unaligned array assert特征未对齐数组断言
【发布时间】:2016-08-10 20:59:01
【问题描述】:

我有一个类可以找到一组 2D 点的凸包。它包含一个内部有 2 个 Eigen::Matrix<double, 2, 1> 的结构。它看起来像这样(删除了很​​多东西):

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
};

向向量edges 添加边时出现断言错误,如下所示:

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

确切的错误是:

断言失败:(reinterpret_cast(array) & 0xf) == 0 && “这里解释了这个断言:” "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalign edArrayAssert.html" " **** 阅读此网页!!! ****“, 文件 \blah\blah\blah\includes\eigen\eigen-eigen-dc6cfdf9bcec\eigen\src\core\densestorage.h,第 86 行

我去了网页并阅读到我需要添加这个宏: EIGEN_MAKE_ALIGNED_OPERATOR_NEW 我将其添加到结构中,如下所示:

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
    };

但错误仍在继续。这发生在 VS 2013 和 Eigen 版本 3.2.9 中。未修改的相同代码适用于版本 3.2.0。在具有 GCC 版本 5.3 的 linux 上,它适用于 Eigen 的 beta 版本。我对这个新版本做错了什么导致这个问题?

【问题讨论】:

    标签: c++ eigen3


    【解决方案1】:

    您有一个std::vector,其中包含要对齐的固定大小的 Eigen 类型。 问题是std::vector&lt;edge&gt;,其中edge 包含固定大小对齐的Eigen::Matrix&lt;double, 2, 1&gt;。 在这里,EIGEN_MAKE_ALIGNED_OPERATOR_NEW 是不够的,您还需要选择 Eigen 的对齐分配器,如https://eigen.tuxfamily.org/dox/group__TopicStlContainers.html 中所述

    在固定大小的可向量化 Eigen 类型或具有此类成员的类上使用 STL 容器需要执行以下两个步骤: (i) 必须使用 16 字节对齐的分配器。 Eigen 确实提供了一个可供使用的方法:aligned_allocator。 (ii) 如果要使用std::vector 容器,需要#include &lt;Eigen/StdVector&gt;

    您应该大致像这样更正您的代码(未经测试):

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

    警告:在 Linux 上你很幸运它可以工作(可能是因为 32 位/64 位),你的代码真的应该被纠正。

    【讨论】:

    • 这个例子中Eigen::aligned_allocator&lt;edge&gt;Eigen::aligned_allocator&lt;Eigen::Matrix&lt;double, 2, 1&gt; &gt; 有什么区别?我问的原因是两者都生成没有错误的代码。
    • 使用为不同类型制作的分配器听起来像是在运行时可能发生的任何事情,我会小心的。
    猜你喜欢
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多