15

在我的项目中,我将使用的点类型从Eigen::Vector2fto更改为Eigen::Vector2d并遇到对齐问题。

这是代码的简化版本:

#include <vector>
#include <Eigen/Eigen>

int main()
{
    std::vector<Eigen::Vector2d> points = { {0,0}, {0,1} };
}

我收到以下运行时错误:

eigen3/Eigen/src/Core/DenseStorage.h:78: Eigen::internal::plain_array<double, 2, 0, 16>::plain_array() [T = double, Size = 2, MatrixOrArrayOptions = 0, Alignment = 16]: Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.

正如 assert-message 所建议的,我阅读了有关Fixed-size vectorizable Eigen objects 所需对齐的信息。还有关于STL Containers的小节。似乎我有两个选择:

  1. 使用Eigen::aligned_allocator
  2. 或使用EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION宏。

两种尝试都无法编译(使用 GCC 4.8.3 和 Clang 3.5 测试),因为编译器无法正确转换初始化列表。

这里更改的代码:

#include <vector>
#include <Eigen/Eigen>
#include <Eigen/StdVector>
// EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d)

int main()
{
    std::vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> points = { {0,0}, {0,1} };
    // std::vector<Eigen::Vector2d> points = { {0,0}, {0,1} };
}

GCC 错误输出:

error: could not convert ‘{{0, 0}, {0, 1}}’ from ‘&lt;brace-enclosed initializer list>’ to ‘std::vector<Eigen::Matrix<double, 2, 1>, Eigen::aligned_allocator<Eigen::Matrix<double, 2, 1> > >’

所以我想知道:

  • 为什么更改分配器时初始化列表不可用std::vector

    • 这是因为对齐吗?
    • 我可以以某种方式对齐初始化列表吗?
  • 为什么专业化版本失败?

    • 这些是否缺少初始化列表功能?
4

1 回答 1

16

在研究了Eigen/StdVector包含文件(准确地说是在Eigen/src/StlSupport/StdVector.h版本 3.2.1 的第 68 行)之后,似乎问题源于std::vector此头文件中的部分模板特化。vector一旦您Eigen::aligned_allocator用作分配器,此部分模板特化就会替换 STL 。而且这种专业化似乎缺乏 C++11 的特性。

详细说明为什么除了替换分配器之外这种特殊化是必要的: 在 C++11 之前,resize函数std::vector可以按值获取一个附加参数来初始化新创建的元素。根据 Eigen3 文档,按值传递参数会丢弃任何对齐修饰符,并且不能与固定大小的可矢量化 Eigen 对象一起使用(请参阅 SIMD)。

编辑: 经过更多测试后,我意识到 C++11 的实现std::vector没有上述问题。因此,要解决对齐问题,您只需填写Eigen::aligned_allocator. 但包括Eigen/StdVector. 包含此文件将阻止您使用 C++11 实现,std::vector因为此标头定义了带有Eigen::aligned_allocatoras 分配器的部分特化。

于 2014-06-21T21:35:06.607 回答