Skip to content

Commit

Permalink
[TKET-1598] fix ConnectivityPredicate fails after FullPeepholeOptimis…
Browse files Browse the repository at this point in the history
…e and AASRouting (#194)

* add bugfix

* Update tket/src/Predicates/include/Predicates/PassGenerators.hpp

Co-authored-by: Alexander Cowtan <[email protected]>

* remove bool add break

Co-authored-by: Alexander Cowtan <[email protected]>
  • Loading branch information
cqc-melf and alexcowtan authored Feb 3, 2022
1 parent a2d2963 commit d3ab84b
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 6 deletions.
18 changes: 15 additions & 3 deletions tket/src/Predicates/PassGenerators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,18 @@ PassPtr gen_placement_pass_phase_poly(const Architecture& arc) {
};
Transform t = Transform(trans);

PredicatePtrMap precons{};
PredicatePtr no_wire_swap = std::make_shared<NoWireSwapsPredicate>();
PredicatePtrMap precons{CompilationUnit::make_type_pair(no_wire_swap)};

PredicatePtr placement_pred = std::make_shared<PlacementPredicate>(arc);
PredicatePtr n_qubit_pred =
std::make_shared<MaxNQubitsPredicate>(arc.n_nodes());

PredicatePtrMap s_postcons{
CompilationUnit::make_type_pair(placement_pred),
CompilationUnit::make_type_pair(n_qubit_pred)};
CompilationUnit::make_type_pair(n_qubit_pred),
CompilationUnit::make_type_pair(no_wire_swap)};

PostConditions pc{s_postcons, {}, Guarantee::Preserve};
// record pass config
nlohmann::json j;
Expand All @@ -297,6 +302,10 @@ PassPtr aas_routing_pass(
"Circuit has more qubits than the architecture has nodes.");
}

// this pass is not able to handle implicit wire swaps
// this is additionally assured by a precondition of this pass
TKET_ASSERT(!circ.has_implicit_wireswaps());

qubit_vector_t all_qu = circ.all_qubits();

Circuit input_circ = circ;
Expand Down Expand Up @@ -379,9 +388,12 @@ PassPtr aas_routing_pass(
PredicatePtr placedpred = std::make_shared<PlacementPredicate>(arc);
PredicatePtr n_qubit_pred =
std::make_shared<MaxNQubitsPredicate>(arc.n_nodes());
PredicatePtr no_wire_swap = std::make_shared<NoWireSwapsPredicate>();

PredicatePtrMap precons{
CompilationUnit::make_type_pair(placedpred),
CompilationUnit::make_type_pair(n_qubit_pred)};
CompilationUnit::make_type_pair(n_qubit_pred),
CompilationUnit::make_type_pair(no_wire_swap)};

PredicatePtr postcon1 = std::make_shared<ConnectivityPredicate>(arc);
std::pair<const std::type_index, PredicatePtr> pair1 =
Expand Down
10 changes: 9 additions & 1 deletion tket/src/Predicates/PassLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ const PassPtr &ComposePhasePolyBoxes() {
* converts a circuit containing all possible gates to a circuit
* containing only phase poly boxes + H gates (and measure + reset + collapse
* + barrier)
* this pass will replace all wire swaps in the given circuit and they will be
* included in the last or an additional phase poly boxes
*/
static const PassPtr pp([]() {
Transform t =
Expand All @@ -293,7 +295,13 @@ const PassPtr &ComposePhasePolyBoxes() {

PredicatePtrMap precons{CompilationUnit::make_type_pair(noclas)};

PostConditions postcon = {precons, {}, Guarantee::Clear};
PredicatePtr no_wire_swap = std::make_shared<NoWireSwapsPredicate>();

PredicatePtrMap s_postcons{
CompilationUnit::make_type_pair(noclas),
CompilationUnit::make_type_pair(no_wire_swap)};
PostConditions postcon{s_postcons, {}, Guarantee::Preserve};

nlohmann::json j;
j["name"] = "ComposePhasePolyBoxes";
return std::make_shared<StandardPass>(precons, t, postcon, j);
Expand Down
1 change: 1 addition & 0 deletions tket/src/Predicates/include/Predicates/PassGenerators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ PassPtr gen_directed_cx_routing_pass(
/**
* execute architecture aware synthesis on a given architecture for an allready
* place circuit, only for circuit which contains Cx+Rz+H gates
* this pass is not able to handle implicit wire swaps
* @param arc architecture to route on
* @param lookahead parameter for the recursion depth in the algorithm, the
* value should be > 0
Expand Down
11 changes: 11 additions & 0 deletions tket/src/Transformations/Decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,17 @@ Transform decomp_boxes() {

Transform compose_phase_poly_boxes() {
return Transform([](Circuit &circ) {
// replace wireswaps with three CX
while (circ.has_implicit_wireswaps()) {
qubit_map_t perm = circ.implicit_qubit_permutation();
for (const std::pair<const Qubit, Qubit> &pair : perm) {
if (pair.first != pair.second) {
circ.replace_implicit_wire_swap(pair.first, pair.second);
break;
}
}
}

CircToPhasePolyConversion conv = CircToPhasePolyConversion(circ);
conv.convert();
circ = conv.get_circuit();
Expand Down
70 changes: 68 additions & 2 deletions tket/tests/test_CompilerPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ SCENARIO("rebase and decompose PhasePolyBox test") {
Circuit result = cu.get_circ_ref();

REQUIRE(test_unitary_comparison(result, circ));
REQUIRE(!NoWireSwapsPredicate().verify(result));
REQUIRE(NoWireSwapsPredicate().verify(result));
}
GIVEN("NoWireSwapsPredicate for ComposePhasePolyBoxes II") {
Circuit circ(5);
Expand All @@ -817,7 +817,73 @@ SCENARIO("rebase and decompose PhasePolyBox test") {
Circuit result = cu.get_circ_ref();

REQUIRE(test_unitary_comparison(result, circ));
REQUIRE(!NoWireSwapsPredicate().verify(result));
REQUIRE(NoWireSwapsPredicate().verify(result));
}
GIVEN("NoWireSwapsPredicate for ComposePhasePolyBoxes III") {
Circuit circ(5);
add_2qb_gates(circ, OpType::CX, {{0, 3}, {1, 4}});
circ.add_op<unsigned>(OpType::SWAP, {3, 4});
circ.add_op<unsigned>(OpType::CX, {2, 3});
circ.add_op<unsigned>(OpType::Z, {3});
circ.add_op<unsigned>(OpType::CX, {2, 3});
circ.add_op<unsigned>(OpType::SWAP, {0, 1});
circ.add_op<unsigned>(OpType::CX, {1, 4});
circ.add_op<unsigned>(OpType::Z, {4});
circ.add_op<unsigned>(OpType::CX, {1, 4});
circ.add_op<unsigned>(OpType::SWAP, {1, 2});
circ.add_op<unsigned>(OpType::SWAP, {2, 3});
circ.add_op<unsigned>(OpType::CX, {0, 1});
circ.add_op<unsigned>(OpType::CX, {1, 2});
circ.add_op<unsigned>(OpType::CX, {2, 3});

REQUIRE(NoWireSwapsPredicate().verify(circ));
circ.replace_SWAPs();
REQUIRE(!NoWireSwapsPredicate().verify(circ));

CompilationUnit cu(circ);
REQUIRE(ComposePhasePolyBoxes()->apply(cu));
Circuit result = cu.get_circ_ref();

REQUIRE(test_unitary_comparison(result, circ));
REQUIRE(NoWireSwapsPredicate().verify(result));
}
GIVEN("NoWireSwapsPredicate for aas I") {
std::vector<Node> nodes = {Node(0), Node(1), Node(2), Node(3), Node(4)};
Architecture architecture(
{{nodes[0], nodes[1]},
{nodes[1], nodes[2]},
{nodes[2], nodes[3]},
{nodes[3], nodes[4]}});

Circuit circ(5);
add_2qb_gates(circ, OpType::CX, {{0, 3}, {1, 4}});
circ.add_op<unsigned>(OpType::SWAP, {3, 4});
circ.add_op<unsigned>(OpType::CX, {2, 3});
circ.add_op<unsigned>(OpType::Z, {3});
circ.add_op<unsigned>(OpType::CX, {2, 3});
circ.add_op<unsigned>(OpType::SWAP, {0, 1});
circ.add_op<unsigned>(OpType::CX, {1, 4});
circ.add_op<unsigned>(OpType::Z, {4});
circ.add_op<unsigned>(OpType::CX, {1, 4});
circ.add_op<unsigned>(OpType::SWAP, {1, 2});
circ.add_op<unsigned>(OpType::SWAP, {2, 3});
circ.add_op<unsigned>(OpType::CX, {0, 1});
circ.add_op<unsigned>(OpType::CX, {1, 2});
circ.add_op<unsigned>(OpType::CX, {2, 3});

REQUIRE(NoWireSwapsPredicate().verify(circ));
circ.replace_SWAPs();
REQUIRE(!NoWireSwapsPredicate().verify(circ));

CompilationUnit cu(circ);

REQUIRE(gen_full_mapping_pass_phase_poly(
architecture, 1, aas::CNotSynthType::Rec)
->apply(cu));
Circuit result = cu.get_circ_ref();

REQUIRE(test_unitary_comparison(result, circ));
REQUIRE(NoWireSwapsPredicate().verify(result));
}
}

Expand Down

0 comments on commit d3ab84b

Please sign in to comment.