TVM中C代码和python代码结构
前言
伴随着python的崛起以及神经网络的广泛运用,python被越来越多人所使用。特别是现在“算法工程师”大部分都是用的是python来训练网络,但是python在边缘侧和端侧的性能不足会是一个部署所面临的严峻问题。因此TVM通过python的前端来解析网络,将网络通过编译生成高性能的模型固件,从而能够基本达到部署的条件。这篇文章主要学习python和C之间配合,来进行前后端的配合。此篇文章以linux环境为例。
打开与调用逻辑——_ffi_api模块
在TVM中,会把C有关的代码,编译成动态库。然后通过python代码CDLL来打开,并调用其中的函数。
所有TVM中C和python的交互都是通过模块_ffi模块来进行的。
- 在python启动,import tvm开始就会自动开始load所需的库。如下图所示,主要通过python\tvm_ffi\base.py中的_load_lib。通过定义相关环境变量,可以设置load library所查找的路径。最后通过ctypes.CDLL来打开动态库,可以来使用动态库中的函数。
- 通过初始化函数_init_api来对打开的动态库中所需使用的函数放入到module中。如下图所示,首先会通过list_global_func_name函数调用_LIB的TVMFuncListGlobalNames,获取在_LIB所注册的函数。再通过注册函数的name来查找函数指针,通过setattr来把构造的函数handle放入到module中。
通过上述两个步骤,可以把C动态库中约定注册的函数拿出来进行使用。如在python\tvm\ir中所需要初始化的api:
tvm._ffi._init_api("ir", __name__