Pybind Numpy access 2D / ND arrays

前端 未结 2 1011
抹茶落季
抹茶落季 2020-12-14 05:00

New to pybind - read the documentation but I do not grasp how to apply it to 2D arrays.

I have two arrays storing 3d coordinates shape = (10,3)

相关标签:
2条回答
  • 2020-12-14 05:48

    PyBind is awesome, shout out to the authors/maintainers! You have an almost working example here.

    Adapted to your problem it would give something like (edited answer after El Dude's comment):

    #include <iostream>
    #include <pybind11/pybind11.h>
    #include <pybind11/numpy.h>
    
    
    namespace py = pybind11;
    
    
    py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
      py::buffer_info buf1 = input1.request();
      py::buffer_info buf2 = input2.request();
    
      if (buf1.size != buf2.size) {
        throw std::runtime_error("Input shapes must match");
      }
    
      /*  allocate the buffer */
      py::array_t<double> result = py::array_t<double>(buf1.size);
    
      py::buffer_info buf3 = result.request();
    
      double *ptr1 = (double *) buf1.ptr,
             *ptr2 = (double *) buf2.ptr,
             *ptr3 = (double *) buf3.ptr;
      int X = buf1.shape[0];
      int Y = buf1.shape[1];
    
      for (size_t idx = 0; idx < X; idx++) {
        for (size_t idy = 0; idy < Y; idy++) {
          ptr3[idx*Y + idy] = ptr1[idx*Y+ idy] + ptr2[idx*Y+ idy];
        }
      }
     
      // reshape array to match input shape
      result.resize({X,Y});
    
      return result;
    }
    
    
    PYBIND11_MODULE(example, m) {
            m.doc() = "Add two vectors using pybind11"; // optional module docstring
    
            m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
    }
    

    That I built on linux with python2.7 and gcc v5.4 using (I had to use a slightly different command than provided in the doc, because Python.h wasn't found, hence I added the link to python 2.7)

    c++ -O3 -Wall -shared -std=c++11 -fPIC -I/usr/include/python2.7 -lpython2.7 `python -m pybind11 --includes` example.cpp -o example`python-config --extension-suffix
    

    And you'd call it from python with

    import numpy as np
    import example # [bad] name I chose for my compiled module
    
    a = np.zeros((10,3))
    b = np.ones((10,3)) * 3 
    c = example.add_arrays(a, b)
    
    print c
    

    Hope it helps.

    0 讨论(0)
  • 2020-12-14 05:53

    The trick is to use the buffer class. It's well hidden / convoluted into the documentation and examples, but it's mentioned (@Christian 's post).

    Buffers contain a pointer to the data as well as strides and others array parameters. Essentially the numpy header accessed through request method. Easy to use from there on, but finding it is bit of a pain since the example uses beautiful C11 auto type to explain this usage.

    0 讨论(0)
提交回复
热议问题