| 911 | } |
| 912 | |
| 913 | Status MutableGraphView::AddRegularFaninByPort(absl::string_view node_name, |
| 914 | int port, |
| 915 | const TensorId& fanin) { |
| 916 | auto error_status = [node_name, port, fanin](absl::string_view msg) { |
| 917 | string params = absl::Substitute("node_name='$0', port=$1, fanin='$2'", |
| 918 | node_name, port, fanin.ToString()); |
| 919 | return MutationError("AddRegularFaninByPort", params, msg); |
| 920 | }; |
| 921 | |
| 922 | TF_RETURN_IF_ERROR(CheckFaninIsRegular(fanin, error_status)); |
| 923 | TF_RETURN_IF_ERROR(CheckAddingFaninToSelf(node_name, fanin, error_status)); |
| 924 | NodeDef* node = GetNode(node_name); |
| 925 | TF_RETURN_IF_ERROR(CheckNodeExists(node_name, node, error_status)); |
| 926 | const int num_regular_fanins = |
| 927 | NumFanins(*node, /*include_controlling_nodes=*/false); |
| 928 | TF_RETURN_IF_ERROR( |
| 929 | CheckPortRange(port, /*min=*/0, num_regular_fanins, error_status)); |
| 930 | NodeDef* fanin_node = GetNode(fanin.node()); |
| 931 | TF_RETURN_IF_ERROR(CheckNodeExists(fanin.node(), fanin_node, error_status)); |
| 932 | |
| 933 | const int last_node_input = node->input_size(); |
| 934 | node->add_input(TensorIdToString(fanin)); |
| 935 | node->mutable_input()->SwapElements(num_regular_fanins, last_node_input); |
| 936 | for (int i = num_regular_fanins - 1; i >= port; --i) { |
| 937 | TensorId tensor_id = ParseTensorName(node->input(i)); |
| 938 | OutputPort fanin_port(nodes()[tensor_id.node()], tensor_id.index()); |
| 939 | absl::flat_hash_set<InputPort>* fanouts_set = &fanouts()[fanin_port]; |
| 940 | fanouts_set->erase({node, i}); |
| 941 | fanouts_set->insert({node, i + 1}); |
| 942 | node->mutable_input()->SwapElements(i, i + 1); |
| 943 | } |
| 944 | |
| 945 | OutputPort fanin_port(fanin_node, fanin.index()); |
| 946 | fanouts()[fanin_port].insert({node, port}); |
| 947 | UpdateMaxRegularOutputPortForAddedFanin(fanin_port); |
| 948 | |
| 949 | max_regular_input_port()[node] = num_regular_fanins; |
| 950 | if (CanDedupControlWithRegularInput(*this, *fanin_node)) { |
| 951 | RemoveControllingFaninInternal(node, fanin_node); |
| 952 | } |
| 953 | |
| 954 | return Status::OK(); |
| 955 | } |
| 956 | |
| 957 | NodeDef* MutableGraphView::GetControllingFaninToAdd(absl::string_view node_name, |
| 958 | const OutputPort& fanin, |