ForwardFanins forwards fanins of a node to be removed to its fanouts. This currently is specific to nodes defined in `IsTrivialOp` under the assumption they can have at most one regular fanin (at index 0) and one regular fanout index (at 0). The forwarding is as follows: If the node to be removed has a regular fanin (at index 0), that fanin will be forwarded by replacing the fanin (consisting of
| 168 | // controlled fanout. |
| 169 | // TODO(lyandy): Move this to a shared util for GraphView. |
| 170 | Status ForwardFanins(utils::MutableGraphView* graph_view, int node_to_delete, |
| 171 | absl::flat_hash_set<int>* mutated_fanouts) { |
| 172 | utils::Mutation* mutation = graph_view->GetMutationBuilder(); |
| 173 | auto* node_view = graph_view->GetNode(node_to_delete); |
| 174 | std::vector<absl::string_view> controlling_fanin_names; |
| 175 | controlling_fanin_names.reserve(node_view->NumControllingFanins()); |
| 176 | for (const auto& controlling_fanin : node_view->GetControllingFanins()) { |
| 177 | controlling_fanin_names.push_back(controlling_fanin.node_view()->GetName()); |
| 178 | } |
| 179 | const auto& node_regular_fanin_0 = node_view->GetRegularFanin(0); |
| 180 | const bool has_regular_fanin_0 = node_view->NumRegularFanins() >= 1; |
| 181 | const string regular_fanin_0_name = |
| 182 | has_regular_fanin_0 ? node_regular_fanin_0.node_view()->GetName() : ""; |
| 183 | |
| 184 | // Forward to regular fanouts. |
| 185 | if (has_regular_fanin_0) { |
| 186 | TensorId tensor_id(regular_fanin_0_name, node_regular_fanin_0.index()); |
| 187 | for (const auto& fanout : node_view->GetRegularFanout(0)) { |
| 188 | auto* fanout_node_view = fanout.node_view(); |
| 189 | mutation->AddOrUpdateRegularFanin(fanout_node_view, fanout.index(), |
| 190 | tensor_id); |
| 191 | for (const auto& controlling_fanin : controlling_fanin_names) { |
| 192 | mutation->AddControllingFanin(fanout_node_view, controlling_fanin); |
| 193 | } |
| 194 | mutated_fanouts->emplace(fanout.node_index()); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | // Forward to controlled fanouts. |
| 199 | for (const auto& controlled_fanout : node_view->GetControlledFanouts()) { |
| 200 | auto* fanout_node_view = controlled_fanout.node_view(); |
| 201 | mutation->RemoveControllingFanin(fanout_node_view, node_view->GetName()); |
| 202 | if (has_regular_fanin_0) { |
| 203 | mutation->AddControllingFanin(fanout_node_view, regular_fanin_0_name); |
| 204 | } |
| 205 | for (const auto& controlling_fanin : controlling_fanin_names) { |
| 206 | mutation->AddControllingFanin(fanout_node_view, controlling_fanin); |
| 207 | } |
| 208 | mutated_fanouts->emplace(controlled_fanout.node_index()); |
| 209 | } |
| 210 | |
| 211 | return mutation->Apply(); |
| 212 | } |
| 213 | |
| 214 | absl::flat_hash_map<int, std::vector<bool>> IdentityNTerminalPorts( |
| 215 | const utils::MutableGraphView& graph_view, |
no test coverage detected