From 1b00b21fee0a55fb415d4310715e80b4d3d71949 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Thu, 25 Jul 2024 08:38:46 +0200 Subject: [PATCH 1/5] Add non commutable option to Layer --- include/mqt-core/datastructures/Layer.hpp | 23 +++++++++++++---------- src/datastructures/Layer.cpp | 12 +++++++----- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/include/mqt-core/datastructures/Layer.hpp b/include/mqt-core/datastructures/Layer.hpp index cfe8be2ad..3bf46306c 100644 --- a/include/mqt-core/datastructures/Layer.hpp +++ b/include/mqt-core/datastructures/Layer.hpp @@ -52,9 +52,9 @@ class Layer final { : operation(op), executableSet(&es) {} public: - [[nodiscard]] static auto - create(Operation* operation, - ExecutableSet& executableSet) -> std::shared_ptr { + [[nodiscard]] static auto create(Operation* operation, + ExecutableSet& executableSet) + -> std::shared_ptr { std::shared_ptr v(new DAGVertex(operation, executableSet)); v->updateExecutableSet(); return v; @@ -125,7 +125,7 @@ class Layer final { protected: ExecutableSet executableSet; - auto constructDAG(const QuantumComputation& qc) -> void; + auto constructDAG(const QuantumComputation& qc, bool commutable) -> void; public: Layer() = default; @@ -134,14 +134,17 @@ class Layer final { Layer& operator=(const Layer&) = default; Layer& operator=(Layer&&) = default; ~Layer() = default; - explicit Layer(const QuantumComputation& qc) { constructDAG(qc); } + explicit Layer(const QuantumComputation& qc, bool commutable = true) { + constructDAG(qc, commutable); + } [[nodiscard]] auto getExecutableSet() const -> const ExecutableSet& { return executableSet; } - [[nodiscard]] auto - constructInteractionGraph(OpType opType, - std::size_t nControls) const -> InteractionGraph; - [[nodiscard]] auto getExecutablesOfType(OpType opType, std::size_t nControls) - const -> std::vector>; + [[nodiscard]] auto constructInteractionGraph(OpType opType, + std::size_t nControls) const + -> InteractionGraph; + [[nodiscard]] auto getExecutablesOfType(OpType opType, + std::size_t nControls) const + -> std::vector>; }; } // namespace qc diff --git a/src/datastructures/Layer.cpp b/src/datastructures/Layer.cpp index 6593c868d..a98547d49 100644 --- a/src/datastructures/Layer.cpp +++ b/src/datastructures/Layer.cpp @@ -12,7 +12,8 @@ namespace qc { -auto Layer::constructDAG(const QuantumComputation& qc) -> void { +auto Layer::constructDAG(const QuantumComputation& qc, const bool commutable) + -> void { const auto nQubits = qc.getNqubits(); // For a pair of self-canceling operations like two consecutive X operations // or RY rotations with opposite angles the first operations is a @@ -97,8 +98,9 @@ auto Layer::constructDAG(const QuantumComputation& qc) -> void { // check whether the current operation commutes with the current // group members if (!currentGroup[qubit].empty() and - !(currentGroup[qubit][0]->getOperation()) - ->commutesAtQubit(*current->getOperation(), qubit)) { + (!commutable or + !(currentGroup[qubit][0]->getOperation()) + ->commutesAtQubit(*current->getOperation(), qubit))) { // here: the current operation does not commute with the current // group members and is not the inverse of the lookahead // --> start a new group @@ -133,8 +135,8 @@ auto Layer::constructDAG(const QuantumComputation& qc) -> void { // check whether the current operation commutes with the current // group members if (!currentGroup[qubit].empty() and - !(currentGroup[qubit][0]->getOperation()) - ->commutesAtQubit(*current->getOperation(), qubit)) { + (!commutable or !(currentGroup[qubit][0]->getOperation()) + ->commutesAtQubit(*current->getOperation(), qubit))) { // here: the current operation does not commute with the current // group members and is not the inverse of the lookahead // --> start a new group From 7fcd6a9dc252cff0ea943feb56cfb4d6937267bf Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:39:29 +0200 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9D=20Add=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/mqt-core/datastructures/Layer.hpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/include/mqt-core/datastructures/Layer.hpp b/include/mqt-core/datastructures/Layer.hpp index 3bf46306c..9e3191c97 100644 --- a/include/mqt-core/datastructures/Layer.hpp +++ b/include/mqt-core/datastructures/Layer.hpp @@ -84,12 +84,12 @@ class Layer final { auto updateExecutableSet() -> void { if (isExecutable()) { if (const auto& it = executableSet->find(shared_from_this()); - it == executableSet->end()) { + it == executableSet->end()) { executableSet->insert(shared_from_this()); } } else { if (const auto& it = executableSet->find(shared_from_this()); - it != executableSet->end()) { + it != executableSet->end()) { executableSet->erase(it); } } @@ -134,6 +134,18 @@ class Layer final { Layer& operator=(const Layer&) = default; Layer& operator=(Layer&&) = default; ~Layer() = default; + /** + * @brief Constructs a new layer from the given quantum circuit. + * @details The layer contains all gates that are currently executable in a + * set of executable gates. When a gate is executed, this can enable other + * gates that are added to the set of executable sets then, or disable gates + * that are removed from the set of executable gates. The commutable flag can + * be used to specify whether commutation rules should be considered. + * + * @param qc quantum circuit + * @param commutable true if commutation rules should be considered, false + * otherwise (default: true) + */ explicit Layer(const QuantumComputation& qc, bool commutable = true) { constructDAG(qc, commutable); } @@ -147,4 +159,4 @@ class Layer final { std::size_t nControls) const -> std::vector>; }; -} // namespace qc +} // namespace qc \ No newline at end of file From dcd8ac50b00d9ffef9de37d22775b12548a01871 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:57:19 +0200 Subject: [PATCH 3/5] =?UTF-8?q?=E2=9C=85=20Add=20test=20for=20new=20param?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/datastructures/test_layer.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/datastructures/test_layer.cpp b/test/datastructures/test_layer.cpp index c9b0d85ce..12b5d529e 100644 --- a/test/datastructures/test_layer.cpp +++ b/test/datastructures/test_layer.cpp @@ -86,6 +86,31 @@ TEST(Layer, ExecutableSet2) { EXPECT_EQ(layer.getExecutableSet().size(), 10); } +TEST(Layer, ExecutableSetNotCommutable) { + QuantumComputation qc{}; + qc = QuantumComputation(8); + qc.cz(1, 7); + qc.cz(2, 4); + qc.cz(5, 6); + qc.cz(1, 5); + qc.cz(6, 7); + qc.cz(2, 3); + qc.cz(1, 3); + qc.cz(4, 6); + qc.cz(2, 5); + const Layer layer(qc, false); + EXPECT_EQ(layer.getExecutableSet().size(), 3); + std::unordered_set actualSet{}; + for (const auto& u : layer.getExecutableSet()) { + actualSet.emplace(u->getOperation()); + } + std::unordered_set expectedSet{}; + expectedSet.emplace(qc.at(0).get()); + expectedSet.emplace(qc.at(1).get()); + expectedSet.emplace(qc.at(2).get()); + EXPECT_EQ(actualSet, expectedSet); +} + TEST(Layer, InteractionGraph) { QuantumComputation qc{}; qc = QuantumComputation(8); From 8e38ae546004e43e84cda510ac165ab1762da6fb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 18:30:59 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/mqt-core/datastructures/Layer.hpp | 23 +++++++++++------------ src/datastructures/Layer.cpp | 12 +++++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/mqt-core/datastructures/Layer.hpp b/include/mqt-core/datastructures/Layer.hpp index 9e3191c97..c6f85d1d9 100644 --- a/include/mqt-core/datastructures/Layer.hpp +++ b/include/mqt-core/datastructures/Layer.hpp @@ -52,9 +52,9 @@ class Layer final { : operation(op), executableSet(&es) {} public: - [[nodiscard]] static auto create(Operation* operation, - ExecutableSet& executableSet) - -> std::shared_ptr { + [[nodiscard]] static auto + create(Operation* operation, + ExecutableSet& executableSet) -> std::shared_ptr { std::shared_ptr v(new DAGVertex(operation, executableSet)); v->updateExecutableSet(); return v; @@ -84,12 +84,12 @@ class Layer final { auto updateExecutableSet() -> void { if (isExecutable()) { if (const auto& it = executableSet->find(shared_from_this()); - it == executableSet->end()) { + it == executableSet->end()) { executableSet->insert(shared_from_this()); } } else { if (const auto& it = executableSet->find(shared_from_this()); - it != executableSet->end()) { + it != executableSet->end()) { executableSet->erase(it); } } @@ -152,11 +152,10 @@ class Layer final { [[nodiscard]] auto getExecutableSet() const -> const ExecutableSet& { return executableSet; } - [[nodiscard]] auto constructInteractionGraph(OpType opType, - std::size_t nControls) const - -> InteractionGraph; - [[nodiscard]] auto getExecutablesOfType(OpType opType, - std::size_t nControls) const - -> std::vector>; + [[nodiscard]] auto + constructInteractionGraph(OpType opType, + std::size_t nControls) const -> InteractionGraph; + [[nodiscard]] auto getExecutablesOfType(OpType opType, std::size_t nControls) + const -> std::vector>; }; -} // namespace qc \ No newline at end of file +} // namespace qc diff --git a/src/datastructures/Layer.cpp b/src/datastructures/Layer.cpp index 9585e628d..bd84c61e8 100644 --- a/src/datastructures/Layer.cpp +++ b/src/datastructures/Layer.cpp @@ -13,8 +13,8 @@ namespace qc { -auto Layer::constructDAG(const QuantumComputation& qc, const bool commutable) - -> void { +auto Layer::constructDAG(const QuantumComputation& qc, + const bool commutable) -> void { const auto nQubits = qc.getNqubits(); // For a pair of self-canceling operations like two consecutive X operations // or RY rotations with opposite angles the first operations is a @@ -105,7 +105,8 @@ auto Layer::constructDAG(const QuantumComputation& qc, const bool commutable) // that would not commute because redundant operations in a group // cause problems later on, e.g., when generating interaction graphs if (!currentGroup[qubit].empty() && - (!commutable || !(currentGroup[qubit][0]->getOperation()) + (!commutable || + !(currentGroup[qubit][0]->getOperation()) ->commutesAtQubit(*current->getOperation(), qubit) || std::find_if( currentGroup[qubit].cbegin(), currentGroup[qubit].cend(), @@ -146,8 +147,9 @@ auto Layer::constructDAG(const QuantumComputation& qc, const bool commutable) // check whether the current operation commutes with the current // group members if (!currentGroup[qubit].empty() and - (!commutable or !(currentGroup[qubit][0]->getOperation()) - ->commutesAtQubit(*current->getOperation(), qubit))) { + (!commutable or + !(currentGroup[qubit][0]->getOperation()) + ->commutesAtQubit(*current->getOperation(), qubit))) { // here: the current operation does not commute with the current // group members and is not the inverse of the lookahead // --> start a new group From 85c69a079cee7448425efde872418ad05ff765f1 Mon Sep 17 00:00:00 2001 From: Yannick Stade <100073938+ystade@users.noreply.github.com> Date: Tue, 6 Aug 2024 09:08:04 +0200 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=8E=A8=20Add=20missing=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/datastructures/test_layer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/datastructures/test_layer.cpp b/test/datastructures/test_layer.cpp index 12b5d529e..4fcaabbfd 100644 --- a/test/datastructures/test_layer.cpp +++ b/test/datastructures/test_layer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace qc {