如何学习TensorFlow源码

如何学习TensorFlow源码,第1张

如果从源码构建TensorFlow会需要执行如下命令:

bazel build -c opt //tensorflow/tools/pip_package:build_pip_package

对应的BUILD文件的rule为:

sh_binary(

name = "build_pip_package",

srcs = ["build_pip_package.sh"],

data = [

"MANIFEST.in",

"README",

"setup.py",

"//tensorflow/core:framework_headers",

":other_headers",

":simple_console",

"//tensorflow:tensorflow_py",

"//tensorflow/examples/tutorials/mnist:package",

"//tensorflow/models/embedding:package",

"//tensorflow/models/image/cifar10:all_files",

"//tensorflow/models/image/mnist:convolutional",

"//tensorflow/models/rnn:package",

"//tensorflow/models/rnn/ptb:package",

"//tensorflow/models/rnn/translate:package",

"//tensorflow/tensorboard",

],

)

sh_binary在这里的主要作用是生成data的这些依赖。一个一个来看,一开始的三个文件MANIFEST.in、README、setup.py是直接存在的,因此不会有什么 *** 作。

“//tensorflow/core:framework_headers”:其对应的rule为:

filegroup(

name = "framework_headers",

srcs = [

"framework/allocator.h",

......

"util/device_name_utils.h",

],

)

这里filegroup的作用是给这一堆头文件一个别名,方便其他rule引用。

“:other_headers”:rule为:

transitive_hdrs(

name = "other_headers",

deps = [

"//third_party/eigen3",

"//tensorflow/core:protos_all_cc",

],

)

transitive_hdrs的定义在:

load("//tensorflow:tensorflow.bzl", "transitive_hdrs")

实现为:

# Bazel rule for collecting the header files that a target depends on.

def _transitive_hdrs_impl(ctx):

outputs = set()

for dep in ctx.attr.deps:

outputs += dep.cc.transitive_headers

return struct(files=outputs)

_transitive_hdrs = rule(attrs={

"deps": attr.label_list(allow_files=True,

providers=["cc"]),

},

implementation=_transitive_hdrs_impl,)

def transitive_hdrs(name, deps=[], **kwargs):

_transitive_hdrs(name=name + "_gather",

deps=deps)

native.filegroup(name=name,

srcs=[":" + name + "_gather"])

其作用依旧是收集依赖需要的头文件。

“:simple_console”:其rule为:

py_binary(

name = "simple_console",

srcs = ["simple_console.py"],

srcs_version = "PY2AND3",

deps = ["//tensorflow:tensorflow_py"],

)

py_library(

name = "tensorflow_py",

srcs = ["__init__.py"],

srcs_version = "PY2AND3",

visibility = ["//visibility:public"],

deps = ["//tensorflow/python"],

)

simple_console.py的代码的主要部分是:

from __future__ import absolute_import

from __future__ import division

from __future__ import print_function

import code

import sys

def main(_):

"""Run an interactive console."""

code.interact()

return 0

if __name__ == '__main__':

sys.exit(main(sys.argv))

可以看到起通过deps = [“//tensorflow/python”]构建了依赖包,然后生成了对应的执行文件。看下依赖的rule规则。//tensorflow/python对应的rule为:

py_library(

name = "python",

srcs = [

"__init__.py",

],

srcs_version = "PY2AND3",

visibility = ["//tensorflow:__pkg__"],

deps = [

":client",

":client_testlib",

":framework",

":framework_test_lib",

":kernel_tests/gradient_checker",

":platform",

":platform_test",

":summary",

":training",

"//tensorflow/contrib:contrib_py",

],

)

这里如果仔细看的话会发现其主要是生成一堆python的模块。从这里貌似可以看出每个python的module都对应了一个rule,且module依赖的module都写在了deps里。特别的,作为一个C++的切入,我们关注下training这个依赖:

py_library(

name = "training",

srcs = glob(

["training/**/*.py"],

exclude = ["**/*test*"],

),

srcs_version = "PY2AND3",

deps = [

":client",

":framework",

":lib",

":ops",

":protos_all_py",

":pywrap_tensorflow",

":training_ops",

],

)

这里其依赖的pywrap_tensorflow的rule为:

tf_py_wrap_cc(

name = "pywrap_tensorflow",

srcs = ["tensorflow.i"],

swig_includes = [

"client/device_lib.i",

"client/events_writer.i",

"client/server_lib.i",

"client/tf_session.i",

"framework/python_op_gen.i",

"lib/core/py_func.i",

"lib/core/status.i",

"lib/core/status_helper.i",

"lib/core/strings.i",

"lib/io/py_record_reader.i",

"lib/io/py_record_writer.i",

"platform/base.i",

"platform/numpy.i",

"util/port.i",

"util/py_checkpoint_reader.i",

],

deps = [

":py_func_lib",

":py_record_reader_lib",

":py_record_writer_lib",

":python_op_gen",

":tf_session_helper",

"//tensorflow/core/distributed_runtime:server_lib",

"//tensorflow/core/distributed_runtime/rpc:grpc_server_lib",

"//tensorflow/core/distributed_runtime/rpc:grpc_session",

"//util/python:python_headers",

],

)

tf_py_wrap_cc为其自己实现的一个rule,这里的.i就是SWIG的interface文件。来看下其实现:

def tf_py_wrap_cc(name, srcs, swig_includes=[], deps=[], copts=[], **kwargs):

module_name = name.split("/")[-1]

# Convert a rule name such as foo/bar/baz to foo/bar/_baz.so

# and use that as the name for the rule producing the .so file.

cc_library_name = "/".join(name.split("/")[:-1] + ["_" + module_name + ".so"])

extra_deps = []

_py_wrap_cc(name=name + "_py_wrap",

srcs=srcs,

swig_includes=swig_includes,

deps=deps + extra_deps,

module_name=module_name,

py_module_name=name)

native.cc_binary(

name=cc_library_name,

srcs=[module_name + ".cc"],

copts=(copts + ["-Wno-self-assign", "-Wno-write-strings"]

+ tf_extension_copts()),

linkopts=tf_extension_linkopts(),

linkstatic=1,

linkshared=1,

deps=deps + extra_deps)

native.py_library(name=name,

srcs=[":" + name + ".py"],

srcs_version="PY2AND3",

data=[":" + cc_library_name])

按照SWIG的正常流程,先要通过swig命令生成我们的wrap的c文件,然后和依赖生成我们的so文件,最后生成一个同名的python文件用于import。这里native.cc_binary和native.py_library做了我们后面的两件事情,而swig命令的执行则交给了_py_wrap_cc。其实现为:

_py_wrap_cc = rule(attrs={

"srcs": attr.label_list(mandatory=True,

allow_files=True,),

"swig_includes": attr.label_list(cfg=DATA_CFG,

allow_files=True,),

"deps": attr.label_list(allow_files=True,

providers=["cc"],),

"swig_deps": attr.label(default=Label(

"//tensorflow:swig")), # swig_templates

"module_name": attr.string(mandatory=True),

"py_module_name": attr.string(mandatory=True),

"swig_binary": attr.label(default=Label("//tensorflow:swig"),

cfg=HOST_CFG,

executable=True,

allow_files=True,),

},

outputs={

"cc_out": "%{module_name}.cc",

"py_out": "%{py_module_name}.py",

},

implementation=_py_wrap_cc_impl,)

_py_wrap_cc_impl的实现为:

# Bazel rules for building swig files.

def _py_wrap_cc_impl(ctx):

srcs = ctx.files.srcs

if len(srcs) != 1:

fail("Exactly one SWIG source file label must be specified.", "srcs")

module_name = ctx.attr.module_name

cc_out = ctx.outputs.cc_out

py_out = ctx.outputs.py_out

src = ctx.files.srcs[0]

args = ["-c++", "-python"]

args += ["-module", module_name]

args += ["-l" + f.path for f in ctx.files.swig_includes]

cc_include_dirs = set()

cc_includes = set()

for dep in ctx.attr.deps:

cc_include_dirs += [h.dirname for h in dep.cc.transitive_headers]

cc_includes += dep.cc.transitive_headers

args += ["-I" + x for x in cc_include_dirs]

args += ["-I" + ctx.label.workspace_root]

args += ["-o", cc_out.path]

args += ["-outdir", py_out.dirname]

args += [src.path]

outputs = [cc_out, py_out]

ctx.action(executable=ctx.executable.swig_binary,

arguments=args,

mnemonic="PythonSwig",

inputs=sorted(set([src]) + cc_includes + ctx.files.swig_includes +

ctx.attr.swig_deps.files),

outputs=outputs,

progress_message="SWIGing {input}".format(input=src.path))

return struct(files=set(outputs))

这里的ctx.executable.swig_binary是一个shell脚本,内容为:

# If possible, read swig path out of "swig_path" generated by configure

SWIG=swig

SWIG_PATH=tensorflow/tools/swig/swig_path

if [ -e $SWIG_PATH ]then

SWIG=`cat $SWIG_PATH`

fi

# If this line fails, rerun configure to set the path to swig correctly

"$SWIG" "$@"

可以看到起就是调用了swig命令。

“//tensorflow:tensorflow_py”:其rule为:

py_library(

name = "tensorflow_py",

srcs = ["__init__.py"],

srcs_version = "PY2AND3",

visibility = ["//visibility:public"],

deps = ["//tensorflow/python"],

)

TensorFlow是编程语言Python,C++,CUDA。

TensorFlow™是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现,其前身是谷歌的神经网络算法库DistBelief。

Tensorflow拥有多层级结构,可部署于各类服务器、PC终端和网页并支持GPU和TPU高性能数值计算,被广泛应用于谷歌内部的产品开发和各领域的科学研究。

TensorFlow由谷歌人工智能团队谷歌大脑(Google Brain)开发和维护,拥有包括TensorFlow Hub、TensorFlow Lite、TensorFlow Research Cloud在内的多个项目以及各类应用程序接口(Application Programming Interface, API)。

自2015年11月9日起,TensorFlow依据阿帕奇授权协议(Apache 2.0 open source license)开放源代码。

扩展资料:

TensorFlow的核心组件:

分布式TensorFlow的核心组件(core runtime)包括:分发中心(distributed master)、执行器(dataflow executor/worker service)、内核应用(kernel implementation)和最底端的设备层(device layer)/网络层(networking layer)。

分发中心从输入的数据流图中剪取子图(subgraph),将其划分为 *** 作片段并启动执行器。分发中心处理数据流图时会进行预设定的 *** 作优化,包括公共子表达式消去(common subexpression elimination)、常量折叠(constant folding)等。

执行器负责图 *** 作(graph operation)在进程和设备中的运行、收发其它执行器的结果。分布式TensorFlow拥有参数器(parameter server)以汇总和更新其它执行器返回的模型参数。执行器在调度本地设备时会选择进行并行计算和GPU加速。

TensorFlow的安装:

语言与系统支持

1、Python

TensorFlow提供Python语言下的四个不同版本:CPU版本(tensorflow)、包含GPU加速的版本(tensorflow-gpu),以及它们的每日编译版本(tf-nightly、tf-nightly-gpu)。

TensorFlow的Python版本支持Ubuntu 16.04、Windows 7、macOS 10.12.6 Sierra、Raspbian 9.0及对应的更高版本,其中macOS版不包含GPU加速。安装Python版TensorFlow可以使用模块管理工具pip/pip3或anaconda并在终端直接运行。

2、配置GPU

TensorFlow支持在Linux和Window系统下使用统一计算架构(Compute Unified Device Architecture, CUDA)高于3.5的NVIDIA GPU。

配置GPU时要求系统有NVIDIA GPU驱动384.x及以上版本、CUDA Toolkit和CUPTI(CUDA Profiling Tools Interface)9.0版本、cuDNN SDK7.2以上版本。可选配置包括NCCL 2.2用于多GPU支持、TensorRT 4.0用于TensorFlow模型优化。

参考资料来源:百度百科-TensorFlow


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11206163.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存