Pass and return numpy arrays in C++ with pybind11

Viewed 771

I have a python function called add_array in numpyfuncs.py which looks like this:

import numpy as np

def add_arrays(a, b):
    return np.add(a, b)

if __name__ == "__main__":
    data1 = np.random.random_sample((3, 2))
    data2 = np.random.random_sample((3, 2))
    print(add_arrays(data1, data2))

I want to call this function through C++ with pybind11. So basically I want to pass a C++ eigen matrix, make an addition and return the numpy.ndarray into C++ and cast it into a eigen matrix again see example (which throws me this error:

terminate called after throwing an instance of 'pybind11::cast_error'
  what():  make_tuple(): unable to convert argument of type 'Eigen::Matrix<double, 2, 2, 0, 2, 2>' to Python object
Aborted

)below (main.cpp):

// Embeding the interpreter into c++
// https://pybind11.readthedocs.io/en/master/advanced/embedding.html

#include <pybind11/embed.h>
#include <iostream>
#include <string>
#include <eigen3/Eigen/Dense>

// Define namespace for pybind11
namespace py = pybind11;
using namespace pybind11::literals;


int main() {
    // Initialize the python interpreter
    py::scoped_interpreter python;

    // Import all the functions from scripts by file name in the working directory
    py::module numpyfunc = py::module::import("numpyfuncs");

    // Initialize matrices
    Eigen::Matrix2d a;
    a << 1, 2,
        3, 4;
    Eigen::MatrixXd b(2,2);
    b << 2, 3,
        1, 4;

    // Call the python function
    py::object result = numpyfunc.attr("add_arrays")(a, b);

    // Make a casting from python objects to real C++ Eigen Matrix type
    Eigen::MatrixXd c = result.cast<Eigen::MatrixXd>();

    return 0;
}

Is this possible? I read this excellent documentation on Eigen and numpy but I cant seem to make it work in my example. What am I doing wrong? Any help would be appreciated. Thanks for hints, advices and solutions in advance.

P.S.: Here is my CMakeLists.txt to test and compile this:

cmake_minimum_required(VERSION 3.0)
project(numpytest)
add_subdirectory(pybind11)
file(COPY numpyfuncs.py DESTINATION .)
add_executable(numpytest main.cpp)
target_link_libraries(numpytest pybind11::embed)
0 Answers
Related