本系列为华为海思海思AI芯片(Hi3519A/3559A)方案学习系列之十八,系列文章请关注海思AI芯片方案学习。
作者:ltshan139
前言
前面的博客我们已经分析了yolov3相关sample代码。但这毕竟是参考代码,不能直接拿来在自己项目中使用。本文就主要谈如何将sample中的yolov3相关代码提取出来,重新组织,并编译成so库,提供api给应用软件调用。
代码重构
sample代码除了有yolov3相关代码外,还有别的模型如RFCN等推理。当然,还有很多的代码是这些模型共用的。熟读这些代码后,我将yolov3相关的代码分成了三个c文件:
nnie_ai.c: 主要提供public API接口给应用软件调用,比如 nnie_init, nnie_load_model以及nnie_forward。
nnie_driver.c: 主要是和HI_XXX底层接口打交道的代码层。它的public接口将被nnie_ai.c调用。
nnie_yolo3_sw.c: 该文件是专门针对yolo3模型的推理结果进行parse来获得最终的目标检测结果值。因为nnie不识别yolo层,所以这段分析代码需要跑在cpu上,这也是为什么取名sw的原因。它的public接口也是会被nnie_ai.c调用。
编译成动态库
在编译成一个能正常运行的so库过程中,会遇到很多错误,如下所示。
1)未定义错误,比如error: unkown type name 'SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S'
这类错误往往是 缺少头文件。解决很简单,缺啥就从sample sdk里面拷过来。
2)warning:implicit declaration of function 'usleep'
解决办法就是 添加头文件 #include <unistd.h>
3)warning: implicit declaration of function 'exp'
办法: #include <math.h>
将动态库和测试代码一起编译连接成可执行文件时,会遇到下面链接问题
4)undefined reference to 'HI_MPI_SYS_Init'
: 要链接 libmpi.a。 可以使用readelf -s libmpi.a | grep HI_MPI_SYS_Init或nm命令来查询该接口是否在该库里面提供。
5) undefined reference to 'exp' or 'memcpy_s'等
:要链接math,libsecure.a等库。
6)undefined reference to 'dlopen' or 'dlerror' or 'dlclose'
: 编译参数里面添加 -ldl,表示支持显示加载动态库。
速度优化
7)指定硬件浮点单元来加速cpu的浮点数运算速度
添加: -mfloat-abi=softfp -mfpu=neon-vfpv4
结论
最后的编译成可运行的动态库命令如下所示供大家参考。
在ubuntu上编译测试代码main成可执行文件时,可以通过-L来指定libnnie_ai.so所在路径,但在板子上运行时,由于平台环境差距较大,往往导致加载so文件失败。所以需要通过更新LD_LIBARARY_PATH或ld.so.conf或拷贝到系统目录/lib 或 /usr/lib来进行解决,具体可以参考另外一篇博文:Linux下头文件以及库编译链接运行时的搜寻路径顺序
版权声明:本文为CSDN博主「ltshan139」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/avideointerfaces/article/details/96141090
海思AI芯片系列文章
- 海思AI芯片(Hi3519A/3559A)方案学习(十七)开发板上运行yolo3模型的代码分析
- 海思AI芯片(Hi3519A/3559A)方案学习(十六)对图像进行不变形缩放,可以提高识别准确度
- 海思AI芯片(Hi3519A/3559A)方案学习(十五)基于nnie引擎进行推理的仿真代码浅析
更多海思AI芯片方案学习笔记欢迎关注海思AI芯片方案学习。