From 171356489c783b1322972fdddfba4702e496c3de Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:39:16 +0000 Subject: [PATCH 01/19] add timeout --- pytket/binders/passes.cpp | 4 ++- .../tket/Predicates/PassGenerators.hpp | 3 ++- .../GreedyPauliOptimisation.hpp | 2 +- tket/src/Predicates/PassGenerators.cpp | 5 ++-- .../GreedyPauliOptimisation.cpp | 25 +++++++++++++------ 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/pytket/binders/passes.cpp b/pytket/binders/passes.cpp index 6768b6d3a9..0edf619915 100644 --- a/pytket/binders/passes.cpp +++ b/pytket/binders/passes.cpp @@ -957,10 +957,12 @@ PYBIND11_MODULE(passes, m) { "\n:param allow_zzphase: If set to True, allows the algorithm to " "implement 2-qubit rotations using ZZPhase gates when deemed " "optimal. Defaults to False." + "\n:param timeout: Sets maximum out of time spent finding solution." "\n:return: a pass to perform the simplification", py::arg("discount_rate") = 0.7, py::arg("depth_weight") = 0.3, py::arg("max_lookahead") = 500, py::arg("max_tqe_candidates") = 500, - py::arg("seed") = 0, py::arg("allow_zzphase") = false); + py::arg("seed") = 0, py::arg("allow_zzphase") = false, + py::arg("timeout") = 100); m.def( "PauliSquash", &PauliSquash, "Applies :py:meth:`PauliSimp` followed by " diff --git a/tket/include/tket/Predicates/PassGenerators.hpp b/tket/include/tket/Predicates/PassGenerators.hpp index 9e7f87931c..59fe71bcfe 100644 --- a/tket/include/tket/Predicates/PassGenerators.hpp +++ b/tket/include/tket/Predicates/PassGenerators.hpp @@ -354,12 +354,13 @@ PassPtr gen_special_UCC_synthesis( * @param max_tqe_candidates * @param seed * @param allow_zzphase + * @param timeout * @return PassPtr */ PassPtr gen_greedy_pauli_simp( double discount_rate = 0.7, double depth_weight = 0.3, unsigned max_lookahead = 500, unsigned max_tqe_candidates = 500, - unsigned seed = 0, bool allow_zzphase = false); + unsigned seed = 0, bool allow_zzphase = false, unsigned timeout = 100); /** * Generate a pass to simplify the circuit where it acts on known basis states. diff --git a/tket/include/tket/Transformations/GreedyPauliOptimisation.hpp b/tket/include/tket/Transformations/GreedyPauliOptimisation.hpp index de6bb19d5c..3cc6348582 100644 --- a/tket/include/tket/Transformations/GreedyPauliOptimisation.hpp +++ b/tket/include/tket/Transformations/GreedyPauliOptimisation.hpp @@ -643,7 +643,7 @@ Circuit greedy_pauli_set_synthesis( Transform greedy_pauli_optimisation( double discount_rate = 0.7, double depth_weight = 0.3, unsigned max_lookahead = 500, unsigned max_tqe_candidates = 500, - unsigned seed = 0, bool allow_zzphase = false); + unsigned seed = 0, bool allow_zzphase = false, unsigned timeout = 100); } // namespace Transforms diff --git a/tket/src/Predicates/PassGenerators.cpp b/tket/src/Predicates/PassGenerators.cpp index 610caabd84..db8291daf5 100644 --- a/tket/src/Predicates/PassGenerators.cpp +++ b/tket/src/Predicates/PassGenerators.cpp @@ -1015,10 +1015,11 @@ PassPtr gen_synthesise_pauli_graph( PassPtr gen_greedy_pauli_simp( double discount_rate, double depth_weight, unsigned max_lookahead, - unsigned max_tqe_candidates, unsigned seed, bool allow_zzphase) { + unsigned max_tqe_candidates, unsigned seed, bool allow_zzphase, + unsigned timeout) { Transform t = Transforms::greedy_pauli_optimisation( discount_rate, depth_weight, max_lookahead, max_tqe_candidates, seed, - allow_zzphase); + allow_zzphase, timeout); OpTypeSet ins = { OpType::Z, OpType::X, diff --git a/tket/src/Transformations/GreedyPauliOptimisation.cpp b/tket/src/Transformations/GreedyPauliOptimisation.cpp index e052102656..0e59711f23 100644 --- a/tket/src/Transformations/GreedyPauliOptimisation.cpp +++ b/tket/src/Transformations/GreedyPauliOptimisation.cpp @@ -15,6 +15,8 @@ #include "tket/Transformations/GreedyPauliOptimisation.hpp" #include +#include +#include #include #include "tket/Circuit/PauliExpBoxes.hpp" @@ -778,15 +780,22 @@ Circuit greedy_pauli_graph_synthesis( Transform greedy_pauli_optimisation( double discount_rate, double depth_weight, unsigned max_lookahead, - unsigned max_tqe_candidates, unsigned seed, bool allow_zzphase) { + unsigned max_tqe_candidates, unsigned seed, bool allow_zzphase, + unsigned timeout) { return Transform([discount_rate, depth_weight, max_lookahead, - max_tqe_candidates, seed, allow_zzphase](Circuit& circ) { - circ = GreedyPauliSimp::greedy_pauli_graph_synthesis( - circ, discount_rate, depth_weight, max_lookahead, max_tqe_candidates, - seed, allow_zzphase); - // decompose the conditional CircBoxes - circ.decompose_boxes_recursively(); - return true; + max_tqe_candidates, seed, allow_zzphase, + timeout](Circuit& circ) { + std::future future = std::async( + std::launch::async, GreedyPauliSimp::greedy_pauli_graph_synthesis, circ, + discount_rate, depth_weight, max_lookahead, max_tqe_candidates, seed, + allow_zzphase); + if (future.wait_for(std::chrono::seconds(timeout)) == + std::future_status::ready) { + circ = future.get(); + circ.decompose_boxes_recursively(); + return true; + } + return false; }); } From e275cf81dc692d65aff399f79420778b74caa42c Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:47:50 +0000 Subject: [PATCH 02/19] add timeout to serialisation --- tket/src/Predicates/CompilerPass.cpp | 3 ++- tket/src/Predicates/PassGenerators.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tket/src/Predicates/CompilerPass.cpp b/tket/src/Predicates/CompilerPass.cpp index f0a5461e4b..580aa29098 100644 --- a/tket/src/Predicates/CompilerPass.cpp +++ b/tket/src/Predicates/CompilerPass.cpp @@ -521,9 +521,10 @@ PassPtr deserialise( unsigned max_lookahead = content.at("max_lookahead").get(); unsigned seed = content.at("seed").get(); bool allow_zzphase = content.at("allow_zzphase").get(); + unsigned timeout = content.at("timeout").get(); pp = gen_greedy_pauli_simp( discount_rate, depth_weight, max_lookahead, max_tqe_candidates, seed, - allow_zzphase); + allow_zzphase, timeout); } else if (passname == "PauliSimp") { // SEQUENCE PASS - DESERIALIZABLE ONLY diff --git a/tket/src/Predicates/PassGenerators.cpp b/tket/src/Predicates/PassGenerators.cpp index db8291daf5..d33b83edff 100644 --- a/tket/src/Predicates/PassGenerators.cpp +++ b/tket/src/Predicates/PassGenerators.cpp @@ -1068,6 +1068,7 @@ PassPtr gen_greedy_pauli_simp( j["max_tqe_candidates"] = max_tqe_candidates; j["seed"] = seed; j["allow_zzphase"] = allow_zzphase; + j["timeout"] = timeout; return std::make_shared(precons, t, postcon, j); } From 4fea92626da91d86d146d5223c164c716c2bb004 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:48:09 +0000 Subject: [PATCH 03/19] Update changelog.rst --- pytket/docs/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/pytket/docs/changelog.rst b/pytket/docs/changelog.rst index df54b92f4e..dab6e73aa0 100644 --- a/pytket/docs/changelog.rst +++ b/pytket/docs/changelog.rst @@ -12,6 +12,7 @@ Features: conditions. * Add `custom_deserialisation` argument to `BasePass` and `SequencePass` `from_dict` method to support construction of `CustomPass` from json. +* Add `timeout` argument to `GreedyPauliSimp`. Fixes: From 87aec9eb27c4c2bf01c21dee7db1adb0aeef8ad0 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:49:04 +0000 Subject: [PATCH 04/19] bump library --- pytket/conanfile.py | 2 +- tket/conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pytket/conanfile.py b/pytket/conanfile.py index 094c0e3d89..e23892a53b 100644 --- a/pytket/conanfile.py +++ b/pytket/conanfile.py @@ -38,7 +38,7 @@ def requirements(self): self.requires("pybind11_json/0.2.14") self.requires("symengine/0.12.0") self.requires("tkassert/0.3.4@tket/stable") - self.requires("tket/1.3.39@tket/stable") + self.requires("tket/1.3.40@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") diff --git a/tket/conanfile.py b/tket/conanfile.py index 147e674cb2..31633eef95 100644 --- a/tket/conanfile.py +++ b/tket/conanfile.py @@ -23,7 +23,7 @@ class TketConan(ConanFile): name = "tket" - version = "1.3.39" + version = "1.3.40" package_type = "library" license = "Apache 2" homepage = "https://github.com/CQCL/tket" From be649449917403214325f05d9046495630359262 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:57:16 +0000 Subject: [PATCH 05/19] Update transform.cpp --- pytket/binders/transform.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pytket/binders/transform.cpp b/pytket/binders/transform.cpp index 21724759c3..cfd70bcec3 100644 --- a/pytket/binders/transform.cpp +++ b/pytket/binders/transform.cpp @@ -440,10 +440,12 @@ PYBIND11_MODULE(transform, m) { "\n:param allow_zzphase: If set to True, allows the algorithm to " "implement 2-qubit rotations using ZZPhase gates when deemed " "optimal. Defaults to False." + "\n:param timeout: Sets maximum out of time spent finding solution." "\n:return: a pass to perform the simplification", py::arg("discount_rate") = 0.7, py::arg("depth_weight") = 0.3, py::arg("max_tqe_candidates") = 500, py::arg("max_lookahead") = 500, - py::arg("seed") = 0, py::arg("allow_zzphase") = false) + py::arg("seed") = 0, py::arg("allow_zzphase") = false, + py::arg("timeout") = 100) .def_static( "ZZPhaseToRz", &Transforms::ZZPhase_to_Rz, "Fixes all ZZPhase gate angles to [-1, 1) half turns.") From 02bb1d045e0dff129845b78ccc2ea2e9990f8407 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:03:18 +0000 Subject: [PATCH 06/19] Update test_GreedyPauli.cpp --- tket/test/src/test_GreedyPauli.cpp | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tket/test/src/test_GreedyPauli.cpp b/tket/test/src/test_GreedyPauli.cpp index 366143ece4..dd855ea1b0 100644 --- a/tket/test/src/test_GreedyPauli.cpp +++ b/tket/test/src/test_GreedyPauli.cpp @@ -709,6 +709,46 @@ SCENARIO("Test GreedyPauliSimp for individual gates") { REQUIRE(test_unitary_comparison(circ, d, true)); } } + +SCENARIO("Test greedy_pauli_optimisation timeout") { + GIVEN("Large circuit with ZZPhase, 0 second timeout.") { + 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}); + Circuit d(circ); + REQUIRE( + !Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 0) + .apply(d)); + } +} SCENARIO("Test GreedyPauliSimp pass construction") { // test pass construction GIVEN("A circuit") { From 9862430bab6b4ba23440ab6ab016f3ad8468a84e Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:10:05 +0000 Subject: [PATCH 07/19] update stubs --- pytket/pytket/_tket/passes.pyi | 3 ++- pytket/pytket/_tket/transform.pyi | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pytket/pytket/_tket/passes.pyi b/pytket/pytket/_tket/passes.pyi index 650273f020..f2efed5973 100644 --- a/pytket/pytket/_tket/passes.pyi +++ b/pytket/pytket/_tket/passes.pyi @@ -444,7 +444,7 @@ def GlobalisePhasedX(squash: bool = True) -> BasePass: It is not recommended to use this pass with symbolic expressions, as in certain cases a blow-up in symbolic expression sizes may occur. """ -def GreedyPauliSimp(discount_rate: float = 0.7, depth_weight: float = 0.3, max_lookahead: int = 500, max_tqe_candidates: int = 500, seed: int = 0, allow_zzphase: bool = False) -> BasePass: +def GreedyPauliSimp(discount_rate: float = 0.7, depth_weight: float = 0.3, max_lookahead: int = 500, max_tqe_candidates: int = 500, seed: int = 0, allow_zzphase: bool = False, timeout: int = 100) -> BasePass: """ Construct a pass that converts a circuit into a graph of Pauli gadgets to account for commutation and phase folding, and resynthesises them using a greedy algorithm adapted from arxiv.org/abs/2103.08602. The method for synthesising the final Clifford operator is adapted from arxiv.org/abs/2305.10966. @@ -454,6 +454,7 @@ def GreedyPauliSimp(discount_rate: float = 0.7, depth_weight: float = 0.3, max_l :param max_lookahead: Maximum lookahead when evaluating each Clifford gate candidate. Default to 500. :param seed: Unsigned integer seed used for sampling candidates and tie breaking. Default to 0. :param allow_zzphase: If set to True, allows the algorithm to implement 2-qubit rotations using ZZPhase gates when deemed optimal. Defaults to False. + :param timeout: Sets maximum out of time spent finding solution. :return: a pass to perform the simplification """ def GuidedPauliSimp(strat: pytket._tket.transform.PauliSynthStrat = pytket._tket.transform.PauliSynthStrat.Sets, cx_config: pytket._tket.circuit.CXConfigType = pytket._tket.circuit.CXConfigType.Snake) -> BasePass: diff --git a/pytket/pytket/_tket/transform.pyi b/pytket/pytket/_tket/transform.pyi index 4801b4238c..ce620128b2 100644 --- a/pytket/pytket/_tket/transform.pyi +++ b/pytket/pytket/_tket/transform.pyi @@ -165,7 +165,7 @@ class Transform: It is not recommended to use this transformation with symbolic expressions, as in certain cases a blow-up in symbolic expression sizes may occur. """ @staticmethod - def GreedyPauliSimp(discount_rate: float = 0.7, depth_weight: float = 0.3, max_tqe_candidates: int = 500, max_lookahead: int = 500, seed: int = 0, allow_zzphase: bool = False) -> Transform: + def GreedyPauliSimp(discount_rate: float = 0.7, depth_weight: float = 0.3, max_tqe_candidates: int = 500, max_lookahead: int = 500, seed: int = 0, allow_zzphase: bool = False, timeout: int = 100) -> Transform: """ Convert a circuit into a graph of Pauli gadgets to account for commutation and phase folding, and resynthesises them using a greedy algorithm adapted from arxiv.org/abs/2103.08602. The method for synthesising the final Clifford operator is adapted from arxiv.org/abs/2305.10966. @@ -175,6 +175,7 @@ class Transform: :param max_lookahead: Maximum lookahead when evaluating each Clifford gate candidate. Default to 500. :param seed: Unsigned integer seed used for sampling candidates and tie breaking. Default to 0. :param allow_zzphase: If set to True, allows the algorithm to implement 2-qubit rotations using ZZPhase gates when deemed optimal. Defaults to False. + :param timeout: Sets maximum out of time spent finding solution. :return: a pass to perform the simplification """ @staticmethod From a147bb4d1deba3f5acd4fb52a536a2032037ff65 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:29:17 +0000 Subject: [PATCH 08/19] fix serialisation --- pytket/tests/passes_serialisation_test.py | 6 ++---- schemas/compiler_pass_v1.json | 9 +++++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pytket/tests/passes_serialisation_test.py b/pytket/tests/passes_serialisation_test.py index 3c76194963..dbfcf168a2 100644 --- a/pytket/tests/passes_serialisation_test.py +++ b/pytket/tests/passes_serialisation_test.py @@ -20,8 +20,6 @@ from pathlib import Path from typing import Any, Dict, List -from sympy import Expr - from pytket.circuit import Node, Circuit, Qubit, OpType from pytket.predicates import Predicate from pytket.architecture import Architecture @@ -36,7 +34,6 @@ CommuteThroughMultis, RepeatWithMetricPass, RebaseCustom, - CXMappingPass, FullMappingPass, DefaultMappingPass, AASRouting, @@ -299,6 +296,7 @@ def nonparam_predicate_dict(name: str) -> Dict[str, Any]: "max_tqe_candidates": 100, "seed": 2, "allow_zzphase": True, + "timeout": 5000, } ), # lists must be sorted by OpType value @@ -699,7 +697,7 @@ def tk1_rep(a: ParamType, b: ParamType, c: ParamType) -> Circuit: np_pass = dm_pass_0.get_sequence()[2] d_pass = dm_pass.get_sequence()[1] assert d_pass.to_dict()["StandardPass"]["name"] == "DelayMeasures" - assert d_pass.to_dict()["StandardPass"]["allow_partial"] == False + assert not d_pass.to_dict()["StandardPass"]["allow_partial"] assert p_pass.to_dict()["StandardPass"]["name"] == "PlacementPass" assert np_pass.to_dict()["StandardPass"]["name"] == "NaivePlacementPass" assert r_pass.to_dict()["StandardPass"]["name"] == "RoutingPass" diff --git a/schemas/compiler_pass_v1.json b/schemas/compiler_pass_v1.json index b8175c8b92..d36580d3d8 100644 --- a/schemas/compiler_pass_v1.json +++ b/schemas/compiler_pass_v1.json @@ -373,6 +373,10 @@ "allow_zzphase": { "type": "boolean", "definition": "parameter controlling the use of ZZPhase gates in \"GreedyPauliSimp\"" + }, + "timeout": { + "type": "number", + "definition": "parameter controlling the maximum runtime of \"GreedyPauliSimp\"" } }, "required": [ @@ -903,9 +907,10 @@ "max_lookahead", "max_tqe_candidates", "seed", - "allow_zzphase" + "allow_zzphase", + "timeout" ], - "maxProperties": 7 + "maxProperties": 8 } }, { From e3716f1ea6aa6212900727a2b8a9581113757bdc Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:30:44 +0000 Subject: [PATCH 09/19] Update test_GreedyPauli.cpp --- tket/test/src/test_GreedyPauli.cpp | 47 ++++-------------------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/tket/test/src/test_GreedyPauli.cpp b/tket/test/src/test_GreedyPauli.cpp index dd855ea1b0..73675929d8 100644 --- a/tket/test/src/test_GreedyPauli.cpp +++ b/tket/test/src/test_GreedyPauli.cpp @@ -620,8 +620,12 @@ SCENARIO("Complete synthesis") { SymPauliTensor({Pauli::Y, Pauli::Z, Pauli::Z, Pauli::X}, 0.125)), {1, 3, 5, 0}); Circuit d(circ); - REQUIRE(Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true) - .apply(d)); + REQUIRE( + !Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 0) + .apply(d)); + REQUIRE( + Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 10) + .apply(d)); REQUIRE(test_unitary_comparison(circ, d, true)); } GIVEN("Select TQE over ZZPhase") { @@ -710,45 +714,6 @@ SCENARIO("Test GreedyPauliSimp for individual gates") { } } -SCENARIO("Test greedy_pauli_optimisation timeout") { - GIVEN("Large circuit with ZZPhase, 0 second timeout.") { - 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}); - Circuit d(circ); - REQUIRE( - !Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 0) - .apply(d)); - } -} SCENARIO("Test GreedyPauliSimp pass construction") { // test pass construction GIVEN("A circuit") { From 278474796618314937930a3f08bd3e233df777eb Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:41:05 +0000 Subject: [PATCH 10/19] optionally relabel classical expressions when renaming units --- pytket/binders/circuit/Circuit/main.cpp | 7 ++++++- pytket/tests/predicates_test.py | 4 +++- tket/include/tket/Circuit/Circuit.hpp | 16 +++++++++------- tket/src/Circuit/basic_circ_manip.cpp | 4 ++-- .../Transformations/GreedyPauliOptimisation.cpp | 3 +-- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 867996beb1..ce999432c5 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -322,7 +322,12 @@ void def_circuit(py::class_> &pyCircuit) { .def( "flatten_registers", &Circuit::flatten_registers, "Combines all qubits into a single register namespace with " - "the default name, and likewise for bits") + "the default name, and likewise for bits" + "\n\n:param relabel_classical_expression: Determines whether python " + "classical expressions held in `ClassicalExpBox` have their " + "expression " + "relabelled to match relabelled Bit.", + py::arg("relabel_classical_expression") = true) // Circuit composition: .def( diff --git a/pytket/tests/predicates_test.py b/pytket/tests/predicates_test.py index ffc0f26064..b18180c48c 100644 --- a/pytket/tests/predicates_test.py +++ b/pytket/tests/predicates_test.py @@ -1040,6 +1040,7 @@ def test_greedy_pauli_synth() -> None: ).SWAP(regb[1], rega[0]) d = circ.copy() pss = GreedyPauliSimp(0.5, 0.5) + assert not GreedyPauliSimp(0.5, 0.5, timeout = 0).apply(d) assert pss.apply(d) assert np.allclose(circ.get_unitary(), d.get_unitary()) assert d.name == "test" @@ -1062,7 +1063,8 @@ def test_greedy_pauli_synth() -> None: circ.measure_all() circ.Reset(0) circ.add_pauliexpbox(pg1, [2, 3]) - assert GreedyPauliSimp(0.5, 0.5, 100, 100, 0, True).apply(circ) + assert not GreedyPauliSimp(0.5, 0.5, 100, 100, 0, True, 0).apply(circ) + assert GreedyPauliSimp(0.5, 0.5, 100, 100, 0, True, 100).apply(circ) # PauliExpBoxes implemented using ZZPhase d = Circuit(4, 4, name="test") d.H(0) diff --git a/tket/include/tket/Circuit/Circuit.hpp b/tket/include/tket/Circuit/Circuit.hpp index 64a4f338c9..73777c89c7 100644 --- a/tket/include/tket/Circuit/Circuit.hpp +++ b/tket/include/tket/Circuit/Circuit.hpp @@ -749,9 +749,12 @@ class Circuit { /** * Convert all quantum and classical bits to use default registers. * + * @param relabel_classical_expression Whether expressions in ClassicalExpBox + * have their expr updated to match the input wires + * * @return mapping from old to new unit IDs */ - unit_map_t flatten_registers(); + unit_map_t flatten_registers(bool relabel_classical_expression = true); //_________________________________________________ @@ -1044,7 +1047,8 @@ class Circuit { * @return true iff circuit was modified */ template - bool rename_units(const std::map &qm); + bool rename_units( + const std::map &qm, bool relabel_classicalexpbox = true); /** Automatically rewire holes when removing vertices from the circuit? */ enum class GraphRewiring { Yes, No }; @@ -1718,7 +1722,8 @@ JSON_DECL(Circuit) /** Templated method definitions */ template -bool Circuit::rename_units(const std::map &qm) { +bool Circuit::rename_units( + const std::map &qm, bool relabel_classicalexpbox) { // Can only work for Unit classes static_assert(std::is_base_of::value); static_assert(std::is_base_of::value); @@ -1767,21 +1772,18 @@ bool Circuit::rename_units(const std::map &qm) { "Unit already exists in circuit: " + pair.first.repr()); TKET_ASSERT(modified); } - // For every ClassicalExpBox, update its logic expressions - if (!bm.empty()) { + if (!bm.empty() && relabel_classicalexpbox) { BGL_FORALL_VERTICES(v, dag, DAG) { Op_ptr op = get_Op_ptr_from_Vertex(v); if (op->get_type() == OpType::ClassicalExpBox) { const ClassicalExpBoxBase &cbox = static_cast(*op); // rename_units is marked as const to get around the Op_ptr - // cast, but it can still mutate a python object modified |= cbox.rename_units(bm); } } } - return modified; } diff --git a/tket/src/Circuit/basic_circ_manip.cpp b/tket/src/Circuit/basic_circ_manip.cpp index ca3d27faa3..9bb8b11902 100644 --- a/tket/src/Circuit/basic_circ_manip.cpp +++ b/tket/src/Circuit/basic_circ_manip.cpp @@ -422,7 +422,7 @@ void Circuit::remove_edge(const Edge& edge) { boost::remove_edge(edge, this->dag); } -unit_map_t Circuit::flatten_registers() { +unit_map_t Circuit::flatten_registers(bool relabel_classical_expression) { unit_map_t rename_map; unsigned q_index = 0; unsigned c_index = 0; @@ -434,7 +434,7 @@ unit_map_t Circuit::flatten_registers() { } } try { - rename_units(rename_map); + rename_units(rename_map, relabel_classical_expression); } catch (const std::exception& e) { std::stringstream ss; ss << "Unable to flatten registers: " << e.what(); diff --git a/tket/src/Transformations/GreedyPauliOptimisation.cpp b/tket/src/Transformations/GreedyPauliOptimisation.cpp index 0e59711f23..e0c1890a7a 100644 --- a/tket/src/Transformations/GreedyPauliOptimisation.cpp +++ b/tket/src/Transformations/GreedyPauliOptimisation.cpp @@ -742,7 +742,6 @@ Circuit greedy_pauli_graph_synthesis( if (max_tqe_candidates == 0) { throw GreedyPauliSimpError("max_tqe_candidates must be greater than 0."); } - Circuit circ_flat(circ); unsigned n_qubits = circ_flat.n_qubits(); unsigned n_bits = circ_flat.n_bits(); @@ -752,7 +751,7 @@ Circuit greedy_pauli_graph_synthesis( if (name != std::nullopt) { new_circ.set_name(name.value()); } - unit_map_t unit_map = circ_flat.flatten_registers(); + unit_map_t unit_map = circ_flat.flatten_registers(false); unit_map_t rev_unit_map; for (const auto& pair : unit_map) { rev_unit_map.insert({pair.second, pair.first}); From 8cda1151a8ee89a0053f11bb50ecd8a570be487f Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:43:00 +0000 Subject: [PATCH 11/19] Update predicates_test.py --- pytket/tests/predicates_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/tests/predicates_test.py b/pytket/tests/predicates_test.py index b18180c48c..167420afdf 100644 --- a/pytket/tests/predicates_test.py +++ b/pytket/tests/predicates_test.py @@ -1040,7 +1040,7 @@ def test_greedy_pauli_synth() -> None: ).SWAP(regb[1], rega[0]) d = circ.copy() pss = GreedyPauliSimp(0.5, 0.5) - assert not GreedyPauliSimp(0.5, 0.5, timeout = 0).apply(d) + assert not GreedyPauliSimp(0.5, 0.5, timeout=0).apply(d) assert pss.apply(d) assert np.allclose(circ.get_unitary(), d.get_unitary()) assert d.name == "test" From 809d385bcc7862939e9f765df164e0cd3114c18d Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:52:17 +0000 Subject: [PATCH 12/19] update flattenrelabelregisters --- pytket/binders/passes.cpp | 7 +++++-- pytket/docs/changelog.rst | 2 ++ pytket/pytket/_tket/circuit.pyi | 4 +++- pytket/pytket/_tket/passes.pyi | 3 ++- schemas/compiler_pass_v1.json | 5 +++-- tket/include/tket/Predicates/PassGenerators.hpp | 2 +- tket/src/Predicates/CompilerPass.cpp | 2 +- tket/src/Predicates/PassGenerators.cpp | 5 +++-- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/pytket/binders/passes.cpp b/pytket/binders/passes.cpp index 0edf619915..3d96b982a9 100644 --- a/pytket/binders/passes.cpp +++ b/pytket/binders/passes.cpp @@ -752,9 +752,12 @@ PYBIND11_MODULE(passes, m) { "FlattenRelabelRegistersPass", &gen_flatten_relabel_registers_pass, "Removes empty Quantum wires from the Circuit and relabels all Qubit to " "a register from passed name. \n\n:param label: Name to relabel " - "remaining Qubit to, default 'q'.\n:return: A pass that removes empty " + "remaining Qubit to, default 'q'.\n:param relabel_classical_expressions: " + "Whether to relabel arguments of expressions held in `ClassicalExpBox`. " + "\n:return: A pass that removes empty " "wires and relabels.", - py::arg("label") = q_default_reg()); + py::arg("label") = q_default_reg(), + py::arg("relabel_classical_expressions") = true); m.def( "RenameQubitsPass", &gen_rename_qubits_pass, diff --git a/pytket/docs/changelog.rst b/pytket/docs/changelog.rst index dab6e73aa0..5e2b38e137 100644 --- a/pytket/docs/changelog.rst +++ b/pytket/docs/changelog.rst @@ -13,6 +13,8 @@ Features: * Add `custom_deserialisation` argument to `BasePass` and `SequencePass` `from_dict` method to support construction of `CustomPass` from json. * Add `timeout` argument to `GreedyPauliSimp`. +* Add option to not relabel `ClassicalExpBox` when calling `rename_units` + and `flatten_registers` Fixes: diff --git a/pytket/pytket/_tket/circuit.pyi b/pytket/pytket/_tket/circuit.pyi index 4cbc158def..f153fd5fd0 100644 --- a/pytket/pytket/_tket/circuit.pyi +++ b/pytket/pytket/_tket/circuit.pyi @@ -2104,9 +2104,11 @@ class Circuit: :param types: the set of operation types of interest :return: the circuit depth with respect to operations matching an element of `types` """ - def flatten_registers(self) -> dict[pytket._tket.unit_id.UnitID, pytket._tket.unit_id.UnitID]: + def flatten_registers(self, relabel_classical_expression: bool = True) -> dict[pytket._tket.unit_id.UnitID, pytket._tket.unit_id.UnitID]: """ Combines all qubits into a single register namespace with the default name, and likewise for bits + + :param relabel_classical_expression: Determines whether python classical expressions held in `ClassicalExpBox` have their expression relabelled to match relabelled Bit. """ def free_symbols(self) -> set[sympy.Symbol]: """ diff --git a/pytket/pytket/_tket/passes.pyi b/pytket/pytket/_tket/passes.pyi index f2efed5973..b928a2e970 100644 --- a/pytket/pytket/_tket/passes.pyi +++ b/pytket/pytket/_tket/passes.pyi @@ -410,11 +410,12 @@ def FlattenRegisters() -> BasePass: """ Merges all quantum and classical registers into their respective default registers with contiguous indexing. """ -def FlattenRelabelRegistersPass(label: str = 'q') -> BasePass: +def FlattenRelabelRegistersPass(label: str = 'q', relabel_classical_expressions: bool = True) -> BasePass: """ Removes empty Quantum wires from the Circuit and relabels all Qubit to a register from passed name. :param label: Name to relabel remaining Qubit to, default 'q'. + :param relabel_classical_expressions: Whether to relabel arguments of expressions held in `ClassicalExpBox`. :return: A pass that removes empty wires and relabels. """ def FullMappingPass(arc: pytket._tket.architecture.Architecture, placer: pytket._tket.placement.Placement, config: typing.Sequence[pytket._tket.mapping.RoutingMethod]) -> BasePass: diff --git a/schemas/compiler_pass_v1.json b/schemas/compiler_pass_v1.json index d36580d3d8..dbd68c9e18 100644 --- a/schemas/compiler_pass_v1.json +++ b/schemas/compiler_pass_v1.json @@ -648,9 +648,10 @@ }, "then": { "required": [ - "label" + "label", + "relabel_classical_registers" ], - "maxProperties": 2 + "maxProperties": 3 } }, { diff --git a/tket/include/tket/Predicates/PassGenerators.hpp b/tket/include/tket/Predicates/PassGenerators.hpp index 59fe71bcfe..f4bcb4a8d4 100644 --- a/tket/include/tket/Predicates/PassGenerators.hpp +++ b/tket/include/tket/Predicates/PassGenerators.hpp @@ -110,7 +110,7 @@ PassPtr gen_clifford_push_through_pass(); * Qubits removed from the Circuit are preserved in the bimap, but not updated * to a new labelling. */ -PassPtr gen_flatten_relabel_registers_pass(const std::string& label); +PassPtr gen_flatten_relabel_registers_pass(const std::string& label, bool relabel_classical_expressions = true); /** * Pass to rename some or all qubits according to the given map. * diff --git a/tket/src/Predicates/CompilerPass.cpp b/tket/src/Predicates/CompilerPass.cpp index 580aa29098..5176f207a6 100644 --- a/tket/src/Predicates/CompilerPass.cpp +++ b/tket/src/Predicates/CompilerPass.cpp @@ -469,7 +469,7 @@ PassPtr deserialise( pp = gen_euler_pass(q, p, s); } else if (passname == "FlattenRelabelRegistersPass") { pp = gen_flatten_relabel_registers_pass( - content.at("label").get()); + content.at("label").get(), content.at("relabel_classical_expressions").get()); } else if (passname == "RoutingPass") { Architecture arc = content.at("architecture").get(); std::vector con = content.at("routing_config"); diff --git a/tket/src/Predicates/PassGenerators.cpp b/tket/src/Predicates/PassGenerators.cpp index d33b83edff..bbf14ab895 100644 --- a/tket/src/Predicates/PassGenerators.cpp +++ b/tket/src/Predicates/PassGenerators.cpp @@ -354,7 +354,7 @@ PassPtr gen_clifford_push_through_pass() { return std::make_shared(precons, t, pc, j); } -PassPtr gen_flatten_relabel_registers_pass(const std::string& label) { +PassPtr gen_flatten_relabel_registers_pass(const std::string& label, bool relabel_classical_expressions) { Transform t = Transform([=](Circuit& circuit, std::shared_ptr maps) { unsigned n_qubits = circuit.n_qubits(); @@ -366,7 +366,7 @@ PassPtr gen_flatten_relabel_registers_pass(const std::string& label) { relabelling_map.insert({all_qubits[i], Qubit(label, i)}); } - circuit.rename_units(relabelling_map); + circuit.rename_units(relabelling_map, relabel_classical_expressions); changed |= update_maps(maps, relabelling_map, relabelling_map); return changed; }); @@ -376,6 +376,7 @@ PassPtr gen_flatten_relabel_registers_pass(const std::string& label) { nlohmann::json j; j["name"] = "FlattenRelabelRegistersPass"; j["label"] = label; + j["relabel_classical_expressions"] = relabel_classical_expressions; return std::make_shared(precons, t, postcons, j); } From 533c90742ee8e430edffdbe5c7734f6a07146006 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:58:11 +0000 Subject: [PATCH 13/19] reformat, add false to rename_units again --- tket/include/tket/Predicates/PassGenerators.hpp | 3 ++- tket/src/Predicates/CompilerPass.cpp | 3 ++- tket/src/Predicates/PassGenerators.cpp | 3 ++- tket/src/Transformations/GreedyPauliOptimisation.cpp | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tket/include/tket/Predicates/PassGenerators.hpp b/tket/include/tket/Predicates/PassGenerators.hpp index f4bcb4a8d4..699f9b9edc 100644 --- a/tket/include/tket/Predicates/PassGenerators.hpp +++ b/tket/include/tket/Predicates/PassGenerators.hpp @@ -110,7 +110,8 @@ PassPtr gen_clifford_push_through_pass(); * Qubits removed from the Circuit are preserved in the bimap, but not updated * to a new labelling. */ -PassPtr gen_flatten_relabel_registers_pass(const std::string& label, bool relabel_classical_expressions = true); +PassPtr gen_flatten_relabel_registers_pass( + const std::string& label, bool relabel_classical_expressions = true); /** * Pass to rename some or all qubits according to the given map. * diff --git a/tket/src/Predicates/CompilerPass.cpp b/tket/src/Predicates/CompilerPass.cpp index 5176f207a6..2caeafe08f 100644 --- a/tket/src/Predicates/CompilerPass.cpp +++ b/tket/src/Predicates/CompilerPass.cpp @@ -469,7 +469,8 @@ PassPtr deserialise( pp = gen_euler_pass(q, p, s); } else if (passname == "FlattenRelabelRegistersPass") { pp = gen_flatten_relabel_registers_pass( - content.at("label").get(), content.at("relabel_classical_expressions").get()); + content.at("label").get(), + content.at("relabel_classical_expressions").get()); } else if (passname == "RoutingPass") { Architecture arc = content.at("architecture").get(); std::vector con = content.at("routing_config"); diff --git a/tket/src/Predicates/PassGenerators.cpp b/tket/src/Predicates/PassGenerators.cpp index bbf14ab895..eb5f50317b 100644 --- a/tket/src/Predicates/PassGenerators.cpp +++ b/tket/src/Predicates/PassGenerators.cpp @@ -354,7 +354,8 @@ PassPtr gen_clifford_push_through_pass() { return std::make_shared(precons, t, pc, j); } -PassPtr gen_flatten_relabel_registers_pass(const std::string& label, bool relabel_classical_expressions) { +PassPtr gen_flatten_relabel_registers_pass( + const std::string& label, bool relabel_classical_expressions) { Transform t = Transform([=](Circuit& circuit, std::shared_ptr maps) { unsigned n_qubits = circuit.n_qubits(); diff --git a/tket/src/Transformations/GreedyPauliOptimisation.cpp b/tket/src/Transformations/GreedyPauliOptimisation.cpp index e0c1890a7a..bf88e4a265 100644 --- a/tket/src/Transformations/GreedyPauliOptimisation.cpp +++ b/tket/src/Transformations/GreedyPauliOptimisation.cpp @@ -770,7 +770,7 @@ Circuit greedy_pauli_graph_synthesis( for (auto it = measures.begin(); it != measures.end(); ++it) { new_circ.add_measure(it->left, it->right); } - new_circ.rename_units(rev_unit_map); + new_circ.rename_units(rev_unit_map, false); new_circ.replace_SWAPs(); return new_circ; } From 747d44b93e91a664e3398d96a47d6fe6b1478963 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:04:23 +0000 Subject: [PATCH 14/19] bump library --- pytket/conanfile.py | 2 +- tket/conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pytket/conanfile.py b/pytket/conanfile.py index e23892a53b..b42d4657d3 100644 --- a/pytket/conanfile.py +++ b/pytket/conanfile.py @@ -38,7 +38,7 @@ def requirements(self): self.requires("pybind11_json/0.2.14") self.requires("symengine/0.12.0") self.requires("tkassert/0.3.4@tket/stable") - self.requires("tket/1.3.40@tket/stable") + self.requires("tket/1.3.41@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") diff --git a/tket/conanfile.py b/tket/conanfile.py index 31633eef95..872160e0a2 100644 --- a/tket/conanfile.py +++ b/tket/conanfile.py @@ -23,7 +23,7 @@ class TketConan(ConanFile): name = "tket" - version = "1.3.40" + version = "1.3.41" package_type = "library" license = "Apache 2" homepage = "https://github.com/CQCL/tket" From 8ad64e8e3445ba1db3c8548d302ffa38bc838e0e Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:15:59 +0000 Subject: [PATCH 15/19] Update passes_serialisation_test.py --- pytket/tests/passes_serialisation_test.py | 30 ++--------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/pytket/tests/passes_serialisation_test.py b/pytket/tests/passes_serialisation_test.py index a1edefa9d7..14e2f42193 100644 --- a/pytket/tests/passes_serialisation_test.py +++ b/pytket/tests/passes_serialisation_test.py @@ -16,41 +16,15 @@ from pathlib import Path from typing import Any, Dict, List -from pytket.circuit import Node, Circuit, Qubit, OpType -from pytket.predicates import Predicate -from pytket.architecture import Architecture -from pytket.placement import Placement, GraphPlacement -import pytket.circuit_library as _library - -from pytket.passes import ( - BasePass, - SequencePass, - RemoveRedundancies, - RepeatUntilSatisfiedPass, - CommuteThroughMultis, - RepeatWithMetricPass, - RebaseCustom, - FullMappingPass, - DefaultMappingPass, - AASRouting, - SquashCustom, - CustomPass, -) import pytest from jsonschema import Draft7Validator, ValidationError # type: ignore from referencing import Registry from referencing.jsonschema import DRAFT7 import pytket.circuit_library as _library +from pytket.architecture import Architecture +from pytket.circuit import Circuit, Node, OpType, Qubit from pytket.circuit.named_types import ParamType - - - - - - - - from pytket.mapping import ( BoxDecompositionRoutingMethod, LexiLabellingMethod, From 2f3446b7a1f633281151ec3cb18256ce6833ab4d Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:16:16 +0000 Subject: [PATCH 16/19] bump library version --- pytket/conanfile.py | 2 +- tket/conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pytket/conanfile.py b/pytket/conanfile.py index 0b13ea52cf..b12e296e0b 100644 --- a/pytket/conanfile.py +++ b/pytket/conanfile.py @@ -38,7 +38,7 @@ def requirements(self): self.requires("pybind11_json/0.2.14") self.requires("symengine/0.12.0") self.requires("tkassert/0.3.4@tket/stable") - self.requires("tket/1.3.41@tket/stable") + self.requires("tket/1.3.42@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") diff --git a/tket/conanfile.py b/tket/conanfile.py index 872160e0a2..a30f2f1de8 100644 --- a/tket/conanfile.py +++ b/tket/conanfile.py @@ -23,7 +23,7 @@ class TketConan(ConanFile): name = "tket" - version = "1.3.41" + version = "1.3.42" package_type = "library" license = "Apache 2" homepage = "https://github.com/CQCL/tket" From 6a288a891629bd5362339f68288e076439f56868 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Mon, 11 Nov 2024 08:05:32 +0000 Subject: [PATCH 17/19] Update test_GreedyPauli.cpp --- tket/test/src/test_GreedyPauli.cpp | 35 +++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/tket/test/src/test_GreedyPauli.cpp b/tket/test/src/test_GreedyPauli.cpp index 73675929d8..629b8d21e3 100644 --- a/tket/test/src/test_GreedyPauli.cpp +++ b/tket/test/src/test_GreedyPauli.cpp @@ -619,10 +619,39 @@ SCENARIO("Complete synthesis") { 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::Z, + Pauli::X}, + 0.125)), + {1, 3, 5, 0, 2, 4}); + + circ.add_box( + PauliExpBox(SymPauliTensor( + {Pauli::X, 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::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::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) - .apply(d)); + REQUIRE(!Transforms::greedy_pauli_optimisation( + 0.7, 0.3, 500, 500, 0, true, timeout = 0) + .apply(d)); REQUIRE( Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 10) .apply(d)); From 5071d1ee4cafd78de7d66c1f86b8ee4adc7667b2 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Mon, 11 Nov 2024 08:24:05 +0000 Subject: [PATCH 18/19] Update test_GreedyPauli.cpp --- tket/test/src/test_GreedyPauli.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tket/test/src/test_GreedyPauli.cpp b/tket/test/src/test_GreedyPauli.cpp index 629b8d21e3..ec436dc50e 100644 --- a/tket/test/src/test_GreedyPauli.cpp +++ b/tket/test/src/test_GreedyPauli.cpp @@ -649,9 +649,9 @@ SCENARIO("Complete synthesis") { {0, 5, 1, 4, 3, 2}); Circuit d(circ); - REQUIRE(!Transforms::greedy_pauli_optimisation( - 0.7, 0.3, 500, 500, 0, true, timeout = 0) - .apply(d)); + REQUIRE( + !Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 0) + .apply(d)); REQUIRE( Transforms::greedy_pauli_optimisation(0.7, 0.3, 500, 500, 0, true, 10) .apply(d)); From 6596f5d984a8999d8985e2904e289667e2e390c6 Mon Sep 17 00:00:00 2001 From: Silas Dilkes <36165522+sjdilkes@users.noreply.github.com> Date: Mon, 11 Nov 2024 08:33:08 +0000 Subject: [PATCH 19/19] Update test_GreedyPauli.cpp --- tket/test/src/test_GreedyPauli.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tket/test/src/test_GreedyPauli.cpp b/tket/test/src/test_GreedyPauli.cpp index ec436dc50e..6d62f74bd5 100644 --- a/tket/test/src/test_GreedyPauli.cpp +++ b/tket/test/src/test_GreedyPauli.cpp @@ -622,29 +622,25 @@ SCENARIO("Complete synthesis") { circ.add_box( PauliExpBox(SymPauliTensor( - {Pauli::X, Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::Z, - Pauli::X}, + {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::Y, Pauli::Z, Pauli::Z, - Pauli::X}, + {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::Z, - Pauli::X}, + {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::Z, - Pauli::X}, + {Pauli::X, Pauli::Z, Pauli::Y, Pauli::Y, Pauli::Z, Pauli::X}, 0.125)), {0, 5, 1, 4, 3, 2});