Boost::python 和 Eigen/dense 创建分段错误

Posted

技术标签:

【中文标题】Boost::python 和 Eigen/dense 创建分段错误【英文标题】:Boost::python and Eigen/dense create a segmentation fault 【发布时间】:2017-07-13 15:58:04 【问题描述】:

我想在这样的结构中使用特征/密集对象:

#include <boost/python.hpp>
#include <Eigen/Dense>
#include <iostream>
#include <vector>

struct data_t 
    Eigen::Matrix2f matrix;
    //std::vector<float> matrix;
;

data_t init_data() 
    data_t result;
    result.matrix(0, 0) = 1.0f;
    result.matrix(0, 1) = 2.0f;
    result.matrix(1, 0) = 3.0f;
    result.matrix(1, 1) = 4.0f;
    //result.matrix.push_back(1.0f);
    //result.matrix.push_back(2.0f);
    //result.matrix.push_back(3.0f);
    //result.matrix.push_back(4.0f);
    return result;



BOOST_PYTHON_MODULE(python_test) 

    boost::python::class_<data_t>("DataType")
        .def("from_init", &init_data)
        .staticmethod("from_init")
    ;

python 代码如下:

import python_test

def init_data():
    return python_test.DataType.from_init()

sample = init_data()

执行导致分段错误。我的问题是:为什么?如果我用 std::vector 替换 Eigen 对象,代码运行良好。

【问题讨论】:

下面的作品:struct data_t Eigen::MatrixXf matrix;;和: data_t init_data() data_t 结果;结果.matrix = Eigen::Matrix2f();结果.matrix(0, 0) = 1.0f;结果.matrix(0, 1) = 2.0f;结果.matrix(1, 0) = 3.0f;结果.matrix(1, 1) = 4.0f;返回结果; 我猜问题是在 return 语句期间,一个固定大小的 Eigen 对象在内部按值传递给 boost::python 函数。 (eigen.tuxfamily.org/dox-devel/group__TopicPassingByValue.html) 您可以尝试使用-D EIGEN_MAX_STATIC_ALIGN_BYTES=0禁用静态对齐 很遗憾这不起作用 所以假设它看起来像一个对齐问题——应该通过禁用静态对齐来解决。如果EIGEN_MAX_STATIC_ALIGN_BYTES 不起作用,您可能使用的是旧的 Eigen 版本。改用-D EIGEN_DONT_ALIGN_STATICALLY(或升级您的 Eigen 版本)。 【参考方案1】:

问题在于data_t 包含一个矩阵,Eigen 期望该矩阵对齐,但 Boost::Python 未能在对齐的内存上分配该矩阵。

最简单的解决方法是只为此禁用对齐(如果您更频繁地使用它,请创建一个 typedef):

struct data_t 
    Eigen::Matrix<float, 2, 2, Eigen::DontAlign> matrix;
;

或者,通过使用-D EIGEN_MAX_STATIC_ALIGN_BYTES=0(在最近的 Eigen 版本上)或 -D EIGEN_DONT_ALIGN_STATICALLY 编译旧的 Eigen 版本来完全禁用静态对齐。

实际上,如果 Boost::Python 使用operator::new 来分配它的对象,那么下面的方法也可以工作:

struct data_t 
    Eigen::Matrix2f matrix;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
;

【讨论】:

以上是关于Boost::python 和 Eigen/dense 创建分段错误的主要内容,如果未能解决你的问题,请参考以下文章

boost::python 和回调驱动的执行

Boost::python 和 Eigen/dense 创建分段错误

Boost.python 和 OMP

提取和转换 boost::python::list 的列表元素

C++ 包括 python.h 和 boost/python.hpp 导致 SEH 异常

使用 Boost::Python::Object 会导致链接器错误