| 222 | Mutation::Mutation(MutableGraphView* graph_view) : graph_view_(graph_view) {} |
| 223 | |
| 224 | MutationNewNode Mutation::AddNode(NodeDef&& node, Status* status) { |
| 225 | bool has_observed_control = false; |
| 226 | const string& node_name = node.name(); |
| 227 | std::vector<SafeTensorId> regular_fanins; |
| 228 | absl::flat_hash_set<string> controlling_fanins; |
| 229 | const int num_fanins = node.input_size(); |
| 230 | for (int i = 0; i < num_fanins; ++i) { |
| 231 | const string& input = node.input(i); |
| 232 | TensorId fanin_id = ParseTensorName(input); |
| 233 | if (fanin_id.node() == node_name) { |
| 234 | *status = |
| 235 | errors::InvalidArgument(kMutationAddNodeError, "node '", node_name, |
| 236 | "' has self cycle fanin '", input, "'."); |
| 237 | return MutationNewNode(this, mutation_counter_, internal::kMissingIndex); |
| 238 | } |
| 239 | bool is_control = IsTensorIdControl(fanin_id); |
| 240 | if (is_control) { |
| 241 | has_observed_control = true; |
| 242 | controlling_fanins.emplace(fanin_id.node()); |
| 243 | } else if (has_observed_control) { |
| 244 | *status = errors::InvalidArgument(kMutationAddNodeError, "node '", |
| 245 | node_name, "' has regular fanin '", |
| 246 | input, "' after controlling fanins."); |
| 247 | return MutationNewNode(this, mutation_counter_, internal::kMissingIndex); |
| 248 | } else { |
| 249 | regular_fanins.emplace_back(fanin_id); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | node.mutable_input()->Clear(); |
| 254 | new_nodes_.emplace_back(graph_view_, std::move(node)); |
| 255 | MutationNewNodeHolder& mutation_node = new_nodes_.back(); |
| 256 | mutation_node.regular_fanins = std::move(regular_fanins); |
| 257 | mutation_node.num_regular_fanins = mutation_node.regular_fanins.size(); |
| 258 | mutation_node.controlling_fanins = std::move(controlling_fanins); |
| 259 | *status = Status::OK(); |
| 260 | return MutationNewNode(this, mutation_counter_, new_nodes_.size() - 1); |
| 261 | } |
| 262 | |
| 263 | void Mutation::AddMutation( |
| 264 | MutableNodeView* node, |