Skip to content

Commit

Permalink
Timeout on GPGraph construction in GreedyPauliSimp (#1706)
Browse files Browse the repository at this point in the history
* Timeout on graph construction

* Update GreedyPauliConverters.cpp

* Update test_GreedyPauli.cpp

* bump

* Update test_GreedyPauli.cpp

* Update test_GreedyPauli.cpp

* Update test_GreedyPauli.cpp

* Update test_GreedyPauli.cpp

* Update test_GreedyPauli.cpp

* remove circuit constructor

unneeded

* Update tket/include/tket/Transformations/GreedyPauliOptimisation.hpp

Co-authored-by: Alec Edgington <[email protected]>

* Update test_GreedyPauli.cpp

* Update GreedyPauliOptimisation.hpp

---------

Co-authored-by: Alec Edgington <[email protected]>
  • Loading branch information
sjdilkes and cqc-alec authored Dec 5, 2024
1 parent 8108de9 commit e13ed26
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 69 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.53@tket/stable")
self.requires("tket/1.3.54@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
4 changes: 4 additions & 0 deletions pytket/docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Fixes:

* Fix circuit iteration giving invalid slices in some cases.

Performance:

* Update `GreedyPauliSimp` `thread_timeout` to hit timeout when constructing Pauli Graph.

1.36.0 (November 2024)
----------------------

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.53"
version = "1.3.54"
package_type = "library"
license = "Apache 2"
homepage = "https://github.com/CQCL/tket"
Expand Down
8 changes: 4 additions & 4 deletions tket/include/tket/Transformations/GreedyPauliOptimisation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,8 @@ typedef boost::adj_list_vertex_property_map<
*/
class GPGraph {
public:
/** Construct an GPGraph from a circuit */
GPGraph(const Circuit& circ);
/** Construct an GPGraph from the qubits and bits */
GPGraph(qubit_vector_t qubits, bit_vector_t bits);

GPVertSet get_successors(const GPVert& vert) const;

Expand All @@ -544,9 +544,8 @@ class GPGraph {
std::tuple<
std::vector<std::vector<PauliNode_ptr>>, std::vector<PauliNode_ptr>,
boost::bimap<unsigned, unsigned>>
get_sequence();
get_sequence(std::shared_ptr<std::atomic<bool>> stop_flag);

private:
/**
* Applies the given gate to the end of the graph.
* Clifford gates transform the tableau.
Expand All @@ -558,6 +557,7 @@ class GPGraph {
const Command& cmd, bool conditional = false,
std::vector<unsigned> cond_bits = {}, unsigned cond_value = 0);

private:
/**
* Add a Pauli rotation to the graph
* If the angle is non-Clifford or if conditional is true then add to the DAG
Expand Down
14 changes: 6 additions & 8 deletions tket/src/Transformations/GreedyPauliConverters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,8 @@ static bool nodes_commute(const PauliNode_ptr& n1, const PauliNode_ptr& n2) {
return true;
}

GPGraph::GPGraph(const Circuit& circ)
: n_qubits_(circ.n_qubits()), n_bits_(circ.n_bits()) {
qubit_vector_t qubits = circ.all_qubits();
bit_vector_t bits = circ.all_bits();
GPGraph::GPGraph(qubit_vector_t qubits, bit_vector_t bits)
: n_qubits_(qubits.size()), n_bits_(bits.size()) {
for (const Qubit& q : qubits) {
TKET_ASSERT(q.reg_name() == q_default_reg());
TKET_ASSERT(q.index().at(0) < qubits.size());
Expand All @@ -124,9 +122,6 @@ GPGraph::GPGraph(const Circuit& circ)
TKET_ASSERT(b.index().at(0) < bits.size());
}
cliff_ = UnitaryRevTableau(n_qubits_);
for (const Command& cmd : circ.get_commands()) {
apply_gate_at_end(cmd);
}
}

GPVertSet GPGraph::get_successors(const GPVert& vert) const {
Expand Down Expand Up @@ -487,11 +482,14 @@ std::vector<GPVert> GPGraph::vertices_in_order() const {
std::tuple<
std::vector<std::vector<PauliNode_ptr>>, std::vector<PauliNode_ptr>,
boost::bimap<unsigned, unsigned>>
GPGraph::get_sequence() {
GPGraph::get_sequence(std::shared_ptr<std::atomic<bool>> stop_flag) {
std::vector<GPVert> vertices = vertices_in_order();
auto it = vertices.begin();
std::vector<std::vector<PauliNode_ptr>> interior_nodes;
while (it != vertices.end()) {
if (stop_flag.get()->load()) {
return {};
}
const PauliNode_ptr& node = graph_[*it];
std::vector<PauliNode_ptr> commuting_set;
commuting_set.push_back(node);
Expand Down
11 changes: 9 additions & 2 deletions tket/src/Transformations/GreedyPauliOptimisation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,14 +772,21 @@ Circuit greedy_pauli_graph_synthesis_flag(
for (const auto& pair : unit_map) {
rev_unit_map.insert({pair.second, pair.first});
}
GPGraph gpg(circ_flat);

GPGraph gpg(circ_flat.all_qubits(), circ_flat.all_bits());
for (const Command& cmd : circ_flat.get_commands()) {
if (stop_flag.get()->load()) {
return Circuit();
}
gpg.apply_gate_at_end(cmd);
}

// We regularly check whether the timeout has ocurred
if (stop_flag.get()->load()) {
return Circuit();
}

auto [rotation_sets, rows, measures] = gpg.get_sequence();
auto [rotation_sets, rows, measures] = gpg.get_sequence(stop_flag);

if (stop_flag.get()->load()) {
return Circuit();
Expand Down
108 changes: 55 additions & 53 deletions tket/test/src/test_GreedyPauli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,70 +764,72 @@ SCENARIO("Test GreedyPauliSimp pass construction") {
SCENARIO("Test GreedyPauliSimp with multiple trials and threads") {
GIVEN("Large circuit with ZZPhase") {
Circuit circ(6);
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::X, Pauli::X}, 0.3)), {0, 1});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Z, Pauli::Y, Pauli::X}, 0.2)),
{0, 1, 2});
circ.add_box(
PauliExpCommutingSetBox({
{{Pauli::I, Pauli::Y, Pauli::I, Pauli::Z}, 1.2},
{{Pauli::X, Pauli::Y, Pauli::Z, Pauli::I}, 0.8},
{{Pauli::I, Pauli::I, Pauli::I, Pauli::Z}, 1.25},
}),
{1, 2, 3, 4});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Y, Pauli::X}, 0.1)), {2, 3});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Z, Pauli::Y, Pauli::X}, 0.11)),
{1, 3, 4});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Y, Pauli::Y}, 0.2)), {4, 5});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Z, Pauli::Z, Pauli::X}, 0.15)),
{2, 4, 5});
circ.add_box(
PauliExpBox(
SymPauliTensor({Pauli::X, Pauli::X, Pauli::X, Pauli::X}, 0.25)),
{2, 4, 5, 0});
circ.add_box(
PauliExpBox(
SymPauliTensor({Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X}, 0.125)),
{1, 3, 5, 0});
for (unsigned i = 0; i < 1000; i++) {
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::X, Pauli::X}, 0.3)), {0, 1});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Z, Pauli::Y, Pauli::X}, 0.2)),
{0, 1, 2});
circ.add_box(
PauliExpCommutingSetBox({
{{Pauli::I, Pauli::Y, Pauli::I, Pauli::Z}, 1.2},
{{Pauli::X, Pauli::Y, Pauli::Z, Pauli::I}, 0.8},
{{Pauli::I, Pauli::I, Pauli::I, Pauli::Z}, 1.25},
}),
{1, 2, 3, 4});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Y, Pauli::X}, 0.1)), {2, 3});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Z, Pauli::Y, Pauli::X}, 0.11)),
{1, 3, 4});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Y, Pauli::Y}, 0.2)), {4, 5});
circ.add_box(
PauliExpBox(SymPauliTensor({Pauli::Z, Pauli::Z, Pauli::X}, 0.15)),
{2, 4, 5});
circ.add_box(
PauliExpBox(
SymPauliTensor({Pauli::X, Pauli::X, Pauli::X, Pauli::X}, 0.25)),
{2, 4, 5, 0});
circ.add_box(
PauliExpBox(
SymPauliTensor({Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X}, 0.125)),
{1, 3, 5, 0});

circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::X, Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::X},
0.125)),
{1, 3, 5, 0, 2, 4});

circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X},
0.125)),
{0, 1, 2, 3, 4, 5});
circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::X, Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::X},
0.125)),
{1, 3, 5, 0, 2, 4});

circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::X, Pauli::Z, Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X},
0.125)),
{5, 2, 4, 1, 3, 0});
circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X},
0.125)),
{0, 1, 2, 3, 4, 5});

circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::X, Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::X},
0.125)),
{0, 5, 1, 4, 3, 2});
circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::X, Pauli::Z, Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X},
0.125)),
{5, 2, 4, 1, 3, 0});

circ.add_box(
PauliExpBox(SymPauliTensor(
{Pauli::X, Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::X},
0.125)),
{0, 5, 1, 4, 3, 2});
}
Circuit d(circ);
REQUIRE(!Transforms::greedy_pauli_optimisation(
0.7, 0.3, 500, 500, 0, true, 0, 10)
0.7, 0.3, 500, 500, 0, true, 1, 10)
.apply(d));
REQUIRE(Transforms::greedy_pauli_optimisation(
0.7, 0.3, 500, 500, 0, true, 10, 10)
0.7, 0.3, 500, 500, 0, true, 100, 10)
.apply(d));
REQUIRE(test_unitary_comparison(circ, d, true));
}
}

} // namespace test_GreedyPauliSimp
} // namespace tket

0 comments on commit e13ed26

Please sign in to comment.