美文网首页Python 优化--cython/numba/pypy/cppyy/pybind11
CPPYY--即时利用c++代码 生成python扩展模块(一)

CPPYY--即时利用c++代码 生成python扩展模块(一)

作者: 北方的花姑娘 | 来源:发表于2019-08-24 20:03 被阅读0次

CPPYY

cppyy 非常灵活易用,可以将c/c++代码封装成python可以直接调用的模块,在这中间,用户不需要任何额外的代码

  • Install:

pip install cppyy

  • 即时编译c++代码生成python 扩展模块

以下代码在jupyter/ipython中运行:

import cppyy
# 直接在ipython中写c++代码,cppyy会自动编译成python可以调用的模块,on-the-fly compilation
# 生成的模块接口和c++中定义的是一致的

cppyy.cppdef("""
std::vector<double> vec_dot(const std::vector<double> &vec1, const std::vector<double> &vec2){
    std::vector<double> ret;
    if (vec1.size() != vec2.size()) return ret;
    int size = vec1.size();
    for (int i=0;i<size;i++){
        ret.push_back(vec1[i] * vec2[i]);
    }
    return ret;
}
""")
True
# 使用上面定义的vec_dot

# cppyy.gbl 是global 命名空间,即时生成模块都在这里
vec_dot = cppyy.gbl.vec_dot
# vec_dot 使用了 std::vector 为入口和出口参数
Vector = cppyy.gbl.std.vector
# Vector[typename]()  Vector 是一个模板类,需要传入tpyenae,但是python中使用[] 而不是<>
vec1 = Vector[float]([1.0, 2.0, 3.0, 4.0])
vec2 = Vector[float]([1.0, 3.0, 2.0, 4.0])
vec1, vec2
(<cppyy.gbl.std.vector<float> object at 0x000001E120E8ECF0>,
 <cppyy.gbl.std.vector<float> object at 0x000001E120E8FA70>)
# 可以转换成list,看到数据
list(vec1), list(vec2)
([1.0, 2.0, 3.0, 4.0], [1.0, 3.0, 2.0, 4.0])
# 调用c++函数vec_dot
vec_ret = vec_dot(vec1, vec2)
list(vec_ret)
[1.0, 6.0, 6.0, 16.0]

总结

  • 需要注意的是即时编译的代码,也是即时用的,下次还需要编译,而不要去探究这个代码编译成的库是存在哪里了。
  • 当然可以将c++代码保存在一个文件里如vec_dot.cpp, 直接使用cppyy.include("path/to/vec_dot.cpp"), 和上面的方法是一样的
  • cppyy.include 一般是导入头文件,配合cppyy.load_libraries 导入动态库,这样可以避免即时编译,头文件只是提供一些接口,使得python知道有哪些模块函数
  • 即时编译的技术是利用了cling,由CERN(欧洲原子能组织)为ROOT项目(用于物理实验数据分析/绘图等)开发的
  • 如果已经存在一个c++项目,可以使用cmake配合cppyy提供的类似pybind11的功能(但是不需要像pybind11一样来写binding接口),直接将项目生成为python可以调用的模块

参考:

  1. cppyy docs
  2. cppyy tutorials
  3. 性能比较

相关文章

网友评论

    本文标题:CPPYY--即时利用c++代码 生成python扩展模块(一)

    本文链接:https://www.haomeiwen.com/subject/tdoqectx.html