-
Notifications
You must be signed in to change notification settings - Fork 45
mxnet如何从python调用cpp?
发现不少人关心这个问题.简单的说一下这个基本过程吧.
在base.py中调用ctypes.CDLL加载mxnet.dll.然后装入全局变量_Lib中.
首先检查MXNET_ENABLE_CYTHON环境变量检测CYTHON是否启用. 如启用,根据python版本导入对应的CYTHON版本的SymbolBase类,_set_symbol_class,和_symbol_creator函数 如果没有则导入ctypes版本的SymbolBase类,_set_symbol_class,和_symbol_creator函数
随后以python类SymbolBase(上面导入的)为基类定义python类Symbol,该类是对应c++中的Symbol的包装.这里不展开说了.
最后调用_init_symbol_module开始关键的初始化过程.在symbol这个python module中注入用来创建op的代理函数.就是比如mx.symbol.FullyConnected这样的函数
以下全部C函数的调用通过ctypes实现,用的是全局变量_Lib
1.用python类Symbol为参数调用_set_symbol_class,该函数将python类Symbol保存在_symbol_cls备用
2.调用C函数MXListAllOpNames.获取全部op的名字
3.遍历每一个op名字.调用C函数NNGetOpHandle得到op的Handle
4.通过Handle调用C函数MXSymbolGetAtomicSymbolInfo获取op的详细信息
5.根据op详细信息动态构造python函数.该函数就是创建op用的代理函数(代理函数的功能在下一节)
6.将5中构造的函数动态注入mxnet.symbol模块(部分op注入到其他模块)
最后当你调用比如mx.symbol.FullyConnected时.就会调用FullyConnected对应的在5中创建的函数.
以下全部C函数的调用通过ctypes实现,同样用的是全局变量_Lib
1.调用C函数MXSymbolCreateAtomicSymbol来创建Symbol实例
2.然后用返回的SymbolHandle调用_symbol_cls(前面保存的)创建python类Symbol的实例.这样一个python类Symbol的实例就和一个c++中的Symbol实例对应起来了
3.接受参数,比如
mx.symbol.FullyConnected(data=data, weight=w, name="fc1", num_hidden=128)
用这些参数调用Symbol._compose
4._compose用传入的参数调用C函数MXSymbolCompose,MXSymbolCompose会根据这些参数,完成Symbol组装.