标签:out 构建 开发 int 集合 图结构 map nali tput
TF中的图由节点构成,每个节点包含了一个操作,表名这个节点的作用,比如,将两个输入矩阵相乘,输出结果。节点是自带图结构的,每个节点都包含了输入的来源,因此若干节点的集合就能无需其它信息的生成一张图。节点必须被放置在某一个设备上,为了减少跨设备传输数据,也为了提高计算效率,TF还专门开发了相应的节点放置算法。
我们先来看一下节点的定义:
message NodeDef {
string name = 1;//节点名称
string op = 2;//节点包含的操作名称
repeated string input = 3;//节点的输入,详见正文
string device = 4;//节点所在的设备
map<string, AttrValue> attr = 5;//节点包含的op,其参数的具体赋值
};
由于节点对于后续理解graph和kernel非常重要,因此我们详细分析一下它包含的字段:
"/job:worker/replica:0/task:1/gpu:3"
,也可以是局部限定的,比如"/job:worker/gpu:3"
,也可以不限定。因此这个字段指代的,可能不是某一个具体的设备,这就需要上文提到的节点放置算法,对节点所在的设备进行选择了。也就是说,device这个字段有些情况下只是给节点所在的设备限制了一个粗略的条件,节点放置算法需要在考虑这些条件的基础上,为节点选择合适的设备。关于节点放置算法的细节,我们将在后面详述。按照惯例,TF会给每一个核心概念设计一个构建类,node也不例外,这个类就是NodeDefBuilder。我们先来看一下它的用法:
NodeDef node_def;
Status status = NodeDefBuilder(node_name, op_name)
.Input(...)
.Attr(...)
.Finalize(&node_def);
可见,与OpDefBuilder类似,我们也可以采用链式规则,通过逐个设置NodeDef的字段来构建它。下面我们看下NodeDefBuilder包含的私有数据:
class NodeDefBuilder {
private:
const OpDef* op_def_;
NodeDef node_def_;
int inputs_specified_;
std::vector<string> control_inputs_;
std::vector<string> errors_;
};
这里之所以会包含OpDef,是因为在NodeDef中,仅包含了操作的名称。
标签:out 构建 开发 int 集合 图结构 map nali tput
原文地址:https://www.cnblogs.com/jicanghai/p/9540261.html