Creates executors given a graph definition "gdef" of a "session". If a node in "gdef" is shared by other graphs in "session", the same op kernel is reused. E.g., typically a params node is shared by multiple graphs in a session. If "gdef" is assigned to multiple devices, extra nodes (e.g., send/recv nodes) maybe added. The extra nodes' name are generated by calling "new_name(old_name)". "executo
| 126 | // "executors" are filled with one executor per device if success and |
| 127 | // the caller takes the ownership of returned executors. |
| 128 | Status GraphMgr::InitItem(const string& handle, const GraphDef& gdef, |
| 129 | WorkerSession* session, |
| 130 | const GraphOptions& graph_options, |
| 131 | const DebugOptions& debug_options, |
| 132 | int64 collective_graph_key, |
| 133 | DistributedFunctionLibraryRuntime* cluster_flr, |
| 134 | Item* item) { |
| 135 | item->session = handle; |
| 136 | item->collective_graph_key = collective_graph_key; |
| 137 | item->lib_def.reset( |
| 138 | new FunctionLibraryDefinition(OpRegistry::Global(), gdef.library())); |
| 139 | |
| 140 | TF_RETURN_IF_ERROR(ValidateGraphDefForDevices(gdef)); |
| 141 | |
| 142 | if (gdef.versions().producer() >= 5) { |
| 143 | // Validate the graph: we assume that merging two valid graphs |
| 144 | // should maintain graph validity. |
| 145 | TF_RETURN_IF_ERROR(graph::ValidateGraphDef(gdef, *item->lib_def)); |
| 146 | } |
| 147 | |
| 148 | item->proc_flr.reset(new ProcessFunctionLibraryRuntime( |
| 149 | device_mgr_, worker_env_->env, gdef.versions().producer(), |
| 150 | item->lib_def.get(), graph_options.optimizer_options(), |
| 151 | worker_env_->compute_pool, cluster_flr)); |
| 152 | |
| 153 | // Constructs the graph out of "gdef". |
| 154 | Graph graph(OpRegistry::Global()); |
| 155 | GraphConstructorOptions opts; |
| 156 | opts.allow_internal_ops = true; |
| 157 | opts.expect_device_spec = true; |
| 158 | TF_RETURN_IF_ERROR(ConvertGraphDefToGraph(opts, gdef, &graph)); |
| 159 | |
| 160 | // Splits "graph" into multiple subgraphs by device names. |
| 161 | std::unordered_map<string, GraphDef> partitions; |
| 162 | PartitionOptions popts; |
| 163 | popts.node_to_loc = SplitByDevice; |
| 164 | popts.new_name = [this](const string& prefix) { |
| 165 | mutex_lock l(mu_); |
| 166 | return strings::StrCat(prefix, "_G", next_id_++); |
| 167 | }; |
| 168 | popts.get_incarnation = [this](const string& name) -> int64 { |
| 169 | Device* device = nullptr; |
| 170 | Status s = device_mgr_->LookupDevice(name, &device); |
| 171 | if (s.ok()) { |
| 172 | return device->attributes().incarnation(); |
| 173 | } else { |
| 174 | return PartitionOptions::kIllegalIncarnation; |
| 175 | } |
| 176 | }; |
| 177 | popts.flib_def = &graph.flib_def(); |
| 178 | popts.control_flow_added = true; |
| 179 | popts.scheduling_for_recvs = graph_options.enable_recv_scheduling(); |
| 180 | TF_RETURN_IF_ERROR(Partition(popts, &graph, &partitions)); |
| 181 | if (popts.scheduling_for_recvs) { |
| 182 | TF_RETURN_IF_ERROR(AddControlEdges(popts, &partitions)); |
| 183 | } |
| 184 | |
| 185 | std::unordered_map<string, std::unique_ptr<Graph>> partition_graphs; |
nothing calls this directly
no test coverage detected