I am trying to expose an Eigen tensor to python using pybind11. I can compile everything with no issue and can successfully import it to python. However, the data cannot be converted to a python type. I tried two methods. One is directly exposing the data and second using mapping. Both fail in python environment.
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include <pybind11/eigen.h>
#include <unsupported/Eigen/CXX11/Tensor>
class myclass{
myclass(){
m_data = new float[m_dim1*m_dim2*m_dim3]; // Contiguous data that represents a three dimensional array
for(int i = 0; i<m_dim1*m_dim2*m_dim3; i++)
m_data[i] = i;
m_tensor = Eigen::TensorMap<Eigen::Tensor<float, 3>>(m_data, m_dim1, m_dim2, m_dim3);
}
Eigen::TensorMap<Eigen::Tensor<float, 3>>& getDataUsingMapping() { Eigen::TensorMap<Eigen::Tensor<float, 3>> temp(m_data, m_dim1, m_dim2, m_dim3); return temp; }
Eigen::Tensor<float, 3>& getDataWithoutUsingMapping() { return m_tensor};
private:
Eigen::Tensor<float, 3> m_tensor;
// In fact, m_data, m_dim1, m_dim2, m_dim3 all are
// read from a data file but for this example let's
// assume some values.
float* m_data;
int m_dim1 = 2, m_dim2 = 5, m_dim3 = 10;
}
PYBIND11_MODULE(example, m) {
py::class_<myclass>(m, "myclass")
.def(py::init<>())
.def("getDataUsingMapping", &myClass::getDataUsingMapping, py::return_value_policy::reference)
.def("getDataWithoutUsingMapping", &myClass::getDataWithoutUsingMapping, py::return_value_policy::reference);
}
I would like to be able to process this 3D array in python with its dimensional information (m_dim1, m_dim2, m_dim3)
.
Here are the error messages I get after trying to get the data in python.
>>> import example
>>> d = example()
>>>
>>> DataInPython = d.getDataUsingMapping()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Unable to convert function return value to a Python type! The signature was
(self: example) -> Eigen::TensorMap<Eigen::Tensor<float,3,0,__int64>,0,Eigen::MakePointer>
>>>
>>>
>>> DataInPython = d.getDataWithoutUsingMapping()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Unable to convert function return value to a Python type! The signature was
(self: example) -> Eigen::Tensor<std::complex<float>,3,0,__int64>
Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
conversions are optional and require extra headers to be included
when compiling your pybind11 module.
I tried including all pybdin11 include files but did not fix the problem. Could someone kindly help me?