| 495 | } |
| 496 | |
| 497 | Status MutableGraphView::UpdateNode( |
| 498 | absl::string_view node_name, absl::string_view op, absl::string_view device, |
| 499 | absl::Span<const std::pair<string, AttrValue>> attrs) { |
| 500 | auto error_status = [node_name, op, device, attrs](absl::string_view msg) { |
| 501 | std::vector<string> attr_strs; |
| 502 | attr_strs.reserve(attrs.size()); |
| 503 | for (const auto& attr : attrs) { |
| 504 | string attr_str = absl::Substitute("('$0', $1)", attr.first, |
| 505 | attr.second.ShortDebugString()); |
| 506 | attr_strs.push_back(attr_str); |
| 507 | } |
| 508 | string params = |
| 509 | absl::Substitute("node_name='$0', op='$1', device='$2', attrs={$3}", |
| 510 | node_name, op, device, absl::StrJoin(attr_strs, ", ")); |
| 511 | return MutationError("UpdateNodeOp", params, msg); |
| 512 | }; |
| 513 | |
| 514 | NodeDef* node = GetNode(node_name); |
| 515 | TF_RETURN_IF_ERROR(CheckNodeExists(node_name, node, error_status)); |
| 516 | |
| 517 | MutableGraphView::OutputPort control_port(node, Graph::kControlSlot); |
| 518 | auto control_fanouts = GetFanout(control_port); |
| 519 | if (op == "Switch" && !control_fanouts.empty()) { |
| 520 | return error_status( |
| 521 | "can't change node op to Switch when node drives a control dependency " |
| 522 | "(alternatively, we could add the identity node needed, but it seems " |
| 523 | "like an unlikely event and probably a mistake)"); |
| 524 | } |
| 525 | |
| 526 | if (node->device() != device) { |
| 527 | node->set_device(string(device)); |
| 528 | } |
| 529 | node->mutable_attr()->clear(); |
| 530 | for (const auto& attr : attrs) { |
| 531 | (*node->mutable_attr())[attr.first] = attr.second; |
| 532 | } |
| 533 | |
| 534 | if (node->op() == op) { |
| 535 | return Status::OK(); |
| 536 | } |
| 537 | |
| 538 | node->set_op(string(op)); |
| 539 | |
| 540 | if (CanDedupControlWithRegularInput(*this, *node)) { |
| 541 | for (const auto& control_fanout : control_fanouts) { |
| 542 | if (HasRegularFaninNode(*this, *control_fanout.node, node->name())) { |
| 543 | RemoveControllingFaninInternal(control_fanout.node, node); |
| 544 | } |
| 545 | } |
| 546 | } |
| 547 | |
| 548 | return Status::OK(); |
| 549 | } |
| 550 | |
| 551 | Status MutableGraphView::UpdateNodeName(absl::string_view from_node_name, |
| 552 | absl::string_view to_node_name, |