1、参考https://cython.readthedocs.io/en/latest/src/tutorial/cython_tutorial.html
以bbox.pyx为例,先新建setup.py,内容为
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("bbox.pyx")
)
然后执行命令
python setup.py build_ext --inplace
在自动执行以下命令时
gcc -pthread -B /home/Shaelyn/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/Shaelyn/anaconda3/include/python3.7m -c bbox.c -o build/temp.linux-x86_64-3.7/bbox.o
发生错误
bbox.c:626:31: fatal error: numpy/arrayobject.h: No such file or directory
compilation terminated.
error: command 'gcc' failed with exit status 1
解决方法是找到numpy/arrayobject.h位置(注意,路径要更改成自己的用户名)
/home/Shaelyn/anaconda3/lib/python3.7/site-packages/numpy/core/include
再显式添加在命令里:
gcc -pthread -B /home/Shaelyn/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/Shaelyn/anaconda3/include/python3.7m -I/home/Shaelyn/anaconda3/lib/python3.7/site-packages/numpy/core/include -c bbox.c -o build/temp.linux-x86_64-3.7/bbox.o
编译成功。
如果只是执行了上面出现错误的语句,还需再手动执行
gcc -shared -o bbox.so bbox.o
参考http://forum.digitser.cn/thread-2227-1-1.html,.pyx 文件必须先被编译成 .c 文件,再编译成 .pyd (Windows 平台) 或 .so (Linux 平台) 文件,才可作为模块 import 导入使用。至此结束,可以import bbox。
最后出现了一个小问题
undefined symbol: _Py_FalseStruct
是因为编译时用的Python3,但import用的Python2,参考https://stackoverflow.com/questions/52917994/python-lib-undefined-symbol-py-falsestruct
2、参考https://blog.csdn.net/u012816621/article/details/52334622
以faster rcnn中的nms为例,涉及到的文件有gpu_nms.pyx, nms_kernel.cu, 需要将二者分别编译再整合成gpu_nms.so
(1) 同1,先新建setup.py,将"bbox.pyx"换成"gpu_nms.pyx"即可,运行后生成gpu_nms.o
(2) 将nms_kernel.cu编译成nms_kernel.o,
nvcc --gpu-architecture=compute_61 --gpu-code=compute_61 -DGPU -I/usr/local/cuda/include/ -DCUDNN --compiler-options "-DGPU -DCUDNN -fPIC" -c nms_kernel.cu -o nms_kernel.o
nvcc: cuda的编译器
–gpu-architecture=compute_61 –gpu-code=compute_61 : 这个是根据显卡计算能力来确定的,由于显卡是GTX1080,所以是compute_61。查看显卡计算力参考https://blog.csdn.net/xiaxuesong666/article/details/79192162
–compiler-options : 在双引号中填写一些编译选项。 尤其是-fPIC选项,因为在外面写是编译不通过的,只能在双引号里面写。
(3) 将nms_kernel.o和gpu_nms.o编译成gpu_nms.so
gcc -shared -o gpu_nms.so gpu_nms.o nms_kernel.o -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand -lcudnn
我们已经将cudnn的相关支持链接进去了,即
-L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand -lcudnn
可以避免一些错误,比如cudafree等
(4) import gpu_nms,出现错误提示
nms/gpu_nms.so: undefined symbol: _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
在https://blog.csdn.net/devil_2009/article/details/17738871中给出了解释,是因为使用gcc编译了c++
一定要用g++编译C++代码,不然会报类似“OSError: ./libtest4.so: undefined symbol:
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_”这样的错误,
因为gcc不会链接C++的库文件。
因此删除(1)生成的gpu_nms.o和gpu_nms.c,重新运行setup.py,然后将命令中的gcc改成g++,即
g++ -pthread -B /home/Shaelyn/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/Shaelyn/anaconda3/include/python3.7m -I/home/Shaelyn/anaconda3/lib/python3.7/site-packages/numpy/core/include -c gpu_nms.c -o build/temp.linux-x86_64-3.7/gpu_nms.o
将nms_kernel.o和gpu_nms.o编译成gpu_nms.so时,命令中的gcc同样改成g++,即
g++ -shared -o gpu_nms.so gpu_nms.o nms_kernel.o -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand -lcudnn
至此结束,import gpu_nms时不会出现问题。
(另) 使用mmdetection (pytorch版) 时,import nms_cuda出现问题
nms_cuda.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZN6caffe26detail37_typeMetaDataInstance_preallocated_32E
原因在于没有先import torch,具体原因为https://blog.csdn.net/xiaomudouer/article/details/84330083