pybind新手 - 阅读文档,但我不知道如何将其应用于2D数组。
我有两个存储3d坐标的数组shape = (10,3)
a = np.zeros(shape=(10,3))
b = np.ones(shape=(10,3)) * 3
c = a + b
现在,使用pybind,如何在使用numpy数组的C ++中执行此操作?
在某些文档中,我阅读的是使用[]
运算符访问元素,而在其他文档中使用()
。
如何分配3D矢量?
我如何获得指向数组元素的指针以使用步幅进行赋值 - 或者它是否有运算符?
答案 0 :(得分:4)
PyBind真棒,向作者/维护者大喊大叫! 你有一个几乎有效的例子here。
根据你的问题,它会给出类似的东西(在El Dude的评论之后编辑回答):
#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) {
auto buf1 = input1.request(), 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);
auto 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");
}
我使用python2.7和gcc v5.4构建在linux上(我必须使用与doc中提供的稍微不同的命令,因为找不到Python.h,因此我添加了到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
你用
从python中调用它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
希望它有所帮助。
答案 1 :(得分:0)
诀窍是使用缓冲类。它很好地隐藏/复杂到文档和示例中,但它被提及(@Christian的帖子)。
缓冲区包含指向数据的指针以及步幅和其他数组参数。基本上是通过request
方法访问的numpy标头。从那以后很容易使用,但发现它有点痛苦,因为该示例使用漂亮的C11
auto
类型来解释这种用法。