Я испытываю трудности при работе с boost :: python и boost :: python :: numpy, с python 2.7, boost 1.67.0 и Eigen3.3. Мой компилятор — g ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.10) 5.4.0.
Я пытаюсь преобразовать типы Eigen :: Matrix в Python ndarray и обратно (vector_list.hpp):
#ifndef VECTOR_PYLIST_HH
#define VECTOR_PYLIST_HH
#include<iostream>
#include<vector>
#include<boost/python.hpp>
#include<Eigen/Dense>
#include<typeinfo>
#include<boost/python/numpy.hpp>namespace myutil {
template<class T>
boost::python::list to_py_list(Eigen::Matrix<T, Eigen::Dynamic,Eigen::Dynamic> matrix)
{
boost::python::list list;
boost::python::list helplist;
if (matrix.cols() > 1) {
for (int j = 0; j < matrix.cols(); j++) {
helplist = to_py_list<T>(matrix.col(j));
list.append(helplist);
}
} else {
for (int i = 0; i < matrix.rows(); i++) {
list.append(matrix(i,0));
}
}
return list;
}
template<class T>
boost::python::numpy::ndarray to_py_array(Eigen::Matrix<T, Eigen::Dynamic,Eigen::Dynamic> matrix)
{
int cols = matrix.cols();
int rows = matrix.rows();
boost::python::tuple tu = boost::python::make_tuple(rows,cols);
boost::python::numpy::dtype dtype = boost::python::numpy::dtype::get_builtin<T>();
boost::python::numpy::ndarray arr = boost::python::numpy::empty(tu, dtype);
for (int i; i < rows; i++) {
for (int j = 0; j < cols; j++) {
arr[i][j] = matrix(i,j);
}
}
return arr;
}
#endif
Моя тестовая программа (eigen_ndarray_eigen.cpp) выглядит следующим образом:
#include<vector_list.hpp>
#include<iostream>
#include<typeinfo>
int main()
{
Py_Initialize();
np::initialize();
Eigen::Matrix<double,3,2> m;
m << 1,2,3,4,5,6;
std::cout<<m<<std::endl;
boost::python::numpy::ndarray l = myutil::to_py_array<double>(m);
Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> n = myutil::to_eigen<double>(l);
std::cout<<n<<std::endl;
return 0;
}
И мой CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(myutil)
set(CMAKE_BUILD_TYPE "Debug")set(BOOST_ROOT "$ENV{BOOST_ROOT}")
find_package(PythonLibs 2.7 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
find_package(Boost 1.61.0 COMPONENTS python REQUIRED)
find_package(Eigen3 3.3 REQUIRED NO_MODULE)
include_directories(${Boost_INCLUDE_DIR} include)
add_executable(test_eigen_ndarray_eigen test/eigen_ndarray_eigen.cpp)
target_link_libraries(test_eigen_ndarray_eigen Eigen3::Eigen ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
Я получаю сообщение об ошибке при компиляции:
[ 50%] Building CXX object CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o
[100%] Linking CXX executable test_eigen_ndarray_eigen
CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o:In function `boost::python::numpy::ndarray myutil::to_py_array<double>(Eigen::Matrix<double, -1, -1, 0, -1, -1>)':
/home/usr/devel/myutil/include/vector_list.hpp:70: undefined reference to `boost::python::numpy::empty(boost::python::tuple const&, boost::python::numpy::dtype const&)'
CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o: In function `boost::python::numpy::detail::builtin_dtype<double, false>::get()':
/usr/include/boost/python/numpy/dtype.hpp:98: undefined reference to `boost::python::numpy::dtype boost::python::numpy::detail::get_float_dtype<64>()'
collect2: error: ld returned 1 exit status
CMakeFiles/test_eigen_ndarray_eigen.dir/build.make:96: recipe for target 'test_eigen_ndarray_eigen' failed
make[2]: *** [test_eigen_ndarray_eigen] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/test_eigen_ndarray_eigen.dir/all' failed
make[1]: *** [CMakeFiles/test_eigen_ndarray_eigen.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2
Это явно проблема с линковкой, но я уже связываю свой исполняемый файл со всеми библиотеками boost, и я не могу понять, что может быть не так. Кто-нибудь испытывал нечто подобное? Какие-нибудь советы?
Спасибо за ваш вклад.
Изменить: меня попросили полное сообщение об ошибке при компиляции с VERBOSE = 1:
/usr/bin/cmake -H/home/usr/devel/myutil -B/home/usr/devel/myutil/build --check-build-system CMakeFiles/Makefile.cmake 1
/usr/bin/cmake -E cmake_progress_start /home/usr/devel/myutil/build/CMakeFiles /home/usr/devel/myutil/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/usr/devel/myutil/build'
make -f CMakeFiles/test_eigen_ndarray_eigen.dir/build.make CMakeFiles/test_eigen_ndarray_eigen.dir/depend
make[2]: Entering directory '/home/usr/devel/myutil/build'
cd /home/usr/devel/myutil/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/usr/devel/myutil /home/usr/devel/myutil /home/usr/devel/myutil/build /home/usr/devel/myutil/build /home/usr/devel/myutil/build/CMakeFiles/test_eigen_ndarray_eigen.dir/DependInfo.cmake --color=
Dependee "../include/vector_list.hpp" is newer than depender "CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o".
Clearing dependencies in "/home/usr/devel/myutil/build/CMakeFiles/test_eigen_ndarray_eigen.dir/depend.make".
Scanning dependencies of target test_eigen_ndarray_eigen
make[2]: Leaving directory '/home/usr/devel/myutil/build'
make -f CMakeFiles/test_eigen_ndarray_eigen.dir/build.make CMakeFiles/test_eigen_ndarray_eigen.dir/build
make[2]: Entering directory '/home/usr/devel/myutil/build'
[ 50%] Building CXX object CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o
/usr/bin/c++ -I/usr/include/python2.7 -I/home/usr/devel/myutil/include -isystem /home/usr/devel/src/eigen-git-mirror -g -o CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o -c /home/usr/devel/myutil/test/eigen_ndarray_eigen.cpp
[100%] Linking CXX executable test_eigen_ndarray_eigen
/usr/bin/cmake -E cmake_link_script CMakeFiles/test_eigen_ndarray_eigen.dir/link.txt --verbose=1
/usr/bin/c++ -g CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o -o test_eigen_ndarray_eigen -rdynamic -lboost_python -lpython2.7
CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o: In function `boost::python::numpy::ndarray myutil::to_py_array<double>(Eigen::Matrix<double, -1, -1, 0, -1, -1>)':
/home/usr/devel/myutil/include/vector_list.hpp:70: undefined reference to `boost::python::numpy::empty(boost::python::tuple const&, boost::python::numpy::dtype const&)'
CMakeFiles/test_eigen_ndarray_eigen.dir/test/eigen_ndarray_eigen.cpp.o: In function `boost::python::numpy::detail::builtin_dtype<double, false>::get()':
/usr/include/boost/python/numpy/dtype.hpp:98: undefined reference to `boost::python::numpy::dtype boost::python::numpy::detail::get_float_dtype<64>()'
collect2: error: ld returned 1 exit status
CMakeFiles/test_eigen_ndarray_eigen.dir/build.make:96: recipe for target 'test_eigen_ndarray_eigen' failed
make[2]: *** [test_eigen_ndarray_eigen] Error 1
make[2]: Leaving directory '/home/usr/devel/myutil/build'
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/test_eigen_ndarray_eigen.dir/all' failed
make[1]: *** [CMakeFiles/test_eigen_ndarray_eigen.dir/all] Error 2
make[1]: Leaving directory '/home/usr/devel/myutil/build'
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2
`'
Я проверил некоторые ответы относительно подобных проблем (Вот). Очевидно, boost_numpy не вызывает нужные библиотеки автоматически, и иногда вам приходится включать их вручную:
#define BOOST_LIB_NAME "boost_numpy"#include <boost/config/auto_link.hpp>
Я попробовал это, но у меня не получилось …
Задача ещё не решена.
Других решений пока нет …