想用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 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 expexp.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++版本的问题。

想用Python调用C++代码?Pytorch原来是这样做的_第1张图片

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文件里面。

想用Python调用C++代码?Pytorch原来是这样做的_第2张图片

 

END

扫描关注,获取最新AI资讯与实战案例

想用Python调用C++代码?Pytorch原来是这样做的_第3张图片

 

实用AI客栈

小编微信号 : langu86

 

你可能感兴趣的:(C/C++,c++,python,pytorch,机器学习,深度学习)