| 83 | } |
| 84 | |
| 85 | Status ImmutableExecutorState::Initialize() { |
| 86 | const Graph& graph = *graph_; |
| 87 | TF_RETURN_IF_ERROR(gview_.Initialize(&graph)); |
| 88 | |
| 89 | // Build the information about frames in this subgraph. |
| 90 | ControlFlowInfo cf_info; |
| 91 | TF_RETURN_IF_ERROR(BuildControlFlowInfo(&graph, &cf_info)); |
| 92 | |
| 93 | for (auto& it : cf_info.unique_frame_names) { |
| 94 | EnsureFrameInfo(it)->nodes = |
| 95 | absl::make_unique<std::vector<const NodeItem*>>(); |
| 96 | } |
| 97 | root_frame_info_ = frame_info_[""].get(); |
| 98 | |
| 99 | pending_ids_.resize(gview_.num_nodes()); |
| 100 | |
| 101 | // Preprocess every node in the graph to create an instance of op |
| 102 | // kernel for each node. |
| 103 | requires_control_flow_ = false; |
| 104 | for (const Node* n : graph.nodes()) { |
| 105 | if (IsSink(n)) continue; |
| 106 | if (IsSwitch(n) || IsMerge(n) || IsEnter(n) || IsExit(n)) { |
| 107 | requires_control_flow_ = true; |
| 108 | } else if (IsRecv(n)) { |
| 109 | // A Recv node from a different device may produce dead tensors from |
| 110 | // non-local control-flow nodes. |
| 111 | // |
| 112 | // TODO(mrry): Track whether control flow was present in the |
| 113 | // pre-partitioned graph, and enable the caller (e.g. |
| 114 | // `DirectSession`) to relax this constraint. |
| 115 | string send_device; |
| 116 | string recv_device; |
| 117 | TF_RETURN_IF_ERROR(GetNodeAttr(n->attrs(), "send_device", &send_device)); |
| 118 | TF_RETURN_IF_ERROR(GetNodeAttr(n->attrs(), "recv_device", &recv_device)); |
| 119 | if (send_device != recv_device) { |
| 120 | requires_control_flow_ = true; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | const int id = n->id(); |
| 125 | const string& frame_name = cf_info.frame_names[id]; |
| 126 | FrameInfo* frame_info = EnsureFrameInfo(frame_name); |
| 127 | |
| 128 | NodeItem* item = gview_.node(id); |
| 129 | item->node = n; |
| 130 | |
| 131 | item->input_start = frame_info->total_inputs; |
| 132 | frame_info->total_inputs += n->num_inputs(); |
| 133 | |
| 134 | Status s = params_.create_kernel(n->def(), &item->kernel); |
| 135 | if (!s.ok()) { |
| 136 | params_.delete_kernel(item->kernel); |
| 137 | item->kernel = nullptr; |
| 138 | s = AttachDef(s, *n); |
| 139 | return s; |
| 140 | } |
| 141 | CHECK(item->kernel); |
| 142 | item->kernel_is_async = (item->kernel->AsAsync() != nullptr); |
nothing calls this directly
no test coverage detected