Skip to content

Commit

Permalink
Remove all references to dead vertices in ZX extraction (#1690)
Browse files Browse the repository at this point in the history
* Make sure we remove all references when we remove vertices

* Bump tket version

* Remove looping tests
  • Loading branch information
willsimmons1465 authored Nov 21, 2024
1 parent e9ceb8b commit 88c0481
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pytket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def requirements(self):
self.requires("pybind11_json/0.2.14")
self.requires("symengine/0.13.0")
self.requires("tkassert/0.3.4@tket/stable")
self.requires("tket/1.3.48@tket/stable")
self.requires("tket/1.3.49@tket/stable")
self.requires("tklog/0.3.3@tket/stable")
self.requires("tkrng/0.3.3@tket/stable")
self.requires("tktokenswap/0.3.9@tket/stable")
Expand Down
2 changes: 1 addition & 1 deletion tket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

class TketConan(ConanFile):
name = "tket"
version = "1.3.48"
version = "1.3.49"
package_type = "library"
license = "Apache 2"
homepage = "https://github.com/CQCL/tket"
Expand Down
11 changes: 7 additions & 4 deletions tket/src/Converters/ZXConverters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,8 @@ std::pair<ZXDiagram, BoundaryVertMap> circuit_to_zx(const Circuit& circ) {

void clean_frontier(
ZXDiagram& diag, ZXVertVec& frontier, Circuit& circ,
std::map<ZXVert, unsigned>& qubit_map) {
std::map<ZXVert, unsigned>& qubit_map,
std::map<ZXVert, ZXVert>& input_qubits) {
std::set<ZXVert> frontier_lookup;
std::list<std::pair<ZXVert, ZXVert>> czs;
for (const ZXVert& f : frontier) {
Expand Down Expand Up @@ -655,6 +656,8 @@ void clean_frontier(
(nt0 == ZXType::Output && nt1 == ZXType::Input)) {
diag.add_wire(ns.at(0), ns.at(1));
diag.remove_vertex(f);
auto input_found = input_qubits.find(f);
if (input_found != input_qubits.end()) input_qubits.erase(f);
removed = true;
}
}
Expand Down Expand Up @@ -852,10 +855,10 @@ Circuit zx_to_circuit(const ZXDiagram& d) {
for (const ZXVert& i : ins)
input_qubits.insert({diag.neighbours(i).at(0), i});

clean_frontier(diag, frontier, circ, qubit_map);
clean_frontier(diag, frontier, circ, qubit_map, input_qubits);
while (!frontier.empty()) {
if (remove_all_gadgets(diag, frontier, input_qubits)) {
clean_frontier(diag, frontier, circ, qubit_map);
clean_frontier(diag, frontier, circ, qubit_map, input_qubits);
}
ZXVertSeqSet neighbours = neighbours_of_frontier(diag, frontier);
boost::bimap<ZXVert, unsigned> correctors, preserve, ys;
Expand Down Expand Up @@ -922,7 +925,7 @@ Circuit zx_to_circuit(const ZXDiagram& d) {
}
}

clean_frontier(diag, frontier, circ, qubit_map);
clean_frontier(diag, frontier, circ, qubit_map, input_qubits);
}

qubit_map_t qm;
Expand Down
48 changes: 48 additions & 0 deletions tket/test/src/ZX/test_ZXSimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <catch2/catch_test_macros.hpp>

#include "tket/Converters/Converters.hpp"
#include "tket/Predicates/PassLibrary.hpp"
#include "tket/Transformations/Rebase.hpp"
#include "tket/ZX/Rewrite.hpp"

Expand Down Expand Up @@ -180,6 +181,53 @@ SCENARIO("Testing cases for internalising gadgets in MBQC") {
}
}

SCENARIO("Testing for vertex reuse bug") {
/**
* The following circuits were shown to hit errors non-deterministically, with
* the error likelihood varying with the device.
*
* At some point during extraction, a vertex would be removed from the graph,
* but some pointers to it lingered. Later, if an input extension occurred,
* new vertices would be added which may (depending on how boost was feeling
* with memory) reuse the same memory locations, so the old pointers now
* worked, meaning lookups in sets/functions would give false positives.
*/
GIVEN("Offender 1") {
Circuit circ(3);
circ.add_op<unsigned>(OpType::H, {1});
circ.add_op<unsigned>(OpType::H, {2});
circ.add_op<unsigned>(OpType::CX, {2, 1});
circ.add_op<unsigned>(OpType::Rz, 1.1, {1});
circ.add_op<unsigned>(OpType::H, {0});
circ.add_op<unsigned>(OpType::CX, {2, 1});
circ.add_op<unsigned>(OpType::H, {1});
circ.add_op<unsigned>(OpType::H, {2});
circ.add_op<unsigned>(OpType::Rz, 0.970644, {1});
circ.add_op<unsigned>(OpType::Rz, 0.9, {2});
circ.add_op<unsigned>(OpType::H, {1});
circ.add_op<unsigned>(OpType::H, {2});

CompilationUnit cu(circ);
ZXGraphlikeOptimisation()->apply(cu);
}
GIVEN("Offender 2") {
Circuit circ(6);
circ.add_op<unsigned>(OpType::Rx, -0.78, {3});
circ.add_op<unsigned>(OpType::Rx, 1.069, {5});
circ.add_op<unsigned>(OpType::CX, {0, 3});
circ.add_op<unsigned>(OpType::CX, {3, 5});
circ.add_op<unsigned>(OpType::CX, {0, 5});
circ.add_op<unsigned>(OpType::Rx, 1.069, {3});
circ.add_op<unsigned>(OpType::Rx, -5.958, {4});
circ.add_op<unsigned>(OpType::CX, {3, 4});
circ.add_op<unsigned>(OpType::CX, {3, 5});
circ.add_op<unsigned>(OpType::CX, {0, 3});

CompilationUnit cu(circ);
ZXGraphlikeOptimisation()->apply(cu);
}
}

} // namespace test_ZXSimp
} // namespace zx
} // namespace tket

0 comments on commit 88c0481

Please sign in to comment.