想用Python调用C++代码?Pytorch原来是这样做的
导
语
目前绝大多数深度学习框架,为了编程方面的便利,都支持Python接口。正如硬币的两面一样,Python的灵活性是建立在它的性能损耗上的。因此对于AI框架,通常做法是把对性能有极高要求的运算(比如卷积等)用C++实现,然后再用Python去调用C++的模块。这是怎么实现的呢?我们基于ubuntu系统以Pytorch为例,逐步剖析这个调用过程,下面有请我们今天的主角:pybind11
1-安装 pybind11
git clone https://github.com/pybind/pybind11.git
cd pybind11
mkdir build
cd build
cmake ..
sudo make -j10 install
make install会将pybind11安装在/usr/local下面
2-编写示例程序
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j)
{
return i + j;
}
//pybind11宏用于绑定函数,pybind11_exp为python模块名称
PYBIND11_MODULE(pybind11_exp, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
//add为函数名称,&add为函数指针
m.def("add", &add, "A function which adds two numbers");
}
将该代码保存并命名为pybind11_exp.cpp
3-编译代码
g++ -O3 -Wall -shared -std=c++11 -fPIC -I/usr/local/include -I/home/ubuntu/anaconda3/envs/apex/include/python3.6m pybind11_exp.cpp -o pybind11_exp`python3-config --extension-suffix`
使用上述代码对pybind11_exp.cpp进行编译,“pybind11_exp.cpp -o pybind11_exp”中模块名称"pybind11_exp"需和pybind11_exp.cpp代码中的一致。编译后会生成文件pybind11_exp.cpython-36m-x86_64-linux-gnu.so
4-python代码引用
import pybind11_exp as exp
exp.add(10,20)
Bug总结
1)编译时多余指令
如果编译时出现python3-config --ldflags
,则会出现fatal error: bytecode stream generated with LTO version x.0 instead of the expected x.x(3_bug1_snapshot)的情况。这个不是g++版本的问题。
2)找不到"Python.h"文件
如果编译代码时未加 -I/home/ubuntu/anaconda3/envs/apex/include/python3.6m,则会出现这种报错。先用命令python3 -m pybind11 --includes找出头文件路径,添加进编译指令即可。这个不是没有安装python3-dev的问题。
3)找不到模块
如果PYBIND11_MODULE(pybind11_exp, m)中的模块名"pybind11_exp"与python代码里面的模块名称不一致,则会出现"ImportError: dynamic module does not define module export function(PyInit_pybind11_exp)"的错误。另外这个宏定义需要在cpp文件里面。
END
扫描关注,获取最新AI资讯与实战案例
实用AI客栈
小编微信号 : langu86
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?