Skip to content

Commit 2b9f86e

Browse files
dubstacktensorflower-gardener
authored andcommitted
Refactor BiDirectionalMap to fully hide internals and expose a symmetric API.
PiperOrigin-RevId: 780793848
1 parent bc74ce3 commit 2b9f86e

12 files changed

Lines changed: 262 additions & 118 deletions

third_party/xla/xla/hlo/tools/hlo_diff/hlo_diff_eval.cc

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,28 @@ int64_t CountSplitAllegianceParental(const HloGumgraph& left,
6767
const HloGumgraph& right,
6868
const HloGumgraphMappings& mappings) {
6969
int64_t count = 0;
70-
for (const auto& it : mappings.left_to_right_instruction_map.left) {
71-
if (it.first->children.size() != it.second.node->children.size()) {
70+
for (const auto& [left, right] : mappings.left_to_right_instruction_map) {
71+
if (left->children.size() != right->children.size()) {
7272
continue;
7373
}
7474
bool children_opcode_mismatch = false;
75-
for (int i = 0; i < it.first->children.size(); ++i) {
76-
if (it.first->children[i]->instruction->opcode() !=
77-
it.second.node->children[i]->instruction->opcode()) {
75+
for (int i = 0; i < left->children.size(); ++i) {
76+
if (left->children[i]->instruction->opcode() !=
77+
right->children[i]->instruction->opcode()) {
7878
children_opcode_mismatch = true;
7979
break;
8080
}
8181
}
8282
if (children_opcode_mismatch) {
8383
continue;
8484
}
85-
for (int i = 0; i < it.first->children.size(); ++i) {
86-
if (auto cit = mappings.left_to_right_instruction_map.left.find(
87-
it.first->children[i]);
88-
cit == mappings.left_to_right_instruction_map.left.end() ||
89-
cit->second.node != it.second.node->children[i]) {
85+
for (int i = 0; i < left->children.size(); ++i) {
86+
const auto* left_child = left->children[i];
87+
const auto* expected_right_child = right->children[i];
88+
if (auto mapped_right_child =
89+
mappings.left_to_right_instruction_map.GetRight(left_child);
90+
mapped_right_child != expected_right_child) {
9091
count++;
91-
// LOG(INFO) << it.first->instruction->name() << " has split child: "
92-
// << it.first->children[i]->instruction->name();
9392
}
9493
}
9594
}

third_party/xla/xla/hlo/tools/hlo_diff/hlo_diff_result.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,9 @@ std::unique_ptr<const DiffResult> ConstructDiffResult(
7171

7272
// The node is matched
7373
const HloInstructionNode* right_node =
74-
mappings.left_to_right_instruction_map.left.find(left_node)
75-
->second.node;
76-
const std::optional<HloInstructionNodeMappingProps>& mapping_props =
77-
mappings.left_to_right_instruction_map.left.find(left_node)
78-
->second.props;
74+
*mappings.left_to_right_instruction_map.GetRight(left_node);
75+
const std::optional<HloInstructionNodeMappingProps> mapping_props =
76+
mappings.left_to_right_instruction_map.GetPropsByLeft(left_node);
7977

8078
// Fill in matcher debug info.
8179
diff_result->map_by[std::make_pair(left_node->instruction,

third_party/xla/xla/hlo/tools/hlo_diff/hlo_diff_summary.cc

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <algorithm>
2121
#include <cstdint>
2222
#include <memory>
23+
#include <optional>
2324
#include <ostream>
2425
#include <string>
2526
#include <utility>
@@ -60,25 +61,21 @@ InstructionBimap ConstructInstructionBimap(const DiffResult& diff_result) {
6061

6162
// Returns the mapped instruction node of the given instruction in the given
6263
// direction. Returns nullptr if the instruction is not mapped.
63-
const HloInstruction* FindMappedInstruction(const InstructionBimap& mapping,
64-
const HloInstruction* instruction,
65-
DiffSide side) {
64+
std::optional<const HloInstruction*> FindMappedInstruction(
65+
const InstructionBimap& mapping, const HloInstruction* instruction,
66+
DiffSide side) {
6667
switch (side) {
6768
case DiffSide::kLeft: {
68-
if (auto it = mapping.left.find(instruction); it != mapping.left.end()) {
69-
return it->second.node;
70-
}
69+
return mapping.GetRight(instruction);
7170
break;
7271
}
7372
case DiffSide::kRight: {
74-
if (auto it = mapping.right.find(instruction);
75-
it != mapping.right.end()) {
76-
return it->second;
77-
}
73+
return mapping.GetLeft(instruction);
7874
break;
7975
}
8076
}
81-
return nullptr;
77+
78+
return std::nullopt;
8279
}
8380

8481
// Result of finding the main matched computation.
@@ -99,11 +96,11 @@ MainMatchedComputationResult FindMainMatchedComputation(
9996
int mapped_instruction_count = 0;
10097
const HloComputation* main_matched_computation = nullptr;
10198
for (const HloInstruction* instruction : computation->instructions()) {
102-
if (const HloInstruction* const mapped_instruction =
99+
if (std::optional<const HloInstruction*> mapped_instruction =
103100
FindMappedInstruction(mapping, instruction, side);
104-
mapped_instruction != nullptr) {
101+
mapped_instruction.has_value()) {
105102
++mapped_instruction_count;
106-
const HloComputation* right_computation = mapped_instruction->parent();
103+
const HloComputation* right_computation = (*mapped_instruction)->parent();
107104
const int count = ++matched_instruction_count[right_computation];
108105
if (count > max_count) {
109106
max_count = count;

third_party/xla/xla/hlo/tools/hlo_diff/hlo_gumgraph_diff.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ absl::StatusOr<std::unique_ptr<const HloGumgraphMappings>> FindMappings(
5656

5757
TF_RETURN_IF_ERROR(left.GetCallGraph().VisitNodes(
5858
[&](const CallGraphNode& node) {
59-
if (auto it = mappings->left_to_right_computation_map.left.find(&node);
60-
it != mappings->left_to_right_computation_map.left.end()) {
61-
MatchComputationGraphs(left, right, node, *it->second.node,
62-
*mappings);
59+
if (auto right_node =
60+
mappings->left_to_right_computation_map.GetRight(&node);
61+
right_node.has_value()) {
62+
MatchComputationGraphs(left, right, node, **right_node, *mappings);
6363
}
6464
return absl::OkStatus();
6565
},

third_party/xla/xla/hlo/tools/hlo_diff/hlo_gumgraph_mappings.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ struct HloGumgraphMappings {
9494
// Returns true if the left node is mapped to a right node.
9595
inline bool InstructionMapContainsLeft(
9696
const HloInstructionNode* left_node) const {
97-
return left_to_right_instruction_map.left.contains(left_node);
97+
return left_to_right_instruction_map.ContainsLeft(left_node);
9898
}
9999

100100
// Returns true if the right node is mapped to a left node.
101101
inline bool InstructionMapContainsRight(
102102
const HloInstructionNode* right_node) const {
103-
return left_to_right_instruction_map.right.contains(right_node);
103+
return left_to_right_instruction_map.ContainsRight(right_node);
104104
}
105105
};
106106

third_party/xla/xla/hlo/tools/hlo_diff/matchers/bottom_up_matcher.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ double DiceSimLimitedSubgraph(const HloInstructionNode* absl_nonnull left,
8686

8787
int common = 0;
8888
for (const HloInstructionNode* left_node : left_nodes) {
89-
if (auto it = mappings.left_to_right_instruction_map.left.find(left_node);
90-
it != mappings.left_to_right_instruction_map.left.end() &&
91-
right_nodes_set.contains(it->second.node)) {
89+
if (auto right_node =
90+
mappings.left_to_right_instruction_map.GetRight(left_node);
91+
right_node.has_value() && right_nodes_set.contains(*right_node)) {
9292
++common;
9393
}
9494
}
@@ -127,10 +127,9 @@ double AllOperandHloValuesMatchedScore(
127127
left.GetNode(left_hlo_values[i]->defining_instruction());
128128
HloInstructionNode* right_hlo_value_node =
129129
right.GetNode(right_hlo_values[i]->defining_instruction());
130-
if (auto it = mappings.left_to_right_instruction_map.left.find(
130+
if (auto right_node = mappings.left_to_right_instruction_map.GetRight(
131131
left_hlo_value_node);
132-
it == mappings.left_to_right_instruction_map.left.end() ||
133-
it->second.node != right_hlo_value_node) {
132+
right_node != right_hlo_value_node) {
134133
mappings_matched = false;
135134
}
136135
if (left_hlo_value_node->props.fingerprint !=
@@ -177,9 +176,10 @@ void GreedyLimitedCandidatesBottomUpMatcher::Match(
177176
HloGumgraphBfs(
178177
*left_node,
179178
[&](const HloInstructionNode& node, int distance) {
180-
if (auto it = mappings.left_to_right_instruction_map.left.find(&node);
181-
it != mappings.left_to_right_instruction_map.left.end()) {
182-
right_seeds.push_back(it->second.node);
179+
if (auto right_node =
180+
mappings.left_to_right_instruction_map.GetRight(&node);
181+
right_node.has_value()) {
182+
right_seeds.push_back(*right_node);
183183
}
184184
// Don't pursue subgraphs with too many childrens. Allows us to visit
185185
// deeper subgraphs without getting stuck on a single node with a

third_party/xla/xla/hlo/tools/hlo_diff/matchers/exact_subgraph_matcher.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,11 @@ void MapSubgraph(const HloInstructionNode* absl_nonnull left,
9595
exact_mapped_subgraph_roots.insert(left_subgraph[i]);
9696
exact_mapped_subgraph_roots.insert(right_subgraph[i]);
9797
if (i != 0) {
98-
mappings.left_to_right_instruction_map.left.find(left_subgraph[i])
99-
->second.props->unchanged = true;
98+
auto props = mappings.left_to_right_instruction_map.GetPropsByLeft(
99+
left_subgraph[i]);
100+
props->unchanged = true;
101+
mappings.left_to_right_instruction_map.SetPropsByLeft(left_subgraph[i],
102+
*props);
100103
}
101104
}
102105
}

third_party/xla/xla/hlo/tools/hlo_diff/matchers/hlo_call_graph_matcher.cc

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,20 @@ void MapCalledComputations(const HloInstruction* left_instruction,
138138
void ProcessCallGraphNode(const CallGraphNode& left_computation,
139139
const HloGumgraph& left, const HloGumgraph& right,
140140
HloGumgraphMappings& mappings) {
141+
if (left_computation.callees().empty()) {
142+
return;
143+
}
144+
141145
// Only match called computations if current computation is already matched.
142-
auto it = mappings.left_to_right_computation_map.left.find(&left_computation);
143-
if (it == mappings.left_to_right_computation_map.left.end() ||
144-
left_computation.callees().empty()) {
146+
auto right_computation =
147+
mappings.left_to_right_computation_map.GetRight(&left_computation);
148+
if (!right_computation.has_value()) {
145149
return;
146150
}
147151

148-
const CallGraphNode* right_computation = it->second.node;
149152
HloComputation::CachingPostOrder left_cpo(left_computation.computation());
150-
HloComputation::CachingPostOrder right_cpo(right_computation->computation());
153+
HloComputation::CachingPostOrder right_cpo(
154+
(*right_computation)->computation());
151155

152156
// Phase 1: Match called computations to computations with matching
153157
// computation fingerprints, i.e. exact matches.
@@ -158,7 +162,7 @@ void ProcessCallGraphNode(const CallGraphNode& left_computation,
158162
left_callees_by_fingerprint[left_props.fingerprint].insert(
159163
left_props.call_graph_node);
160164
}
161-
for (const HloComputation* callee : right_computation->callees()) {
165+
for (const HloComputation* callee : (*right_computation)->callees()) {
162166
CallGraphNodeProps right_props = right.AllComputationProps().at(callee);
163167
right_callees_by_fingerprint[right_props.fingerprint].insert(
164168
right_props.call_graph_node);
@@ -185,7 +189,7 @@ void ProcessCallGraphNode(const CallGraphNode& left_computation,
185189
for (const HloInstruction* instruction : left_cpo.PostOrder()) {
186190
bool all_called_computations_matched = true;
187191
for (const HloComputation* callee : instruction->called_computations()) {
188-
if (!mappings.left_to_right_computation_map.left.contains(
192+
if (!mappings.left_to_right_computation_map.ContainsLeft(
189193
&left.GetCallGraph().GetNode(callee))) {
190194
all_called_computations_matched = false;
191195
break;
@@ -202,7 +206,7 @@ void ProcessCallGraphNode(const CallGraphNode& left_computation,
202206
for (const HloInstruction* instruction : right_cpo.PostOrder()) {
203207
bool all_called_computations_matched = true;
204208
for (const HloComputation* callee : instruction->called_computations()) {
205-
if (!mappings.left_to_right_computation_map.right.contains(
209+
if (!mappings.left_to_right_computation_map.ContainsRight(
206210
&right.GetCallGraph().GetNode(callee))) {
207211
all_called_computations_matched = false;
208212
break;
@@ -256,7 +260,7 @@ void ProcessCallGraphNode(const CallGraphNode& left_computation,
256260
absl::flat_hash_map<std::string, absl::flat_hash_set<const CallGraphNode*>>
257261
unmatched_left_callees, unmatched_right_callees;
258262
for (const HloComputation* callee : left_computation.callees()) {
259-
if (!mappings.left_to_right_computation_map.left.contains(
263+
if (!mappings.left_to_right_computation_map.ContainsLeft(
260264
&left.GetCallGraph().GetNode(callee))) {
261265
const CallGraphNode& callee_node = left.GetCallGraph().GetNode(callee);
262266
std::string opcode_and_name;
@@ -276,8 +280,8 @@ void ProcessCallGraphNode(const CallGraphNode& left_computation,
276280
unmatched_left_callees[opcode_name_shape].insert(&callee_node);
277281
}
278282
}
279-
for (const HloComputation* callee : right_computation->callees()) {
280-
if (!mappings.left_to_right_computation_map.right.contains(
283+
for (const HloComputation* callee : (*right_computation)->callees()) {
284+
if (!mappings.left_to_right_computation_map.ContainsRight(
281285
&right.GetCallGraph().GetNode(callee))) {
282286
const CallGraphNode& callee_node = right.GetCallGraph().GetNode(callee);
283287
std::string opcode_and_name;
@@ -364,10 +368,9 @@ void MatchCallGraphs(const HloGumgraph& left, const HloGumgraph& right,
364368
});
365369

366370
int signature_match_count = 0, exact_match_count = 0;
367-
for (auto it = mappings.left_to_right_computation_map.left.begin();
368-
it != mappings.left_to_right_computation_map.left.end(); ++it) {
369-
if (it->second.props->computation_match_type ==
370-
ComputationMatchType::kSignature) {
371+
for (const auto& [left, right] : mappings.left_to_right_computation_map) {
372+
auto props = mappings.left_to_right_computation_map.GetPropsByLeft(left);
373+
if (props->computation_match_type == ComputationMatchType::kSignature) {
371374
++signature_match_count;
372375
} else {
373376
++exact_match_count;

third_party/xla/xla/hlo/tools/hlo_diff/matchers/hlo_computation_graph_matcher.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,16 @@ void MatchComputationGraphs(const HloGumgraph& left, const HloGumgraph& right,
6161
const CallGraphNode& left_computation,
6262
const CallGraphNode& right_computation,
6363
HloGumgraphMappings& mappings) {
64-
auto it = mappings.left_to_right_computation_map.left.find(&left_computation);
65-
if (it == mappings.left_to_right_computation_map.left.end()) {
64+
if (!mappings.left_to_right_computation_map.ContainsLeft(&left_computation)) {
6665
return;
6766
}
6867

6968
MatchCallSites(left, right, left_computation, right_computation, mappings);
7069

7170
// If the two computations are exact matches, we can match all
7271
// instructions in the two computations.
73-
if (it->second.props->computation_match_type ==
74-
ComputationMatchType::kExact) {
72+
if (mappings.left_to_right_computation_map.GetPropsByLeft(&left_computation)
73+
->computation_match_type == ComputationMatchType::kExact) {
7574
auto left_instructions =
7675
left_computation.computation()->MakeInstructionPostOrder();
7776
auto right_instructions =

third_party/xla/xla/hlo/tools/hlo_diff/matchers/top_down_matcher.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,21 @@ void GreedyTopDownMatcher::Match(HloGumgraphMappings& mappings) const {
6767
HloGumgraphDfs(
6868
left_.GetRoot(),
6969
[&](const HloInstructionNode& left_node) {
70-
auto it = mappings.left_to_right_instruction_map.left.find(&left_node);
71-
if (it == mappings.left_to_right_instruction_map.left.end()) {
70+
auto right_node =
71+
mappings.left_to_right_instruction_map.GetRight(&left_node);
72+
if (!right_node) {
7273
return;
7374
}
7475

7576
if (require_same_children_ &&
76-
ShouldSkipMatching(left_node, *it->second.node)) {
77+
ShouldSkipMatching(left_node, **right_node)) {
7778
return;
7879
}
7980

8081
std::vector<HloInstructionNode*> left_children =
8182
GetUnmatchedChildren(left_node.children, mappings);
8283
std::vector<HloInstructionNode*> right_children =
83-
GetUnmatchedChildren(it->second.node->children, mappings);
84+
GetUnmatchedChildren((*right_node)->children, mappings);
8485

8586
MatchInstructions(left_, right_, left_children, right_children,
8687
mappings, type_, MapByPositionMode::kAlways);

0 commit comments

Comments
 (0)