将 Eigen 数组从 c++ 传输到 python 时的地址更改
Posted
技术标签:
【中文标题】将 Eigen 数组从 c++ 传输到 python 时的地址更改【英文标题】:Address changes upon transferring Eigen array from c++ to python 【发布时间】:2018-08-22 03:44:55 【问题描述】:我创建了一个 c++ 函数来创建具有正确内存对齐的 numpy 数组。
不知何故,python 和 c++ 为“相同”数组打印了两个不同的地址。
这是否意味着pybind11仍然复制数组?
如果是这样,如何避免抄袭?
pybind11 来自:https://github.com/pybind/pybind11/archive/stable.zip
c++代码:
#include <Eigen/Eigen>
#include <iostream>
#include <pybind11/eigen.h>
template <typename T>
inline Array<T, Dynamic, Dynamic>* eigen_empty(Index rows, Index cols)
auto a = new Array<T, Dynamic, Dynamic>(rows, cols);
std::cout << "Address: " << (long long) a << "\n";
return a;
namespace py = pybind11;
PYBIND11_MODULE(_cxx, m)
m.def("eigen_empty_d", &eigen_empty<double>,
py::return_value_policy::take_ownership);
// python would "take_ownership" of the array
python 测试:
>>> x=eigen_empty_d(10,1);x.__array_interface__['data'][0];x.flags.owndata
Address: 32962272 # address printed by c++
29726560 # address from python
False # numpy does not own the data
>>> x=eigen_empty_d(10,1);x.__array_interface__['data'][0];x.flags.owndata
Address: 32962240
29511904
False
>>> x=eigen_empty_d(10,1);x.__array_interface__['data'][0];x.flags.owndata
Address: 29516656
29726560
False
>>> x=eigen_empty_d(10,1);x.__array_interface__['data'][0];x.flags.owndata
Address: 33209440
29726560
False
>>> x=eigen_empty_d(10,1);x.__array_interface__['data'][0];x.flags.owndata
Address: 29429712
29511904
False
【问题讨论】:
地址不同,因为它们指向不同类型的不同对象。在 tge Python 端,你有数据(实际的数字数组),在 C++ 端,你有 Eigen Array 对象。 但有时c++的数字比python大。有时它更小。这不仅仅是一个持续的转变。 哦。我得到它。应该从特征数组打印(*a).data()
。
现在它们匹配了。谢谢。
【参考方案1】:
将打印地址的 C++ 行修复为:
std::cout << "Address: " << (long long) a->data() << "\n";
现在它正在打印内存中数组的实际地址。如果不参考 data()
方法,您只是打印实际数组的 Eigen 包装器对象的地址。
【讨论】:
我仍然没有收到x.flags.owndata
。我以为 pybind11 会为我做到这一点。以上是关于将 Eigen 数组从 c++ 传输到 python 时的地址更改的主要内容,如果未能解决你的问题,请参考以下文章
使用 c++ Eigen 库处理 numpy 数组后,输出错误