Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
212533c
isCliffordCheck
jannikpflieger Mar 11, 2025
3f64b2f
added isCliffordOperation
jannikpflieger Mar 19, 2025
5db7ac5
edited collectBlocks to handle CliffordBlocks
jannikpflieger Mar 20, 2025
4995e47
Added Tests and redefined if statements in opertaon
jannikpflieger Mar 21, 2025
62004e5
fixed Testcases
jannikpflieger Mar 21, 2025
1656046
Update ci.yml
jannikpflieger Mar 21, 2025
8c811bd
Update ci.yaml again
jannikpflieger Mar 21, 2025
5812c72
Merge branch 'cda-tum:main' into collectCliffordBlocks
jannikpflieger Mar 21, 2025
d9d2132
🎨 pre-commit fixes
pre-commit-ci[bot] Mar 24, 2025
3282c67
more Test Coverage and fix linting errors
jannikpflieger Mar 24, 2025
43d18ae
Merge branch 'cda-tum:main' into collectCliffordBlocks
jannikpflieger Mar 24, 2025
088ada5
removed outcommented code
jannikpflieger Mar 24, 2025
486e225
Added import and fixed variable const
jannikpflieger Mar 24, 2025
66ed0fc
Merge branch 'munich-quantum-toolkit:main' into collectCliffordBlocks
jannikpflieger Apr 29, 2025
e1ffb25
changed parameter name and added docstring
jannikpflieger Apr 29, 2025
0ae9525
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Apr 29, 2025
d7264a0
🎨 pre-commit fixes
pre-commit-ci[bot] Apr 29, 2025
a12f11a
reverted original tests back to normal, changed function header of co…
jannikpflieger Apr 29, 2025
7eb95fc
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Apr 29, 2025
5555b8e
🎨 pre-commit fixes
pre-commit-ci[bot] Apr 29, 2025
e5de02d
Moved IsCliffordfunction to StandardOperation and CompoundOperation
jannikpflieger Apr 29, 2025
6e728cb
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Apr 29, 2025
71e8bc6
🎨 pre-commit fixes
pre-commit-ci[bot] Apr 29, 2025
f771766
Corrected Test for isClifford operations
jannikpflieger Apr 30, 2025
d97eef5
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Apr 30, 2025
227d2ec
🎨 pre-commit fixes
pre-commit-ci[bot] Apr 30, 2025
5ce85b4
Removed usless test added more meanigful ones
jannikpflieger May 1, 2025
326c5b9
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger May 1, 2025
ace9eaf
🎨 pre-commit fixes
pre-commit-ci[bot] May 1, 2025
6ff54c3
changed tests a little, some were not correct
jannikpflieger May 12, 2025
479d3ba
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger May 12, 2025
e0a4e50
fixed probelsm in collect Blocks
jannikpflieger Jun 6, 2025
a475fab
Merge branch 'munich-quantum-toolkit:main' into collectCliffordBlocks
jannikpflieger Jun 6, 2025
337b2ef
added test for coverage
jannikpflieger Jun 9, 2025
16ff394
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Jun 9, 2025
5ad710c
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jun 9, 2025
c226bf1
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jun 9, 2025
b16ac7b
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 9, 2025
e723671
🩹 fix `isClifford` check
burgholzer Jun 10, 2025
de14645
✅ fix and adjust `isClifford` tests
burgholzer Jun 10, 2025
0f4e9fa
Merge branch 'main' into fork/jannikpflieger/collectCliffordBlocks
burgholzer Jun 10, 2025
3d16b8c
✏️ refine docstring
burgholzer Jun 10, 2025
32b333a
reverted changes
jannikpflieger Jun 17, 2025
fcdf42e
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jun 17, 2025
d3d6c51
added additonal test, used different approach for collectin Blocks
jannikpflieger Jun 19, 2025
801a423
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 19, 2025
54e5b4b
Better tests
jannikpflieger Jun 22, 2025
3fd00a8
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jun 22, 2025
d715a9c
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 22, 2025
eb463ac
slight test changes
jannikpflieger Jun 23, 2025
ff847a1
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jun 23, 2025
15ae2b5
chaning loop behaviour
jannikpflieger Jun 30, 2025
5c7f8bc
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 30, 2025
82580c1
updated test_suite
jannikpflieger Jul 17, 2025
37f76b5
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 17, 2025
aa3f9dc
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 17, 2025
d73ac1e
added entirely new function header
jannikpflieger Jul 18, 2025
7852dc7
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 18, 2025
987e881
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 18, 2025
2ff98d1
CollectCliffordBlocks Method
jannikpflieger Jul 19, 2025
7c43134
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 19, 2025
cd3e7d8
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 19, 2025
2cab14a
new test_file, added max Size
jannikpflieger Jul 19, 2025
860b119
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 19, 2025
3e6900b
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 19, 2025
1636c5b
fixed code merge was bad
jannikpflieger Jul 19, 2025
4c4b4f5
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 19, 2025
4e4934a
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 19, 2025
d5acfc3
comment update
jannikpflieger Jul 19, 2025
a5d7517
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 19, 2025
75c87aa
fixed linting
jannikpflieger Jul 20, 2025
f9925cd
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 20, 2025
034870f
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Jul 20, 2025
17b98ac
Changed Function behaviour to make it right
jannikpflieger Jul 21, 2025
02968be
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 21, 2025
2d77ab3
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Jul 21, 2025
d281f9f
code refactor
jannikpflieger Jul 21, 2025
a6a9cf9
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 21, 2025
b1b2d3f
fixed linting issues
jannikpflieger Jul 21, 2025
e53967d
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 21, 2025
b0d3f64
added Clarifiny Comments, and updated some DataTypes to make it more …
jannikpflieger Jul 21, 2025
52ee8c9
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 21, 2025
ac5fd50
fixed typo
jannikpflieger Jul 21, 2025
3a08cea
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 21, 2025
d077ffa
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 21, 2025
af95cd3
added function comment
jannikpflieger Jul 22, 2025
35147d2
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 22, 2025
d6e7b6c
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 22, 2025
e90e8c1
reverted unrelated changes in CircuitOptimizer.cpp
jannikpflieger Jul 29, 2025
291bef7
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Jul 29, 2025
c50b422
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Jul 29, 2025
c832470
updated to c++20
jannikpflieger Jul 29, 2025
85ccabd
test refactor, added new tests, removed useless tests
jannikpflieger Jul 29, 2025
fdd94c1
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Aug 16, 2025
679b36e
Updated expected circuit outcome in tests
jannikpflieger Aug 16, 2025
4374264
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 16, 2025
269e617
fixed issues in tests
jannikpflieger Aug 20, 2025
d6898b4
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 20, 2025
67db0cc
restructred tests, implemented funtionality to actually form the clif…
jannikpflieger Aug 23, 2025
d7afa26
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 23, 2025
9a8bee9
minor readability changes
jannikpflieger Aug 23, 2025
5fe6190
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 23, 2025
a7048a3
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 23, 2025
1bd5f99
fixed linting and coverage errors
jannikpflieger Aug 23, 2025
f2939cf
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 23, 2025
a3b9302
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 23, 2025
cd5f3a1
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Aug 23, 2025
2878a83
fixed another liniting error
jannikpflieger Aug 23, 2025
b10dccb
fixed signing a signed number to an unsigned type
jannikpflieger Aug 23, 2025
6bb99e2
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 23, 2025
0cb68a5
comment update
jannikpflieger Aug 24, 2025
97ac02d
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 24, 2025
8a68a30
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 24, 2025
0f54680
made tests more minimal
jannikpflieger Aug 24, 2025
67c4b15
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 24, 2025
1152fdb
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 24, 2025
17d553e
removed codelines to keep it clean
jannikpflieger Aug 24, 2025
74c761a
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 24, 2025
a4392e3
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 24, 2025
70e6c71
fixed issue where barrier was consider Clifford, made test more minimal
jannikpflieger Aug 24, 2025
7d0b9eb
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 24, 2025
3ba1260
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Aug 25, 2025
321cc6e
added Test for CompundOperations
jannikpflieger Aug 25, 2025
b4bcad3
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 25, 2025
d08a8a1
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 25, 2025
fbade59
Refactored Tests, cleaned up code, better variable and function names
jannikpflieger Aug 26, 2025
a209ad6
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 26, 2025
6623bf8
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 26, 2025
6e082e7
Merge branch 'main' into collectCliffordBlocks
jannikpflieger Aug 26, 2025
6c2b429
Imporved Readability
jannikpflieger Aug 26, 2025
52a3e53
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 26, 2025
830c1fa
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 26, 2025
bc820b9
removed trainling whitespaces
jannikpflieger Aug 26, 2025
9dbcf41
Merge branch 'collectCliffordBlocks' of github.com:jannikpflieger/mqt…
jannikpflieger Aug 26, 2025
b6d1f7b
Merge branch 'refs/heads/main' into fork/jannikpflieger/collectCliffo…
burgholzer Aug 27, 2025
cb55a47
🎨 slightly simplify `isClifford` check
burgholzer Aug 27, 2025
1c51557
🎨 code style in tests
burgholzer Aug 27, 2025
d14add7
📝 add changelog entry
burgholzer Aug 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel

### Added

- ✨ Add Clifford block collection pass to `CircuitOptimizer` module ([#885]) ([**jannikpflieger**], [**@burgholzer**])
- ✨ Add `isControlled()` method to the `UnitaryInterface` MLIR class ([#1157]) ([**@taminob**], [**@burgholzer**])
- 📝 Integrate generated MLIR documentation ([#1147]) ([**@denialhaag**], [**@burgholzer**])
- ✨ Add `IfElseOperation` to C++ library and Python package to support Qiskit's `IfElseOp` ([#1117]) ([**@denialhaag**], [**@burgholzer**], [**@lavanya-m-k**])
Expand Down Expand Up @@ -221,6 +222,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
[#893]: https://github.com/munich-quantum-toolkit/core/pull/893
[#892]: https://github.com/munich-quantum-toolkit/core/pull/892
[#886]: https://github.com/munich-quantum-toolkit/core/pull/886
[#885]: https://github.com/munich-quantum-toolkit/core/pull/885
[#883]: https://github.com/munich-quantum-toolkit/core/pull/883
[#882]: https://github.com/munich-quantum-toolkit/core/pull/882
[#879]: https://github.com/munich-quantum-toolkit/core/pull/879
Expand Down Expand Up @@ -270,6 +272,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
[**@li-mingbao**]: https://github.com/li-mingbao
[**@lavanya-m-k**]: https://github.com/lavanya-m-k
[**@taminob**]: https://github.com/taminob
[**@jannikpflieger**]: https://github.com/jannikpflieger

<!-- General links -->

Expand Down
13 changes: 13 additions & 0 deletions include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ class CircuitOptimizer {
*/
static void collectBlocks(QuantumComputation& qc, std::size_t maxBlockSize);

/**
* @brief Collects all Clifford blocks in the circuit.
* @details The circuit is traversed and all operations that are part of a
* Clifford block are collected into a compound operation with a certain
* maximum block size. All non-Clifford operations remain untouched.
* Light optimizations are applied to the blocks, such as removing identity
* gates.
* @param qc the quantum circuit
* @param maxBlockSize the maximum size of a block
*/
static void collectCliffordBlocks(QuantumComputation& qc,
std::size_t maxBlockSize);

/**
* @brief Elide permutations by propagating them through the circuit.
* @details The circuit is traversed and any SWAP gate is eliminated by
Expand Down
2 changes: 2 additions & 0 deletions include/mqt-core/ir/operations/CompoundOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class CompoundOperation final : public Operation {

[[nodiscard]] bool isGlobal(size_t nQubits) const noexcept override;

[[nodiscard]] bool isClifford() const override;

void addControl(Control c) override;

void clearControls() override;
Expand Down
3 changes: 3 additions & 0 deletions include/mqt-core/ir/operations/OpType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ std::string shortName(OpType opType);
}
}

/**
* @brief Checks if given OpType is a single qubit gate
*/
[[nodiscard]] constexpr bool isSingleQubitGate(const OpType type) {
switch (type) {
case I:
Expand Down
2 changes: 2 additions & 0 deletions include/mqt-core/ir/operations/Operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ class Operation {

[[nodiscard]] virtual bool isControlled() const { return !controls.empty(); }

[[nodiscard]] virtual bool isClifford() const { return false; }

/**
* @brief Checks whether a gate is global.
* @details A StandardOperation is global if it acts on all qubits.
Expand Down
2 changes: 2 additions & 0 deletions include/mqt-core/ir/operations/StandardOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class StandardOperation : public Operation {

[[nodiscard]] bool isGlobal(size_t nQubits) const override;

[[nodiscard]] bool isClifford() const override;

void addControl(const Control c) override {
if (actsOn(c.qubit)) {
throw std::runtime_error("Cannot add control on qubit " +
Expand Down
235 changes: 235 additions & 0 deletions src/circuit_optimizer/CircuitOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,241 @@ void CircuitOptimizer::collectBlocks(QuantumComputation& qc,
removeIdentities(qc);
}

/**
* @brief Block of Clifford operations
* @details This structure is used to collect Clifford operations that can be
* grouped together. It maintains the qubits that are part of the block
* and the qubits that are blocked by non-Clifford operations.
*/
struct CliffordBlock {
std::unordered_set<Qubit> blockQubits;
std::unordered_set<Qubit> blocked;
std::unique_ptr<CompoundOperation> operations;
std::unique_ptr<Operation>* position = nullptr;
std::size_t logicalStep = 0;

[[nodiscard]] bool empty() const noexcept {
return !operations || operations->empty();
}

/**
* @brief Check if this block is fully disabled by non-Clifford operations
*
*/
[[nodiscard]] bool fullyDisabled() const noexcept {
return std::ranges::all_of(
blockQubits, [this](const Qubit q) { return blocked.contains(q); });
}

/**
* @brief Check if adding qubits used by gate would exceed maxBlockSize
* @param used Qubits used by the gate
* @param maxBlockSize Maximum allowed block size
*/
[[nodiscard]] bool
checkExceedsMaxBlockSize(const std::set<Qubit>& used,
const std::size_t maxBlockSize) const noexcept {
std::size_t extra = 0;
for (const auto q : used) {
if (!blockQubits.contains(q)) {
++extra;
if (blockQubits.size() + extra > maxBlockSize) {
return false;
}
}
}
return true;
}

/**
* @brief Check if qubits used by gate are blocked in this block
* @param used Qubits used by the gate
*/
[[nodiscard]] bool checkBlocked(const std::set<Qubit>& used) const noexcept {
return std::ranges::all_of(
used, [this](const Qubit q) { return !blocked.contains(q); });
}

/**
* @brief Check if repostion is needed to keep block valid
* @param used Qubits used by the gate
* @param lastNonClifford Map of qubits to last non-Clifford operation
*/
[[nodiscard]] bool
checkRepositionNeeded(const std::set<Qubit>& used,
const std::unordered_map<Qubit, std::size_t>&
lastNonClifford) const noexcept {
std::size_t required = 0;
for (const auto q : used) {
if (const auto it = lastNonClifford.find(q);
it != lastNonClifford.end()) {
required = std::max(required, it->second);
}
}
return required > logicalStep;
}

/**
* @brief Append operation into block
* @details Append operation into block. If movePosition is true, re-position
* here otherwise we erase the current slot.
* @param op Operation to add
* @param used Qubits used by the gate
* @param qc Quantum computation
* @param it Current iterator in quantum computation
* @param movePosition Whether to move the position of the block
* @param step Current logical step in the quantum computation
*/
void addOp(std::unique_ptr<Operation>& op, const std::set<Qubit>& used,
QuantumComputation& qc, QuantumComputation::iterator& it,
const bool movePosition, const std::size_t step) {
operations->emplace_back(std::move(op));

if (movePosition) {
// we move block into the right position with identities because they are
// removed later
*position = std::make_unique<StandardOperation>(0, I);
position = &(*it);
logicalStep = step;
} else {
// operations is moved into compound operation so we can delete it
it = qc.erase(it);
--it;
}

for (const auto q : used) {
blockQubits.insert(q);
}
}

/**
* @brief Collapse operation and reset block
*/
void finalize() {
if (position == nullptr || empty()) {
return;
}
if (operations->isConvertibleToSingleOperation()) {
*position = operations->collapseToSingleOperation();
} else {
*position = std::move(operations);
}
// reset
operations = std::make_unique<CompoundOperation>();
blockQubits.clear();
blocked.clear();
position = nullptr;
logicalStep = 0;
}
};

void CircuitOptimizer::collectCliffordBlocks(QuantumComputation& qc,
const std::size_t maxBlockSize) {
if (qc.size() <= 1) {
return;
}

qc.reorderOperations();
deferMeasurements(qc);

std::vector<CliffordBlock> blocks;
std::unordered_map<Qubit, std::size_t> lastNonClifford;
std::size_t step = 0;

for (auto it = qc.begin(); it != qc.end(); ++it, ++step) {
auto& op = *it;
const bool isClif = op->isClifford();
const std::set<Qubit> used = op->getUsedQubits();

if (!isClif) {
// track nonClifford and block qubits for any block
for (const auto q : used) {
lastNonClifford[q] = step;
}
for (auto& block : blocks) {
bool touched = false;
for (const auto q : used) {
if (block.blockQubits.contains(q)) {
block.blocked.insert(q);
touched = true;
}
}
if (touched && block.fullyDisabled()) {
block.finalize();
}
}
// keep this non-Clifford gate in place
continue;
}

// Gate itself is too big
if (used.size() > maxBlockSize) {
continue;
}

// Try to place into newest block
auto chosen = static_cast<std::size_t>(0);
bool movePosition = false;
bool found = false;
for (std::size_t i = blocks.size(); i-- > static_cast<std::size_t>(0);) {
auto& block = blocks[i];
if (block.position == nullptr) {
continue;
}
if (!block.checkBlocked(used)) {
continue;
}
if (!block.checkExceedsMaxBlockSize(used, maxBlockSize)) {
continue;
}

chosen = i;
movePosition = block.checkRepositionNeeded(used, lastNonClifford);
found = true;
break;
}

if (found) {
// Disable these qubits in all older blocks
for (std::size_t t = 0; t < chosen; ++t) {
auto& block = blocks[t];
if (block.position == nullptr) {
continue;
}
bool touches = false;
for (const auto q : used) {
if (block.blockQubits.contains(q)) {
block.blocked.insert(q);
touches = true;
}
}
if (touches && block.fullyDisabled()) {
block.finalize();
}
}

blocks[chosen].addOp(op, used, qc, it, movePosition, step);
continue;
}

// Otherwise open a new block at this slot
CliffordBlock block{};
block.operations = std::make_unique<CompoundOperation>();
block.position = &(*it);
block.logicalStep = step;
block.operations->emplace_back(std::move(op));
for (const auto q : used) {
block.blockQubits.insert(q);
}
blocks.emplace_back(std::move(block));
}

for (auto& block : blocks) {
block.finalize();
}
removeIdentities(qc);
}

namespace {
void elidePermutations(Iterator begin, const std::function<Iterator()>& end,
const std::function<Iterator(Iterator)>& erase,
Expand Down
5 changes: 5 additions & 0 deletions src/ir/operations/CompoundOperation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ bool CompoundOperation::isGlobal(const size_t nQubits) const noexcept {
});
}

bool CompoundOperation::isClifford() const {
return std::ranges::all_of(ops,
[](const auto& op) { return op->isClifford(); });
}

bool CompoundOperation::isSymbolicOperation() const {
return std::ranges::any_of(
ops, [](const auto& op) { return op->isSymbolicOperation(); });
Expand Down
23 changes: 23 additions & 0 deletions src/ir/operations/StandardOperation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,29 @@ bool StandardOperation::isGlobal(const size_t nQubits) const {
/***
* Public Methods
***/
bool StandardOperation::isClifford() const {
switch (type) {
case I:
return true;
case X:
case Y:
case Z:
return (controls.size() <= 1);
case H:
case S:
case Sdg:
case SX:
case SXdg:
case DCX:
case SWAP:
case iSWAP:
case ECR:
return !isControlled();
default:
return false;
}
}

void StandardOperation::dumpOpenQASM(
std::ostream& of, const QubitIndexToRegisterMap& qubitMap,
[[maybe_unused]] const BitIndexToRegisterMap& bitMap, size_t indent,
Expand Down
Loading
Loading