图是我们最熟悉的基本结构,从我们一开始使用tensorflow就会接触到这个概念,graph的类结构同样定义咋一个proto中tensorflow/core/framework/graph.proto。
syntax = "proto3";
package tensorflow;
import "tensorflow/core/framework/function.proto";
import "tensorflow/core/framework/node_def.proto";
import "tensorflow/core/framework/versions.proto";
option cc_enable_arenas = true;
option java_outer_classname = "GraphProtos";
option java_multiple_files = true;
option java_package = "org.tensorflow.framework";
option go_package = "github.com/tensorflow/tensorflow/tensorflow/go/core/framework/graph_go_proto";
// Represents the graph of operations
message GraphDef {
repeated NodeDef node = 1;
// Compatibility versions of the graph. See core/public/version.h for version
// history. The GraphDef version is distinct from the TensorFlow version, and
// each release of TensorFlow will support a range of GraphDef versions.
VersionDef versions = 4;
// Deprecated single version field; use versions above instead. Since all
// GraphDef changes before "versions" was introduced were forward
// compatible, this field is entirely ignored.
int32 version = 3 [deprecated = true];
// "library" provides user-defined functions.
//
// Naming:
// * library.function.name are in a flat namespace.
// NOTE: We may need to change it to be hierarchical to support
// different orgs. E.g.,
// { "/google/nn", { ... }},
// { "/google/vision", { ... }}
// { "/org_foo/module_bar", { ... }}
// map<string, FunctionDefLib> named_lib;
// * If node[i].op is the name of one function in "library",
// node[i] is deemed as a function call. Otherwise, node[i].op
// must be a primitive operation supported by the runtime.
//
//
// Function call semantics:
//
// * The callee may start execution as soon as some of its inputs
// are ready. The caller may want to use Tuple() mechanism to
// ensure all inputs are ready in the same time.
//
// * The consumer of return values may start executing as soon as
// the return values the consumer depends on are ready. The
// consumer may want to use Tuple() mechanism to ensure the
// consumer does not start until all return values of the callee
// function are ready.
FunctionDefLibrary library = 2;
}
他的类结构非常简单,最核心的基本就是一个node,其他就没了。因为若干个node本身就包含了整个图的信息,所以不需要在图上再定义什么复杂的东西。
在图构建完成以后,会把图做一些分割,相同的节点会放在一个子图中,然后在运行图的过程中,运行各个子图。
在文件tensorflow/core/graph/graph_def_builder.h 中是graphDef的定义中,除了proto定义的属性,还提供了一个子类options
class Options {
public:
// Sets the Graph (that Nodes will be added to) and the status. The
// status may be set to nullptr, in which case errors cause CHECK
// failures. The graph and status must outlive *this.
Options(Graph* graph, Status* status);
~Options();
// Methods for setting options. These are const methods: they
// return a copy of *this with the option set.
Options WithName(StringPiece name) const;
Options WithDevice(StringPiece device) const;
Options WithControlInput(Node* control_input) const;
Options WithControlInputs(gtl::ArraySlice<Node*> control_inputs) const;
// Override the default value for an optional attr.
template <class T>
Options WithAttr(StringPiece attr_name, T&& value) const {
return Options(*this).WithAttrImpl(attr_name, std::forward<T>(value));
}
// Note: overload needed to allow {...} expressions for value.
template <class T>
Options WithAttr(StringPiece attr_name,
std::initializer_list<T> value) const {
return WithAttr<std::initializer_list<T>>(attr_name, std::move(value));
}
// Methods for using options from a function that creates a Node.
// Returns true if the status associated with *this has an error.
// Use this to skip processing that may depend on prior results.
bool HaveError() const { return status_ != nullptr && !status_->ok(); }
// Returns a string representation of the status associated with *this.
// Returns the string `"OK"` if the status doesn't have any error.
string StatusToString() const {
return status_->ok() ? "OK" : status_->error_message();
}
// Given the Op type name, return a name for a node of that type.
// Uses the value set in WithName() if that has been called. Otherwise,
// returns a name built out of the Op type name.
string GetNameForOp(StringPiece op) const;
// Sets the device, adds control inputs, adds attrs, and calls Finalize().
// If Finalize returns an error, it is saved and this function returns
// nullptr.
Node* FinalizeBuilder(NodeBuilder* builder) const;
// Updates the associated status, if any, or calls TF_CHECK_OK if none.
void UpdateStatus(const Status& status) const;
// Accessor
const OpRegistryInterface* op_registry() const {
return graph_->op_registry();
}
private:
Options WithNameImpl(StringPiece name);
Options WithDeviceImpl(StringPiece device);
Options WithControlInputImpl(Node* control_input);
Options WithControlInputsImpl(gtl::ArraySlice<Node*> control_inputs);
template <class T>
Options WithAttrImpl(StringPiece name, T&& value) {
attrs_.emplace_back(string(name), AttrValue());
SetAttrValue(std::forward<T>(value), &attrs_.back().second);
return *this;
}
Graph* const graph_;
Status* const status_;
string name_;
string device_;
std::vector<Node*> control_inputs_;
std::vector<std::pair<string, AttrValue>> attrs_;
};