| 3664 | } |
| 3665 | |
| 3666 | Status MklLayoutRewritePass::RewriteNodeForJustOpNameChange( |
| 3667 | std::unique_ptr<Graph>* g, const Node* orig_node, Node** new_node, |
| 3668 | const RewriteInfo* ri) { |
| 3669 | // Get all data inputs. |
| 3670 | int num_data_inputs = orig_node->in_edges().size(); |
| 3671 | // Drop count for control edges from inputs |
| 3672 | for (const Edge* e : orig_node->in_edges()) { |
| 3673 | if (e->IsControlEdge()) { |
| 3674 | num_data_inputs--; |
| 3675 | } |
| 3676 | } |
| 3677 | gtl::InlinedVector<Node*, 4> control_edges; |
| 3678 | gtl::InlinedVector<std::pair<Node*, int>, 4> inputs(num_data_inputs); |
| 3679 | FillInputs(orig_node, &control_edges, &inputs); |
| 3680 | |
| 3681 | // Build new node. We use same name as original node, but change the op name. |
| 3682 | NodeBuilder nb(orig_node->name().c_str(), ri->new_name.c_str()); |
| 3683 | // Copy user-specified device assigned to original node to new node. |
| 3684 | nb.Device(orig_node->def().device()); |
| 3685 | |
| 3686 | Status s = CopyInputs(orig_node, inputs, &nb); |
| 3687 | if (s != Status::OK()) { |
| 3688 | return s; |
| 3689 | } |
| 3690 | |
| 3691 | ri->copy_attrs(const_cast<const Node*>(orig_node), &nb, true); |
| 3692 | nb.Attr("_kernel", mkl_op_registry::kMklNameChangeOpLabel); |
| 3693 | |
| 3694 | // Finalize graph and get new node. |
| 3695 | s = nb.Finalize(&**g, new_node); |
| 3696 | if (s != Status::OK()) { |
| 3697 | return s; |
| 3698 | } |
| 3699 | |
| 3700 | // In the following code of this function, an unsorted set is used to make |
| 3701 | // sure no duplicated edges be added into the new node. Therefore, we can |
| 3702 | // pass allow_duplicates = true in AddControlEdge call to skip the O(#edges) |
| 3703 | // check in the routine. |
| 3704 | |
| 3705 | // Incoming data edges from 'orig_node' node to new 'new_node' node are |
| 3706 | // already copied in BuildNode. We need to handle control edges now. |
| 3707 | std::unordered_set<Node*> unique_node; |
| 3708 | for (const Edge* e : orig_node->in_edges()) { |
| 3709 | if (e->IsControlEdge()) { |
| 3710 | auto result = unique_node.insert(e->src()); |
| 3711 | if (result.second) { |
| 3712 | (*g)->AddControlEdge(e->src(), *new_node, true); |
| 3713 | } |
| 3714 | } |
| 3715 | } |
| 3716 | unique_node.clear(); |
| 3717 | |
| 3718 | // Transfer outgoing edges from 'orig_node' node to new 'new_node' node. |
| 3719 | for (const Edge* e : orig_node->out_edges()) { |
| 3720 | if (e->IsControlEdge()) { |
| 3721 | auto result = unique_node.insert(e->dst()); |
| 3722 | if (result.second) { |
| 3723 | (*g)->AddControlEdge(*new_node, e->dst(), true); |
nothing calls this directly
no test coverage detected