From 737d4fc7e02c69cb47873e4a9d68f76407f857ac Mon Sep 17 00:00:00 2001 From: melf Date: Tue, 7 Dec 2021 18:01:01 +0000 Subject: [PATCH 1/3] add bugfix for wireswap in ppb creation --- tket/src/Circuit/Circuit.hpp | 11 ++++++ tket/src/Circuit/macro_manipulation.cpp | 12 +++++++ tket/src/Converters/PhasePoly.cpp | 45 ++++++++++++++++++++++--- tket/tests/test_PhasePolynomials.cpp | 34 +++++++++++++++++++ 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/tket/src/Circuit/Circuit.hpp b/tket/src/Circuit/Circuit.hpp index 98403d24b9..ff326a64b2 100644 --- a/tket/src/Circuit/Circuit.hpp +++ b/tket/src/Circuit/Circuit.hpp @@ -1272,6 +1272,17 @@ class Circuit { */ void replace_SWAPs(); + /** + * this function replaces an implicit wire swap between the two given qubits + * with three CX operations + * + * @param first qubits to add the wireswap on + * @param second qubits to add the wireswap on + * + * O(c) + */ + void replace_implicit_wire_swap(const Qubit first, const Qubit second); + // O(E+V+q) Circuit dagger() const; diff --git a/tket/src/Circuit/macro_manipulation.cpp b/tket/src/Circuit/macro_manipulation.cpp index e927b130f0..3fd6c0f3ab 100644 --- a/tket/src/Circuit/macro_manipulation.cpp +++ b/tket/src/Circuit/macro_manipulation.cpp @@ -381,6 +381,18 @@ void Circuit::replace_SWAPs() { remove_vertices(bin, GraphRewiring::No, VertexDeletion::Yes); } +void Circuit::replace_implicit_wire_swap( + const Qubit first, const Qubit second) { + add_op(OpType::CX, {first, second}); + add_op(OpType::CX, {second, first}); + Vertex cxvertex = add_op(OpType::CX, {first, second}); + EdgeVec outs = get_all_out_edges(cxvertex); + Edge out1 = outs[0]; + dag[out1].ports.first = 1; + Edge out2 = outs[1]; + dag[out2].ports.first = 0; +} + // helper functions for the dagger and transpose void Circuit::_handle_boundaries(Circuit& circ, vertex_map_t& vmap) const { // Handle boundaries diff --git a/tket/src/Converters/PhasePoly.cpp b/tket/src/Converters/PhasePoly.cpp index 62e4faf9ef..ddd0d924fa 100644 --- a/tket/src/Converters/PhasePoly.cpp +++ b/tket/src/Converters/PhasePoly.cpp @@ -147,18 +147,55 @@ Circuit gray_synth( PhasePolyBox::PhasePolyBox(const Circuit& circ) : Box(OpType::PhasePolyBox), n_qubits_(circ.n_qubits()) { - if (circ.n_bits() != 0) + Circuit newcirc(circ); + + // check for classical bits + if (newcirc.n_bits() != 0) throw NotValid( "Cannot construct phase polynomial from classical controlled " "gates"); + + // check the gateset of the circuit + for (const Command& com : newcirc) { + OpType ot = com.get_op_ptr()->get_type(); + + switch (ot) { + case OpType::CX: { + break; + } + case OpType::Rz: { + break; + } + default: { + throw NotValid("Only CXs and Rzs allowed in Phase Polynomials"); + } + } + } + + // replace wireswaps with three CX + while (newcirc.has_implicit_wireswaps()) { + bool foundswap = false; + + qubit_map_t perm = newcirc.implicit_qubit_permutation(); + for (const std::pair& pair : perm) { + if (pair.first != pair.second) { + if (!foundswap) { + newcirc.replace_implicit_wire_swap(pair.first, pair.second); + foundswap = true; + } + } + } + } + + // generate box signature_ = op_signature_t(n_qubits_, EdgeType::Quantum); unsigned i = 0; - for (const Qubit& qb : circ.all_qubits()) { + for (const Qubit& qb : newcirc.all_qubits()) { qubit_indices_.insert({qb, i}); ++i; } linear_transformation_ = MatrixXb::Identity(n_qubits_, n_qubits_); - for (const Command& com : circ) { + for (const Command& com : newcirc) { OpType ot = com.get_op_ptr()->get_type(); unit_vector_t qbs = com.get_args(); if (ot == OpType::CX) { @@ -180,7 +217,7 @@ PhasePolyBox::PhasePolyBox(const Circuit& circ) else pp_it->second += com.get_op_ptr()->get_params().at(0); } else - throw NotImplemented("Only CXs and Rzs allowed in Phase Polynomials"); + TKET_ASSERT(!"Only CXs and Rzs allowed in Phase Polynomials"); } } diff --git a/tket/tests/test_PhasePolynomials.cpp b/tket/tests/test_PhasePolynomials.cpp index 44650df014..b7ddbaa731 100644 --- a/tket/tests/test_PhasePolynomials.cpp +++ b/tket/tests/test_PhasePolynomials.cpp @@ -713,6 +713,40 @@ SCENARIO("Test conversion of circuit to circuit with phase poly boxes") { REQUIRE(test_statevector_comparison(circ, result)); } } +SCENARIO("Phase polynomial synthesis without architecture") { + GIVEN("single SWAP circuit") { + Circuit circ(2); + circ.add_op(OpType::SWAP, {0, 1}); + circ.replace_SWAPs(); + PhasePolyBox ppbox(circ); + std::shared_ptr circptr = ppbox.to_circuit(); + Circuit circ2 = *circptr; + REQUIRE(test_unitary_comparison(circ, circ2)); + } + GIVEN("more SWAP circuit") { + Circuit circ(5); + circ.add_op(OpType::SWAP, {0, 1}); + circ.add_op(OpType::SWAP, {0, 2}); + circ.add_op(OpType::SWAP, {0, 3}); + circ.replace_SWAPs(); + PhasePolyBox ppbox(circ); + std::shared_ptr circptr = ppbox.to_circuit(); + Circuit circ2 = *circptr; + REQUIRE(test_unitary_comparison(circ, circ2)); + } + GIVEN("more SWAP circuit II") { + Circuit circ(5); + circ.add_op(OpType::SWAP, {0, 1}); + circ.add_op(OpType::SWAP, {1, 2}); + circ.add_op(OpType::SWAP, {2, 3}); + circ.add_op(OpType::SWAP, {3, 4}); + circ.replace_SWAPs(); + PhasePolyBox ppbox(circ); + std::shared_ptr circptr = ppbox.to_circuit(); + Circuit circ2 = *circptr; + REQUIRE(test_unitary_comparison(circ, circ2)); + } +} } // namespace test_PhasePolynomials } // namespace tket From c48604f5feff148d3c589baaef52ef2f10ff8db1 Mon Sep 17 00:00:00 2001 From: melf Date: Tue, 7 Dec 2021 18:27:44 +0000 Subject: [PATCH 2/3] try to fix mac --- tket/src/Converters/PhasePoly.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tket/src/Converters/PhasePoly.cpp b/tket/src/Converters/PhasePoly.cpp index ddd0d924fa..22957768dc 100644 --- a/tket/src/Converters/PhasePoly.cpp +++ b/tket/src/Converters/PhasePoly.cpp @@ -177,7 +177,7 @@ PhasePolyBox::PhasePolyBox(const Circuit& circ) bool foundswap = false; qubit_map_t perm = newcirc.implicit_qubit_permutation(); - for (const std::pair& pair : perm) { + for (const std::pair& pair : perm) { if (pair.first != pair.second) { if (!foundswap) { newcirc.replace_implicit_wire_swap(pair.first, pair.second); From 0e7f53e6f5204b9bac7e156d330ac76f2703ff42 Mon Sep 17 00:00:00 2001 From: melf Date: Tue, 7 Dec 2021 18:29:50 +0000 Subject: [PATCH 3/3] try to fix mac II --- tket/src/Converters/PhasePoly.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tket/src/Converters/PhasePoly.cpp b/tket/src/Converters/PhasePoly.cpp index 22957768dc..086aca5c42 100644 --- a/tket/src/Converters/PhasePoly.cpp +++ b/tket/src/Converters/PhasePoly.cpp @@ -177,7 +177,7 @@ PhasePolyBox::PhasePolyBox(const Circuit& circ) bool foundswap = false; qubit_map_t perm = newcirc.implicit_qubit_permutation(); - for (const std::pair& pair : perm) { + for (const std::pair& pair : perm) { if (pair.first != pair.second) { if (!foundswap) { newcirc.replace_implicit_wire_swap(pair.first, pair.second);