diff --git a/include/mqt-core/datastructures/Layer.hpp b/include/mqt-core/datastructures/Layer.hpp index cfe8be2ad..c6f85d1d9 100644 --- a/include/mqt-core/datastructures/Layer.hpp +++ b/include/mqt-core/datastructures/Layer.hpp @@ -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,7 +134,21 @@ class Layer final { Layer& operator=(const Layer&) = default; Layer& operator=(Layer&&) = default; ~Layer() = default; - explicit Layer(const QuantumComputation& qc) { constructDAG(qc); } + /** + * @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); + } [[nodiscard]] auto getExecutableSet() const -> const ExecutableSet& { return executableSet; } diff --git a/src/datastructures/Layer.cpp b/src/datastructures/Layer.cpp index 46e97959c..bd84c61e8 100644 --- a/src/datastructures/Layer.cpp +++ b/src/datastructures/Layer.cpp @@ -13,7 +13,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 @@ -104,7 +105,8 @@ auto Layer::constructDAG(const QuantumComputation& qc) -> void { // that would not commute because redundant operations in a group // cause problems later on, e.g., when generating interaction graphs if (!currentGroup[qubit].empty() && - (!(currentGroup[qubit][0]->getOperation()) + (!commutable || + !(currentGroup[qubit][0]->getOperation()) ->commutesAtQubit(*current->getOperation(), qubit) || std::find_if( currentGroup[qubit].cbegin(), currentGroup[qubit].cend(), @@ -145,8 +147,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 diff --git a/test/datastructures/test_layer.cpp b/test/datastructures/test_layer.cpp index c9b0d85ce..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 { @@ -86,6 +87,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);