1.实例:指针-->numpy
#include <iostream>
#include<pybind11/pybind11.h>
#undef max//放在<pybind11/numpy.h>之前(#define NOMINMAX有时不起作用)
#include<pybind11/numpy.h>
namespace py = pybind11;
using namespace py::literals;
//*指针-->numpy 1D
template<typename T>
py::array_t<T> _ptr_to_arrays_1d(T* data, py::ssize_t col) {
auto result = py::array_t<T>(col);//申请空间
py::buffer_info buf = result.request();
T* ptr = (T*)buf.ptr;
for (auto i = 0; i < col; i++)
ptr[i] = data[i];
return result;
}
//*指针-->numpy 1D
template<typename T>
py::array_t<T> ptr_to_arrays_1d(T* data, py::ssize_t col) {
py::array_t<double> out = py::array_t<double>(col);
auto r3 = out.mutable_unchecked<1>();
for (int i = 0; i < col; i++)
r3(i) = data[i];
return out;
}
//*指针-->numpy 2D
template<typename T>
py::array_t<T> _ptr_to_arrays_2d(T* data, py::ssize_t row,py::ssize_t col) {
auto result = _ptr_to_arrays_1d(data, row * col);
result.resize({ row,col });//转换为2d矩阵
return result;
}
//*指针-->numpy 2D
template<typename T>
py::array_t<T> ptr_to_arrays_2d(T* data, py::ssize_t row, py::ssize_t col) {
py::array_t<T> out = ptr_to_arrays_1d(data,row * col);
out.resize({ row,col});
return out;
}
//*指针-->numpy 3D
template<typename T>
py::array_t<T> _ptr_to_arrays_3d(T* data, py::ssize_t chunk, py::ssize_t row, py::ssize_t col) {
auto result = _ptr_to_arrays_1d(data, chunk * row * col);
result.resize({ chunk,row,col });//转换为2d矩阵
return result;
}
//*指针-->numpy 3D
template<typename T>
py::array_t<T> ptr_to_arrays_3d(T* data, py::ssize_t chunk, py::ssize_t row, py::ssize_t col) {
py::array_t<T> out = ptr_to_arrays_1d(data, chunk * row * col);
out.resize({ chunk,row,col });
return out;
}
2.实例:测试-numpy数组相加
//*1d numpy数组相加
py::array_t<double> _add_arrays_1d(py::array_t<double>& arr1, py::array_t<double>& arr2) {
py::buffer_info buf1 = arr1.request();// 获取arr1, arr2的信息
py::buffer_info buf2 = arr2.request();
if (buf1.ndim != 1 || buf2.ndim != 1)
throw std::runtime_error("Number of dimensions must be one");
if (buf1.size != buf2.size)
throw std::runtime_error("Input shape must match");
auto result = py::array_t<double>(buf1.size);//申请空间
py::buffer_info buf3 = result.request();
double* ptr1 = (double*)buf1.ptr; //获取numpy.ndarray 数据指针
double* ptr2 = (double*)buf2.ptr;
double* ptr3 = (double*)buf3.ptr;
for (int i = 0; i < buf1.shape[0]; i++){//指针访问numpy.ndarray
ptr3[i] = ptr1[i] + ptr2[i];}
return result;
}
//*1d numpy数组相加
py::array_t<double> add_arrays_1d(py::array_t<double>& arr1, py::array_t<double>& arr2) {
auto r1 = arr1.unchecked<1>();
auto r2 = arr2.unchecked<1>();
py::array_t<double> out = py::array_t<double>(arr1.size());
auto r3 = out.mutable_unchecked<1>();
for (int i = 0; i < arr1.shape()[0]; i++)
r3(i) = r1(i) + r2(i);//下标索引访问 numpy.ndarray
return out;
}
//*2d numpy数组相加
py::array_t<double> _add_arrays_2d(py::array_t<double>& arr1, py::array_t<double>& arr2) {
py::buffer_info buf1 = arr1.request();
py::buffer_info buf2 = arr2.request();
if (buf1.ndim != 2 || buf2.ndim != 2)
throw std::runtime_error("numpy.ndarray dims must be 2!");
if ((buf1.shape[0] != buf2.shape[0]) || (buf1.shape[1] != buf2.shape[1]))
throw std::runtime_error("two array shape must be match!");
auto result = py::array_t<double>(buf1.size);//申请内存
result.resize({ buf1.shape[0],buf1.shape[1] });//转换为2d矩阵
py::buffer_info buf_result = result.request();
double* ptr1 = (double*)buf1.ptr;//指针访问读写 numpy.ndarray
double* ptr2 = (double*)buf2.ptr;
double* ptr_result = (double*)buf_result.ptr;
for (int i = 0; i < buf1.shape[0]; i++){
for (int j = 0; j < buf1.shape[1]; j++){
auto value1 = ptr1[i*buf1.shape[1] + j];
auto value2 = ptr2[i*buf2.shape[1] + j];
ptr_result[i*buf_result.shape[1] + j] = value1 + value2;
}
}
return result;
}
//*2d numpy数组相加
py::array_t<double> add_arrays_2d_(py::array_t<double>& arr1, py::array_t<double>& arr2) {
auto r1 = arr1.unchecked<2>();
auto r2 = arr2.unchecked<2>();
py::array_t<double> out = py::array_t<double>(arr1.size());
out.resize({ arr1.shape()[0],arr1.shape()[1] });
auto r3 = out.mutable_unchecked<2>();
for (int i = 0; i < arr1.shape()[0]; i++) {
for (int j = 0; j < arr1.shape()[1]; j++) {
r3(i,j) = r1(i,j) + r2(i,j);//下标索引访问 numpy.ndarray
}
}
return out;
}
//*2d numpy数组相加
py::array_t<double> add_arrays_2d(py::array_t<double>& arr1, py::array_t<double>& arr2) {
auto row = arr1.shape()[0], col = arr1.shape()[1];
py::array_t<double> arr1_ = arr1,arr2_ = arr2;
arr1_.resize({ row * col });
arr2_.resize({ row * col });
auto out = add_arrays_1d(arr1_,arr2_);
py::array_t<double> out1 = py::array_t<double>(arr1.size());
out1 = out;
out1.resize({ row,col });
return out1;
}
//*3d numpy数组相加
py::array_t<double> _add_arrays_3d(py::array_t<double>& arr1, py::array_t<double>& arr2) {
py::buffer_info buf1 = arr1.request();
py::buffer_info buf2 = arr2.request();
if (buf1.ndim != 3 || buf2.ndim != 3)
throw std::runtime_error("numpy array dim must is 3!");
for (int i = 0; i < buf1.ndim; i++) {
if (buf1.shape[i] != buf2.shape[i])
throw std::runtime_error("inputs shape must match!");
}
auto result = py::array_t<double>(buf1.size);
result.resize({ buf1.shape[0], buf1.shape[1], buf1.shape[2] });
py::buffer_info buf_result = result.request();
double* ptr1 = (double*)buf1.ptr;
double* ptr2 = (double*)buf2.ptr;
double* ptr_result = (double*)buf_result.ptr;
auto chunks = buf1.shape[0];
auto rows = buf1.shape[1];
auto cols = buf1.shape[2];
py::ssize_t idx = 0;
for (int i = 0; i < buf1.shape[0]; i++) {
for (int j = 0; j < buf1.shape[1]; j++) {
for (int k = 0; k < buf1.shape[2]; k++) {
idx = i * rows * cols + j * cols + k;
ptr_result[idx] = ptr1[idx]+ptr2[idx];
}
}
}
return result;
}
//*3d numpy数组相加
py::array_t<double> add_arrays_3d(py::array_t<double>& arr1, py::array_t<double>& arr2) {
//unchecked<N> can be non-writeable
//mutable_unchecked<N> can be writeable
auto r1 = arr1.unchecked<3>();
auto r2 = arr2.unchecked<3>();
py::array_t<double> out = py::array_t<double>(arr1.size());
out.resize({ arr1.shape()[0], arr1.shape()[1], arr1.shape()[2] });
auto r3 = out.mutable_unchecked<3>();
for (int i = 0; i < arr1.shape()[0]; i++){
for (int j = 0; j < arr1.shape()[1]; j++){
for (int k = 0; k < arr1.shape()[2]; k++){
double value1 = r1(i, j, k);
double value2 = r2(i, j, k);
r3(i, j, k) = value1 + value2;//下标索引访问 numpy.ndarray
}
}
}
return out;
}
3.c++中测试:
int main() {
py::scoped_interpreter guard{};//python初始化
//*测试1D
double data1[] = {1.1,2.2,3.3,4.4};
py::array_t<double> _arr1 = _ptr_to_arrays_1d(data1, 4);
py::array_t<double> _arr2 = _ptr_to_arrays_1d(data1, 4);
py::array_t<double> arr1 = ptr_to_arrays_1d(data1, 4);
py::array_t<double> arr2 = ptr_to_arrays_1d(data1, 4);
py::print("1.1.add_1d=");
py::print(_add_arrays_1d(_arr1, _arr2));
py::print("1.2.add_1d=");
py::print(add_arrays_1d(arr1, arr2));
//*测试2D
double data2[] = { 1.1,1.2,1.3,2.1,2.2,2.3 };
_arr1 = _ptr_to_arrays_2d(data2, 2, 3);
_arr2 = _ptr_to_arrays_2d(data2, 2, 3);
arr1 = ptr_to_arrays_2d(data2, 2, 3);
arr2 = ptr_to_arrays_2d(data2, 2, 3);
py::print("2.1.add_2d=");
py::print(_add_arrays_2d(_arr1, _arr2));
py::print("2.2.add_2d=");
py::print(add_arrays_2d(arr1, arr2));
//*测试3D
double data3[] = {
11.1,11.2,11.3,12.1,12.2,12.3 ,
21.1,21.2,21.3,22.1,22.2,22.3 };
_arr1 = _ptr_to_arrays_3d(data3,2, 2, 3);
_arr2 = _ptr_to_arrays_3d(data3,2, 2, 3);
arr1 = ptr_to_arrays_3d(data3, 2, 2, 3);
arr2 = ptr_to_arrays_3d(data3, 2, 2, 3);
py::print("3.1.add_3d=");
py::print(_add_arrays_3d(_arr1, _arr2));
py::print("3.4.add_3d=");
py::print(add_arrays_3d(arr1, arr2));
}
4.python中测试:
PYBIND11_MODULE(py_numpy, m) {
m.doc() = "Simple demo using numpy!";
m.def("_add_arrays_1d", &_add_arrays_1d);
m.def("_add_arrays_2d", &_add_arrays_2d);
m.def("_add_arrays_3d", &_add_arrays_3d);
m.def("add_arrays_1d", &add_arrays_1d);
m.def("add_arrays_2d", &add_arrays_2d);
m.def("add_arrays_3d", &add_arrays_3d);
}
//python测试代码
import py_numpy as cnp
import numpy as np
data1 = np.array([1, 3, 5, 7, 9])
data2 = np.array([2, 4, 6, 8, 10])
var1 = cnp._add_arrays_1d(data1,data2)
print('var1=', var1)
data1 = np.array(range(0, 16)).reshape([4, 4])
data2 = np.array(range(20, 36)).reshape([4, 4])
var2 = cnp._add_arrays_2d(data1,data2)
print('var2', var2)
data1 = np.array(range(0, 48)).reshape([4, 4, 3])
data2 = np.array(range(50, 50 + 48)).reshape([4, 4, 3])
var3 = cnp.add_arrays_3d(data1,data2)
print('var3', var3)
参考:https ://www.jianshu.com/p/c912a0a59af9