| 111 | // code in tensorflow/python/framework/function.py. |
| 112 | |
| 113 | Status GraphToFunctionDef(const Graph& graph, const string& name, |
| 114 | const ControlRetMapping& control_ret, |
| 115 | FunctionDef* fdef) { |
| 116 | fdef->mutable_signature()->set_name(name); |
| 117 | |
| 118 | std::unordered_map<string, string> tensor_renaming; |
| 119 | std::unordered_map<string, string> return_values; |
| 120 | NodeNameMapping node_names; |
| 121 | |
| 122 | for (Node const* node : graph.op_nodes()) { |
| 123 | if (node->IsArg()) { |
| 124 | int index; |
| 125 | DataType type; |
| 126 | TF_RETURN_IF_ERROR(GetNodeAttr(node->attrs(), "T", &type)); |
| 127 | TF_RETURN_IF_ERROR(GetNodeAttr(node->attrs(), "index", &index)); |
| 128 | while (fdef->signature().input_arg_size() <= index) { |
| 129 | fdef->mutable_signature()->add_input_arg(); |
| 130 | } |
| 131 | OpDef::ArgDef* argdef = |
| 132 | fdef->mutable_signature()->mutable_input_arg(index); |
| 133 | argdef->set_type(type); |
| 134 | const string normalized = node_names.Normalize(node->name()); |
| 135 | argdef->set_name(normalized); |
| 136 | tensor_renaming[strings::StrCat(node->name(), ":0")] = normalized; |
| 137 | continue; |
| 138 | } |
| 139 | |
| 140 | if (node->IsRetval()) { |
| 141 | int index; |
| 142 | DataType type; |
| 143 | TF_RETURN_IF_ERROR(GetNodeAttr(node->attrs(), "T", &type)); |
| 144 | TF_RETURN_IF_ERROR(GetNodeAttr(node->attrs(), "index", &index)); |
| 145 | while (fdef->signature().output_arg_size() <= index) { |
| 146 | fdef->mutable_signature()->add_output_arg(); |
| 147 | } |
| 148 | OpDef::ArgDef* argdef = |
| 149 | fdef->mutable_signature()->mutable_output_arg(index); |
| 150 | argdef->set_type(type); |
| 151 | const string normalized = node_names.Normalize(node->name()); |
| 152 | argdef->set_name(normalized); |
| 153 | Edge const* edge; |
| 154 | TF_RETURN_IF_ERROR(node->input_edge(0, &edge)); |
| 155 | return_values[normalized] = |
| 156 | strings::StrCat(edge->src()->name(), ":", edge->src_output()); |
| 157 | continue; |
| 158 | } |
| 159 | |
| 160 | NodeDef* node_def = fdef->add_node_def(); |
| 161 | *node_def = node->def(); |
| 162 | if (!node->assigned_device_name().empty()) { |
| 163 | node_def->set_device(node->assigned_device_name()); |
| 164 | } |
| 165 | node_def->set_name(node_names.Uniquify(node->name())); |
| 166 | MergeDebugInfo(NodeDebugInfo(node->def()), node_def); |
| 167 | |
| 168 | // Check if a node must be a part of control return set. |
| 169 | absl::optional<string> maybe_control_ret = |
| 170 | control_ret ? control_ret(node) : absl::nullopt; |