Skip to content

Commit 9b14b29

Browse files
authored
Merge pull request #40 from oscarhiggott/fix-syndrome-on-boundary
Zero out syndrome in the support of UserGraph boundary nodes. Fixes #41
2 parents df64928 + feed3ce commit 9b14b29

File tree

6 files changed

+54
-2
lines changed

6 files changed

+54
-2
lines changed

src/pymatching/sparse_blossom/driver/mwpm_decoding.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ void process_timeline_until_completion(pm::Mwpm& mwpm, const std::vector<uint64_
8686
for (auto& detection : detection_events) {
8787
if (detection >= mwpm.flooder.graph.nodes.size())
8888
throw std::invalid_argument("Detection event index too large");
89-
mwpm.create_detection_event(&mwpm.flooder.graph.nodes[detection]);
89+
if (detection + 1 > mwpm.flooder.graph.is_user_graph_boundary_node.size() ||
90+
!mwpm.flooder.graph.is_user_graph_boundary_node[detection])
91+
mwpm.create_detection_event(&mwpm.flooder.graph.nodes[detection]);
9092
}
9193

9294
} else {
@@ -102,7 +104,9 @@ void process_timeline_until_completion(pm::Mwpm& mwpm, const std::vector<uint64_
102104
"Detection event index `" + std::to_string(detection) +
103105
"` is larger than any detector node index in the graph.");
104106
if (!mwpm.flooder.graph.nodes[detection].radius_of_arrival) {
105-
mwpm.create_detection_event(&mwpm.flooder.graph.nodes[detection]);
107+
if (detection + 1 > mwpm.flooder.graph.is_user_graph_boundary_node.size() ||
108+
!mwpm.flooder.graph.is_user_graph_boundary_node[detection])
109+
mwpm.create_detection_event(&mwpm.flooder.graph.nodes[detection]);
106110
} else {
107111
// Unmark node
108112
mwpm.flooder.graph.nodes[detection].radius_of_arrival = 0;

src/pymatching/sparse_blossom/driver/user_graph.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ pm::MatchingGraph pm::UserGraph::to_matching_graph(pm::weight_int num_distinct_w
258258
matching_graph.add_boundary_edge(u, weight, observables);
259259
});
260260
matching_graph.normalising_constant = normalising_constant;
261+
if (boundary_nodes.size() > 0) {
262+
matching_graph.is_user_graph_boundary_node.clear();
263+
matching_graph.is_user_graph_boundary_node.resize(nodes.size(), false);
264+
for (auto& i : boundary_nodes)
265+
matching_graph.is_user_graph_boundary_node[i] = true;
266+
}
261267
return matching_graph;
262268
}
263269

src/pymatching/sparse_blossom/driver/user_graph.test.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "pymatching/sparse_blossom/driver/user_graph.h"
16+
#include "pymatching/sparse_blossom/driver/mwpm_decoding.h"
1617

1718
#include <cmath>
1819
#include <gtest/gtest.h>
@@ -143,3 +144,25 @@ TEST(UserGraph, NodesAlongShortestPath) {
143144
ASSERT_EQ(nodes, nodes_expected);
144145
}
145146
}
147+
148+
TEST(UserGraph, DecodeUserGraphDetectionEventOnBoundaryNode) {
149+
{
150+
pm::UserGraph graph;
151+
graph.add_or_merge_edge(0, 1, {0}, 1.0, -1);
152+
graph.add_or_merge_edge(1, 2, {1}, 1.0, -1);
153+
graph.set_boundary({2});
154+
auto& mwpm = graph.get_mwpm();
155+
pm::ExtendedMatchingResult res(mwpm.flooder.graph.num_observables);
156+
pm::decode_detection_events(mwpm, {2}, res.obs_crossed.data(), res.weight);
157+
}
158+
159+
{
160+
pm::UserGraph graph;
161+
graph.add_or_merge_edge(0, 1, {0}, -1.0, -1);
162+
graph.add_or_merge_edge(1, 2, {1}, 1.0, -1);
163+
graph.set_boundary({2});
164+
auto& mwpm = graph.get_mwpm();
165+
pm::ExtendedMatchingResult res(mwpm.flooder.graph.num_observables);
166+
pm::decode_detection_events(mwpm, {2}, res.obs_crossed.data(), res.weight);
167+
}
168+
}

src/pymatching/sparse_blossom/flooder/graph.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ MatchingGraph::MatchingGraph(MatchingGraph&& graph) noexcept
104104
: nodes(std::move(graph.nodes)),
105105
negative_weight_detection_events_set(std::move(graph.negative_weight_detection_events_set)),
106106
negative_weight_observables_set(std::move(graph.negative_weight_observables_set)),
107+
is_user_graph_boundary_node(std::move(graph.is_user_graph_boundary_node)),
107108
negative_weight_sum(graph.negative_weight_sum),
108109
num_nodes(graph.num_nodes),
109110
num_observables(graph.num_observables),

src/pymatching/sparse_blossom/flooder/graph.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class MatchingGraph {
3838
std::set<size_t> negative_weight_observables_set;
3939
/// The sum of the negative edge weights. This number is negative, rather than the absolute value.
4040
pm::total_weight_int negative_weight_sum;
41+
/// is_user_graph_boundary_node is only filled if MatchingGraph is constructed from a UserGraph
42+
/// is_user_graph_boundary_node[i] is true if i is a boudary node in the UserGraph
43+
/// This vector is used to check that a detection event is not added to a node marked as a boundary node
44+
/// in the UserGraph (as such an event cannot be matched, and will raise an error).
45+
std::vector<bool> is_user_graph_boundary_node;
4146
size_t num_nodes;
4247
size_t num_observables;
4348
/// This is the normalising constant that the edge weights were multiplied by when converting from floats to

tests/matching/decode_test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,16 @@ def test_decode_wrong_syndrome_type_raises_type_error():
205205
m = Matching()
206206
m.add_edge(0, 1)
207207
m.decode([0, "A"])
208+
209+
210+
def test_syndrome_on_boundary_nodes():
211+
m = Matching()
212+
m.add_edge(0, 1, fault_ids={0})
213+
m.add_edge(1, 2, fault_ids={1})
214+
m.add_edge(2, 3, fault_ids={2})
215+
m.add_edge(3, 4, fault_ids={3})
216+
m.set_boundary_nodes({3, 4})
217+
m.decode([0, 0, 0, 1, 0])
218+
m.decode([0, 0, 0, 0, 1])
219+
m.decode([0, 0, 0, 1, 1])
220+
m.decode([1, 0, 1, 0, 1])

0 commit comments

Comments
 (0)