Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pybind11 Type Error

I've recently been trying to write a function in C++ that converts a vector of doubles into a vector of strings. I want to run this from a python interpreter so I'm using Pybind11 to interface C++ and Python. This is what I have so far,

#include <pybind11/pybind11.h>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>


std::string castToString(double v) {
    std::string str = boost::lexical_cast<std::string>(v);
    return str;
}

std::vector<std::vector<std::string> > num2StringVector(std::vector<std::vector<double> >& inputVector) {


    //using namespace boost::multiprecision;


    std::vector<std::vector<std::string> > outputVector;

    std::transform(inputVector.begin(), inputVector.end(), std::back_inserter(outputVector), [](const std::vector<double> &iv) {
        std::vector<std::string> dv;
        std::transform(iv.begin(), iv.end(), std::back_inserter(dv), &castToString);
        return dv;
    });

    return outputVector;
}


namespace py = pybind11;

PYBIND11_PLUGIN(num2String) {
    py::module m("num2String", "pybind11 example plugin");

    m.def("num2StringVector", &num2StringVector, "this converts a vector of doubles to a vector of strings.");
    m.def("castToString", &castToString, "This function casts a double to a string using Boost.");

    return m.ptr();
}

Now this compiles into a shared library, using the follow command from command line:

c++ -O3 -shared -std=gnu++11 -I ../include `python-config --cflags --ldflags --libs` num2StringVectorPyBind.cpp -o num2String.so -fPIC -lquadmath

where the ../include is where the pybind11 includes are. After compilation start up python and use,

import num2String
values = [[10, 20], [30, 40]]
num2String.num2StringVector(values)

And I get the following error, "Incompatible function arguments. The following argument types are supported". Where it then gives me a list of possible types, this is strange because I'm just trying to use a vector as my function argument which according to the documentation for pybind11 this is a supported data type: http://pybind11.readthedocs.io/en/latest/basics.html#supported-data-types

Is it that I have a vector of vectors (a 2d vector) and that is unsupported?

like image 713
mike van der naald Avatar asked May 10 '16 19:05

mike van der naald


1 Answers

You can make this work with just one extra line of code:

#include <pybind11/stl.h>

As per the documentation:

The following basic data types are supported out of the box (some may require an additional extension header to be included).

Before including pybind11/stl.h:

>>> import num2String
>>> num2String.num2StringVector([[1, 2], [3, 4, 5]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Incompatible function arguments. The following argument types are supported:
    1. (std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >) -> std::vector<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >

After including pybind11/stl.h and recompiling the shared library:

>>> import num2String
>>> num2String.num2StringVector([[1, 2], [3, 4, 5]])
[['1', '2'], ['3', '4', '5']]
like image 163
Binary Birch Tree Avatar answered Nov 13 '22 20:11

Binary Birch Tree