当前位置: 首页 > 工具软件 > PyX > 使用案例 >

python导入.pyx文件

朱欣荣
2023-12-01

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

 类似资料: