您找不到此源,因为源是由bazel自动生成的.如果你从source构建,你会在bazel-genfiles中看到这个文件.它也出现在您当地的发行版中,您可以使用检查模块找到它.该文件包含自动生成的Python包装器到底层C实现,因此它基本上由一堆1行函数组成.查找此类生成的Python操作的基础C实现的快捷方式是将snake case转换为camel case,即conv2d_backprop_input – > Conv2dBackpropInput
# figure out where gen_nn_ops is
print(tf.nn.conv2d_transpose.__globals__['gen_nn_ops'])
from tensorflow.python.ops import gen_nn_ops
import inspect
inspect.getsourcefile('gen_nn_ops.conv2d_backprop_input')
'/Users/yaroslav/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/gen_nn_ops.py'
如果你想知道这个文件是如何实现的,你可以跟随BUILD文件中的bazel依赖关系.它找到从tensorflow源树生成它的Bazel目标:
fullname=$(bazel query tensorflow/python/ops/gen_nn_ops.py)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
//tensorflow/python:nn_ops_gen
所以现在转到tensorflow / python中的BUILD文件,你会发现这是一个类型为tf_gen_op_wrapper_private_py的目标,它定义为here,并从tensorflow / tensorflow.bzl调用gen_op_wrapper_py,看起来像这样
def tf_gen_op_wrapper_py(name, out=None, hidden=None, visibility=None, deps=[],
....
native.cc_binary(
name = tool_name,
这个native.cc_binary构造是一种让Bazel目标表示任意命令执行的方法.在这种情况下,它使用一些参数调用tool_name.通过几个步骤,您可以发现这里的“工具”是从framework/python_op_gen_main.cc开始编译的
造成这种复杂情况的原因是TensorFlow被设计为与语言无关.因此,在理想世界中,您将拥有ops.pbtxt中描述的每个操作,然后每个操作将使用REGISTER_KERNEL_BUILDER为每个硬件类型实现一个实现,因此所有实现都将在C/C++UDA / Assembly中完成,并自动可用于所有语言前端.对于每种语言都会有一个等效的翻译操作,例如“python_op_gen_main”,并且将自动生成所有客户端库代码.但是,由于Python占据主导地位,因此在Python方面添加功能的压力很大.所以现在有两种操作 – 在gen_nn_ops.py这样的文件中看到的纯TensorFlow操作,在nn_ops.py这样的文件中只有Python操作,它们通常包含ops自动生成的文件gen_nn_ops.py但是添加了额外的功能/语法糖.此外,最初所有名称都是驼峰式的,但是决定面向公众的版本应该符合更常见的Python语法的PEP,所以这是同一操作的C / Python接口之间的驼峰/蛇案例不匹配的原因