使用 Pybind11 的 C++ 到 Python 模块

2022/11/29 1:23:59

本文主要是介绍使用 Pybind11 的 C++ 到 Python 模块,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Python 永远是我的第一选择。但与 C/C++ 相比,它在速度、内存使用和能源消耗方面效率低下。当我开始使用暗网时,我开始了解 ctypes 库,它有助于在 python 中调用 c 函数。感觉很难将它用于 C++ 函数和类对象。我找到了一种使用 pybind11 实现此绑定的简单方法。
在这里我想展示如何使用 C++ 来提高我们使用 pybind11 的 python 项目的性能。我对堆排序算法进行了性能比较,结果包含在本文中。此外,我在这里解释了如何制作不透明类型,以防止 STL 数据类型(向量、地图等)和 Python 数据结构(列表、字典)之间的复制操作。

pybind11的安装

pybind11 的安装非常简单。Pybind11开发者推荐三种安装方式。我选择使用 pip 从 PyPI 安装。

pip 安装 pybind11

堆排序 C++

// cpp_sort.cpp 
# include  <pybind11/pybind11.h>
 # include  <pybind11/numpy.h>

 namespace py = pybind11; 
class  cpp_ { 
public : 
    int *a; 
    诠释n; 

cpp_ (py:: array_t < int > & arr){ // Numpy 数组模板
    auto buf = arr. 请求();// 请求缓冲区描述符
    a = ( int *)buf.ptr; 
    n = buf.shape[ 0 ]; 
} 
int  heapify ( int *a,int i, int n) {// 最大堆
    intleft_child=2*i+1; 
    intright_child= left_child+1; 
    最大整数=我;
    诠释吨; 
    if  (left_child < n) {if(a[left_child]>a[i]){max=left_child;}}
    else{return 0;}
   
    if(right_child < n && a[right_child]>a[max]){max =right_child;}
    if(max!=i){t=a[i]; a[i]=a[max];a[max]=t; heapify(a,max,n);}

    返回 0; 
}

 int 堆排序(){
    诠释我,吨;    
    for ( i= int (n/ 2 ) -1 ;i>= 0 ;i--){ 
        heapify (a,i,n);    
    } 
    // 一个一个地获取最大值
    for ( i=n -1 ;i>= 0 ;i--){ 
        t=a[ 0 ]; 
        a[ 0 ]=a[i];
        [i]=t; 
 
        堆化(a,0,i);
    }   
    返回 0 ; 
} 
}; 
PYBIND11_MODULE (cpp_sort,m ) { // cpp_sort 是模块名,m 是绑定接口  
    py:: class_ <cpp_>(m, "cpp_" ) // 将类作为 cpp_ 暴露给 python
         。def (py::init<py:: array_t < int > &>()) // 暴露类构造函数,数组作为输入
        。def ( "heapsort" , &cpp_::heapsort) // 从 cpp_ 类公开堆排序函数
        。def_readwrite ( "array_size" , &cpp_::n); //暴露变量n,重命名为array_size

 }

py::array_t 模板有助于将某些数据类型的 Numpy 数组传递到 C++ 端。应该包含 pybind11/numpy.h 标头以获得此功能。cpp_ 构造函数将 py::array_t 作为参数。要通过引用传递,数组的 dtype 应该匹配,即 np.int32 与 C++ 中的 int 相同,否则,更改不应反映在 python 端。
PYBIND11_MODULE 是一个带有两个参数的宏,cpp_sort 是模块名称,它应该不带引号,下一个参数是 m,它是用于接口绑定的 py::module_ 类型。
此代码写在 cpp_sort.cpp 文件中。可以使用下面创建共享对象库的命令在 Linux 中编译上述 C++。

C++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) cpp_sort.cpp -o cpp_sort$(python3-config --扩展后缀)$(python3 -m pybind11 --includes) cpp_sort.cpp -o cpp_sort $(python3-config --extension-后缀)

python中的堆排序

#py_sort.py 
class  py_ : 
  # 传递 numpy 数组的构造函数
  def  __init__ ( self,a ): 
    self.a=a 
    self.n=a.shape[ 0 ] 
  # 对于最大堆
  def  heapify ( self, n, i ): 
    maxx = i 
    left_child = 2 * i + 1 
     right_child = 2 * i + 2  
    if left_child < n and self.a[i] < self.a[left_child]: 
      maxx = left_child 
    if right_child < n and self.a[maxx] < self.a[right_child]:
      maxx= right_child 

    if maxx != i: 
      self.a[i],self.a[maxx] = self.a[maxx],self.a[i] 
      self.heapify( n, maxx) 

  def  heapsort ( self ): 
    # 逐一获取最大值
    for i in  range ( int (self.n/ 2 )- 1 , - 1 , - 1 ): 
      self.heapify( self.n, i) 
    
    for i in  range (self.n- 1 , 0 , - 1 ): 
      self.a[i], self.a[ 0 ] = self.a[ 0], self.a[i] 
      self.heapify(i, 0 )

标签:Pybind11,c++,Pytho,函数, STL,安装,数据, 来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。



这篇关于使用 Pybind11 的 C++ 到 Python 模块的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程