mardi 30 juillet 2019

Why send a ndarray from Python to C++ get a strange result?

I'm trying to use the boost-python to bind C++ code. And I get a strange result when I receive a ndarray object from Python to C++. There are two problems make me confuse:

Problem 1: I using the member function get_data() to return the char*. And print by std::string type. The question is why doesn't get any output on my terminal?

Problem 2: When I convert to std::vector it looks like instead space to zero?! If so, what the best strategy to solve this kind of problem?

I will be very thankful if anyone can help me =)

The following code is my test. I also call the other two function "greet()" and "printNDArray()" in this test and work in my expectations.

In C++ side - hello.cpp:


    #include <boost/python.hpp>
    #include <boost/numpy.hpp>

    char const* greet()
    {
       return "hello, world";
    }

    #include <iostream>
    #include <string>
    boost::numpy::ndarray showArray(const boost::numpy::ndarray& in) {
            int input_size = in.shape(0);
            const char* cc = in.get_data();
            std::string str(cc); // Why doesn't get anything?? Why?
            std::cout << " === " << str << std::endl;
            auto input_ptr = reinterpret_cast<int*>(in.get_data());
            std::vector<int> v(input_size);
            for (int i = 0; i < input_size; ++i)
                v[i] = *(input_ptr + i);

            for (auto itr : v) std::cout << itr << std::endl;

            int v_size = v.size();
            boost::python::tuple shape = boost::python::make_tuple(v_size);
            boost::python::tuple stride = boost::python::make_tuple(sizeof(int));
            boost::numpy::dtype dt = boost::numpy::dtype::get_builtin<int>();
            boost::numpy::ndarray output = boost::numpy::from_data(&v[0], dt, shape, stride, boost::python::object());
            boost::numpy::ndarray output_array = output.copy();
            return output_array;
    }

    boost::numpy::ndarray printNDArray() {
            boost::python::tuple shape = boost::python::make_tuple(3,3,3);
            boost::numpy::dtype dtype = boost::numpy::dtype::get_builtin<float>();
            boost::numpy::ndarray result = boost::numpy::zeros(shape,dtype);

            return result;
    }

    BOOST_PYTHON_MODULE(hello)
    {
        using namespace boost::python;
        Py_Initialize();
        boost::numpy::initialize();

        def("greet", greet);

        def("showArray", showArray);

        def("printndarray", printNDArray);
    }


In Python side - hello.py:


    #!/usr/bin/env python

    import numpy as np
    import hello

    a = np.arange(5,10)

    print(a)

    print (hello.showArray(a))

    print (hello.greet())

    print (hello.printndarray())


The following is my terminal output:


    $ python hello.py
    [5 6 7 8 9]
     === 
    5
    0
    6
    0
    7
    [5 0 6 0 7]
    hello, world
    [[[ 0.  0.  0.]
      [ 0.  0.  0.]
      [ 0.  0.  0.]]

     [[ 0.  0.  0.]
      [ 0.  0.  0.]
      [ 0.  0.  0.]]

     [[ 0.  0.  0.]
      [ 0.  0.  0.]
      [ 0.  0.  0.]]]


Aucun commentaire:

Enregistrer un commentaire