1

I'm experiencing difficulties working with boost::python and boost::python::numpy, with python 2.7, boost 1.67.0, and Eigen3.3. My compiler is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0.

I'm trying to convert Eigen::Matrix types to python ndarray and back (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

My test programme (eigen_ndarray_eigen.cpp) looks as follows:

    #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;
    }

And my 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})

I get an error when compiling:

    [ 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

It's clearly a linking problem but I am already linking my executable against all boost libraries, and I can't figure out what might be wrong. Has anyone experienced something similar? Any tips?

Thanks for your input.

Edit: I was asked for the full error message when compiled with 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
    `'

I checked some answers regarding similar problems (here). Apparently boost_numpy doesn't call the right libraries automatically and sometimes you have to include them manually:

    #define BOOST_LIB_NAME "boost_numpy"
    #include <boost/config/auto_link.hpp>

I tried this but it didn't work for me...

borizzzzz
  • 620
  • 1
  • 6
  • 17
  • Run `make VERBOSE=1` to have it print the full linker command, and include that in your question. – John Zwinck Jul 29 '18 at 07:40
  • @JohnZwinck, thanks for the tip, I edited the question accordingly. – borizzzzz Jul 29 '18 at 15:12
  • I don't think gcc supports autolinking, what is your compiler? – n. m. could be an AI Jul 29 '18 at 15:59
  • @n.m. I'm using g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0. Edited the questions adding that in. I'm not really familiar with autolinking, I just copied the lines and hoped for the best... – borizzzzz Jul 30 '18 at 07:49
  • Try adding the right library to your CMakeLists.txt instead. – n. m. could be an AI Jul 30 '18 at 09:30
  • having the same issue on boost 1.71, were you able to resolve this? – miles.sherman Aug 10 '21 at 19:00
  • solved this with the help of this post: https://stackoverflow.com/questions/52414348/boost-python-numpy-undefined-reference-to-initialize/52418440 need to make sure that the python executable is correct in project-config when building boost, and need to make sure that numpy is installed in the python env (pip install numpy). otherwise, b2 will not build boost-numpy – miles.sherman Aug 11 '21 at 18:25

0 Answers0