MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / JoinCondStatesMerge

Method JoinCondStatesMerge

tensorflow/compiler/tf2xla/functionalize_cond.cc:1053–1101  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1051}
1052
1053StatusOr<StateMap::CondId> FunctionalizeCond::JoinCondStatesMerge(
1054 Node* merge, StateMap::CondId src, StateMap::CondId dst) {
1055 // Determine the flow state when joining two states for a merge
1056 // node. Combining the two states for a merge node is effectively performing a
1057 // disjunction of the states along the different input edges. For a merge that
1058 // can be transformed into a If the two inputs paths have to have a predicate
1059 // on which they differ (e.g., along one edge predicate `p` has to hold while
1060 // on another it should not). This function first determines this predicate
1061 // and then the resultant state is the common path between the two inputs
1062 // followed by s(p, both).
1063 VLOG(4) << "Joining (for merge) " << DebugString(src) << " and "
1064 << DebugString(dst);
1065 if (state_map_.IsEmpty(dst)) return src;
1066 if (state_map_.IsEmpty(src)) {
1067 return errors::Internal("Merge node ", merge->name(),
1068 " has input that's not in any CondContext.");
1069 }
1070
1071 if (state_map_.IsDead(src)) return src;
1072 if (state_map_.IsDead(dst)) return dst;
1073
1074 std::vector<StateMap::CondState::value_type> diff;
1075 StateMap::CondState merged;
1076 std::set_symmetric_difference(src->begin(), src->end(), dst->begin(),
1077 dst->end(), std::back_inserter(diff),
1078 CondStateLess());
1079 std::set_intersection(src->begin(), src->end(), dst->begin(), dst->end(),
1080 std::inserter(merged, merged.begin()), CondStateLess());
1081
1082 // Update mapping from merge node to predicate.
1083 if (diff.size() == 2) {
1084 auto pred = diff[0].first;
1085 bool different_branches = (diff[0].second != diff[1].second) &&
1086 (diff[0].second == BranchType::kThenBranch ||
1087 diff[0].second == BranchType::kElseBranch) &&
1088 (diff[1].second == BranchType::kThenBranch ||
1089 diff[1].second == BranchType::kElseBranch);
1090 if (!(pred == diff[1].first) || !different_branches)
1091 return errors::InvalidArgument(
1092 "Unable to determine predicate for merge node");
1093 merge_to_predicate_[merge] = pred;
1094 } else {
1095 return errors::InvalidArgument(
1096 "Merge of two inputs that differ on more than one predicate ",
1097 DebugString(src), " and ", DebugString(dst));
1098 }
1099
1100 return state_map_.GetCondId(merged);
1101}
1102
1103StateMap::CondId FunctionalizeCond::StateAlongEdge(const Edge* e) {
1104 Node* src = e->src();

Callers

nothing calls this directly

Calls 12

InternalFunction · 0.85
CondStateLessClass · 0.85
set_intersectionFunction · 0.85
InvalidArgumentFunction · 0.85
IsDeadMethod · 0.80
GetCondIdMethod · 0.80
DebugStringFunction · 0.70
nameMethod · 0.65
IsEmptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected