tensorflow源码分析
前⾔:
⼀般来说,如果安装tensorflow主要⽬的是为了调试些⼩程序的话,只要下载相应的包,然后,直接使⽤pip install tensorflow即可。
但有时我们需要将Tensorflow的功能移植到其它平台,这时就⽆法直接安装了。需要我们下载相应的Tensorflow源码,⾃已动⼿编译了。正⽂:
Tensorflow功能代码庞⼤,结构复杂;如何快速了解源码结构,就显⽰尤为重要了。
Tensorflow主体结构:
整个框架以C API为界,分为前端和后端两⼤部分。
前端:提供编译模型,多语⾔接⼝⽀持,如:python,java,c++等。
后端:提供运⾏环境,完成计算图执⾏,⼤致可分为4层:
运⾏层:分布式运⾏时和本地运⾏时,负责计算图的接收,构造,编排等;
计算层:提供各算⼦的内核实现,例如: conv2d,relu等;
通信层:实现组件间数据通信,基于GRPC,RDMA两种通信⽅式;
设备层:提供多种异构设备⽀持,如:CPU,GPU,TPU,FPGA等;
模型构造和执⾏流程:
Tensorflow图的构造与执⾏是分开的,⽤户添加完算⼦,构建好图后,才开始进⾏训练和执⾏。
流程如下:
       1、图构建:⽤户在Client中基于Tensorflow的多语⾔编程接⼝,添加算⼦,完成计算图的构造;
2、图传递:Client开启Session,通过它建⽴和Master之间的连接,执⾏Session.run()时,将构造好的graph序列化为graphdef后,以protobuf格式传递给master。
3、图剪枝:master 根据session.run()传递的fetches和feeds列表,反向遍历全图full graph,实施剪枝,得到最⼩依赖⼦图;
4、图分裂:master将最⼩⼦图分裂为多个graph partition,并注册到多个worker上,⼀个worker对应⼀个graph partition;
5、图⼆次分裂:worker根据当前可⽤硬件资源,如CPU,GPU,将graph partition按照op算⼦设备约束规范(例如:
tf.device('/cpu:0')),⼆次分裂到不同设备上。每个计算设备对应⼀个 graph partition.
6、图运⾏:对于每⼀个计算设备,worker依照op在kernel中的实现,完成op的运算。设备间数据通信可以使⽤send/recv节点,⽽worker间通信,则使⽤GRPC或RDMA协议。
前端多语⾔实现:Swig包装器
Tensorflow提供了多种语⾔的前端接⼝,使得⽤户可以通过多种语⾔来完成模型的训练和推断。如何实现要归功于swig包装器。
swig是⼀个帮助C或C++编写的软件能与其它各种⾼级编程语⾔进⾏嵌⼊联接的开发⼯具,在Tensorflow使⽤bazel编译时,swig会⽣成两个wrapper⽂件:
1、pywrap_tensorflow_internal.py      :对接上层Python调⽤
2、pywrap_      :对接底层C API调⽤
pywrap_tensorflow_internal.py模块被导⼊时,会加载_pywrap_tensorflow_internal.so动态链接库,⾥⾯包含所有运⾏时接⼝符号。⽽在pywrap_中,注册了⼀个函数符号表,实现python接⼝和C接⼝的映射。运⾏时,可以通过映射表,到python接⼝在C层的实现。
Tensorflow源码结构
Tensorflow源码基本按照框架分层来组织⽂件,如下图:
其中⽬录core是tensorflow的核⼼,源码结构如下:
session下载
Session:
Session是连接前后端的桥梁,⽤户可利⽤session使得client能够与master的执⾏引擎建⽴连接,通过session.run()来触发⼀次计算。
Session创建时,系统会分配⼀些资源,如graph引⽤,连接的计算引擎名称等,所以,计算完毕后,需要使⽤session.close()关闭session,避免引起内存泄漏,特别是graph⽆法释放问题。可以显式调⽤Session.close(),使⽤with上下⽂管理器,或使⽤InteractiveSession()
session之间采⽤共享graph⽅式来提⾼运⾏效率。⼀个session只能运⾏⼀个graph实例,但⼀个graph可以运⾏在多个session 中。在session创建时,不会重新创建graph实例,⽽是默认graph引⽤计算加1.当session close时,引⽤计数减1.只有引⽤计数为0时,graph才会被回收。
在后端master中,根据前端client调⽤tf.session(target='',graph=none,config=none)时指定的target,来创建不同的session.target 为要连接的tf后端执⾏引擎,默认为空字符串。Session创建了抽象⼯⼚模式,如果为空字符串,则创建本地DirectSession,如果以grpc://开头,则创建分布式grpcSession。
DirectSession只能利⽤本地设备,将任务创建在本地的CPU和GPU上。⽽grpcSession可利⽤远端分布式设备,将任务创建在其他机器的CPU,GPU上,然后通过grpc协议通信。
Session⽣命周期,⼤致有4个阶段:
1、创建:通过tf.session()创建,进⾏系统资源分配,特别是graph引⽤计数加1;
2、运⾏:通过session.run()触发计算的执⾏,client会将整图graph传递给master,由master进⾏执⾏;
3、关闭:通过session.close()关闭,进⾏系统资源的回收,graph引⽤计数减1;
4、销毁:Python垃圾回收器进⾏GC时,调⽤ session.__del__()回收。
基本都在python的basesession中,通过swig⾃动⽣成的函数符号映射关系,调⽤C层的实现。
未完待续。。。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。