-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add transpiler pass for complementary control pattern simplification using Boolean algebra #15352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Mostafa-Atallah2020
wants to merge
27
commits into
Qiskit:main
Choose a base branch
from
Mostafa-Atallah2020:feature/control-pattern-optimization
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,635
−0
Open
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
268234a
Add ControlPatternSimplification transpiler pass skeleton
81fa801
Implements foundational components for the ControlPatternSimplification
853bb6e
Implements gate detection and grouping logic for ControlPatternSimpli…
e46318e
Implement the boolean logic
196907a
Add test file
040f986
Added case that merge while the parameters are different
41977e3
Add test for identical control patterns with different parameters
d35c894
Remove sympy dependency
cdd746c
Add more tests
d99d3ff
Implementing xor pairs trick
6bb3f36
Remove invalid test logic
a8acafa
Pass advanced tests
40d1da8
Add releasenotes
7d23f36
Remove sympy dependency
61eac4b
Reformating with black
2b3d095
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 98b20ef
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 a30dc12
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 9ab1389
Add alexander unittest
31d3120
Remove redundant code lines
793d2b2
Add support for unconditional simplified gates
5133d8e
Add more code reduction opportunities
a64b61b
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 7ac9786
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 6ff6319
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 a3ba655
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 d855fb1
Merge branch 'main' into feature/control-pattern-optimization
Mostafa-Atallah2020 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
126 changes: 126 additions & 0 deletions
126
qiskit/transpiler/passes/optimization/control_pattern_simplification.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| # This code is part of Qiskit. | ||
| # | ||
| # (C) Copyright IBM 2017, 2025. | ||
| # | ||
| # This code is licensed under the Apache License, Version 2.0. You may | ||
| # obtain a copy of this license in the LICENSE.txt file in the root directory | ||
| # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
| # | ||
| # Any modifications or derivative works of this code must retain this | ||
| # copyright notice, and modified files need to carry a notice indicating | ||
| # that they have been altered from the originals. | ||
|
|
||
| """Transpiler pass for simplifying multi-controlled gates with complementary control patterns.""" | ||
|
|
||
| from qiskit.transpiler.basepasses import TransformationPass | ||
| from qiskit.dagcircuit import DAGCircuit | ||
| from qiskit.utils import optionals as _optionals | ||
|
|
||
|
|
||
| @_optionals.HAS_SYMPY.require_in_instance | ||
| class ControlPatternSimplification(TransformationPass): | ||
| """Simplify multi-controlled gates using Boolean algebraic pattern matching. | ||
|
|
||
| This pass detects consecutive multi-controlled gates with identical base operations, | ||
| target qubits, and parameters (e.g., rotation angles) but different control patterns. | ||
| It then applies Boolean algebraic simplification to reduce gate counts. | ||
|
|
||
| **Supported Gate Types:** | ||
|
|
||
| The optimization works for any parametric controlled gate where the same parameter | ||
| value is used across multiple gates, including: | ||
|
|
||
| - Multi-controlled rotation gates: MCRX, MCRY, MCRZ | ||
| - Multi-controlled phase gates: MCRZ, MCPhase | ||
| - Any custom controlled gates with identical parameters | ||
|
|
||
| **Optimization Techniques:** | ||
|
|
||
| 1. **Complementary patterns**: Patterns like ['11', '01'] represent | ||
| ``(q0 ∧ q1) ∨ (q0 ∧ ¬q1) = q0``, reducing 2 multi-controlled gates to 1 single-controlled gate. | ||
|
|
||
| 2. **Subset patterns**: Patterns like ['111', '110'] simplify via | ||
| ``(q0 ∧ q1 ∧ q2) ∨ (q0 ∧ q1 ∧ ¬q2) = (q0 ∧ q1)``, | ||
| reducing the number of control qubits. | ||
|
|
||
| 3. **XOR pairs**: Patterns like ['110', '101'] satisfy ``q1 ⊕ q2 = 1`` and can be | ||
| optimized using CNOT gates, reducing 2 multi-controlled gates to 1 multi-controlled gate + 2 CNOTs. | ||
|
|
||
| 4. **Complete partitions**: Patterns like ['00','01','10','11'] → unconditional gates. | ||
|
|
||
| **Example:** | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from qiskit import QuantumCircuit | ||
| from qiskit.circuit.library import RXGate, RYGate, RZGate | ||
| from qiskit.transpiler.passes import ControlPatternSimplification | ||
|
|
||
| # Works with any rotation gate (RX, RY, RZ, etc.) | ||
| theta = np.pi / 4 | ||
|
|
||
| # Example with RX gates | ||
| qc = QuantumCircuit(3) | ||
| qc.append(RXGate(theta).control(2, ctrl_state='11'), [0, 1, 2]) | ||
| qc.append(RXGate(theta).control(2, ctrl_state='01'), [0, 1, 2]) | ||
|
|
||
| # Apply optimization | ||
| pass_ = ControlPatternSimplification() | ||
| optimized_qc = pass_(qc) | ||
|
|
||
| # Result: Single CRX gate controlled by q0 | ||
|
|
||
| # Also works with RY, RZ, Phase, and other parametric gates | ||
| qc2 = QuantumCircuit(3) | ||
| qc2.append(RYGate(theta).control(2, ctrl_state='11'), [0, 1, 2]) | ||
| qc2.append(RYGate(theta).control(2, ctrl_state='01'), [0, 1, 2]) | ||
| optimized_qc2 = pass_(qc2) # Same optimization applied | ||
|
|
||
| **References:** | ||
|
|
||
| - Atallah et al., "Graph Matching Trotterization for Continuous Time Quantum Walk | ||
| Circuit Simulation", Proceedings of IEEE Quantum Computing and Engineering (QCE) 2025. | ||
| - Gonzalez et al., "Efficient sparse state preparation via quantum walks", | ||
| npj Quantum Information (2025). | ||
| - Amy et al., "Fast synthesis of depth-optimal quantum circuits", IEEE TCAD 32.6 (2013). | ||
| - Shende & Markov, "On the CNOT-cost of TOFFOLI gates", arXiv:0803.2316 (2008). | ||
| - Barenco et al., "Elementary gates for quantum computation", Phys. Rev. A 52.5 (1995). | ||
|
|
||
| .. note:: | ||
| This pass requires the optional SymPy library for Boolean expression simplification. | ||
| Install with: ``pip install sympy`` | ||
| """ | ||
|
|
||
| def __init__(self, tolerance=1e-10): | ||
| """Initialize the control pattern simplification pass. | ||
|
|
||
| Args: | ||
| tolerance (float): Numerical tolerance for comparing gate parameters. | ||
| Default is 1e-10. | ||
|
|
||
| Raises: | ||
| MissingOptionalLibraryError: if SymPy is not installed. | ||
| """ | ||
| super().__init__() | ||
| self.tolerance = tolerance | ||
|
|
||
| def run(self, dag: DAGCircuit) -> DAGCircuit: | ||
| """Run the ControlPatternSimplification pass on a DAGCircuit. | ||
|
|
||
| Args: | ||
| dag: The DAG to be optimized. | ||
|
|
||
| Returns: | ||
| DAGCircuit: The optimized DAG with simplified control patterns. | ||
| """ | ||
| # TODO: Implement the optimization logic | ||
| # 1. Identify runs of consecutive multi-controlled gates | ||
| # 2. Group gates with same base operation, target, and parameters | ||
| # (works for any parametric gate: RX, RY, RZ, Phase, etc.) | ||
| # 3. Extract control patterns from ctrl_state | ||
| # 4. Apply Boolean simplification using SymPy | ||
| # 5. Detect XOR patterns for CNOT tricks | ||
| # 6. Generate optimized circuit with reduced gate count | ||
| # 7. Replace original gates with optimized version | ||
|
|
||
| return dag | ||
93 changes: 93 additions & 0 deletions
93
test/python/transpiler/test_control_pattern_simplification.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # This code is part of Qiskit. | ||
| # | ||
| # (C) Copyright IBM 2017, 2025. | ||
| # | ||
| # This code is licensed under the Apache License, Version 2.0. You may | ||
| # obtain a copy of this license in the LICENSE.txt file in the root directory | ||
| # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
| # | ||
| # Any modifications or derivative works of this code must retain this | ||
| # copyright notice, and modified files need to carry a notice indicating | ||
| # that they have been altered from the originals. | ||
|
|
||
| """Test the ControlPatternSimplification pass.""" | ||
|
|
||
| import unittest | ||
| import numpy as np | ||
|
|
||
| from qiskit import QuantumCircuit | ||
| from qiskit.circuit.library import RXGate, RYGate, RZGate | ||
| from qiskit.transpiler.passes import ControlPatternSimplification | ||
| from qiskit.quantum_info import Statevector, state_fidelity | ||
| from test import QiskitTestCase # pylint: disable=wrong-import-order | ||
| from qiskit.utils import optionals | ||
|
|
||
|
|
||
| class TestControlPatternSimplification(QiskitTestCase): | ||
| """Tests for ControlPatternSimplification transpiler pass.""" | ||
|
|
||
| @unittest.skipUnless(optionals.HAS_SYMPY, "SymPy required for this test") | ||
| def test_complementary_patterns_rx(self): | ||
| """Test complementary control patterns with RX gates ('11' and '01' -> single control on q0).""" | ||
| # TODO: Implement test | ||
| # Expected: 2 MCRX gates -> 1 CRX gate | ||
| theta = np.pi / 4 | ||
| qc = QuantumCircuit(3) | ||
| qc.append(RXGate(theta).control(2, ctrl_state='11'), [0, 1, 2]) | ||
| qc.append(RXGate(theta).control(2, ctrl_state='01'), [0, 1, 2]) | ||
|
|
||
| # For now, just test that the pass can be instantiated | ||
| pass_ = ControlPatternSimplification() | ||
| # optimized = pass_(qc) | ||
| # self.assertLess(optimized.num_nonlocal_gates(), qc.num_nonlocal_gates()) | ||
|
|
||
| @unittest.skipUnless(optionals.HAS_SYMPY, "SymPy required for this test") | ||
| def test_complementary_patterns_ry(self): | ||
| """Test complementary control patterns with RY gates.""" | ||
| # TODO: Implement test - same optimization should work for RY | ||
| theta = np.pi / 4 | ||
| qc = QuantumCircuit(3) | ||
| qc.append(RYGate(theta).control(2, ctrl_state='11'), [0, 1, 2]) | ||
| qc.append(RYGate(theta).control(2, ctrl_state='01'), [0, 1, 2]) | ||
|
|
||
| pass_ = ControlPatternSimplification() | ||
| # optimized = pass_(qc) | ||
|
|
||
| @unittest.skipUnless(optionals.HAS_SYMPY, "SymPy required for this test") | ||
| def test_complementary_patterns_rz(self): | ||
| """Test complementary control patterns with RZ gates.""" | ||
| # TODO: Implement test - same optimization should work for RZ | ||
| theta = np.pi / 4 | ||
| qc = QuantumCircuit(3) | ||
| qc.append(RZGate(theta).control(2, ctrl_state='11'), [0, 1, 2]) | ||
| qc.append(RZGate(theta).control(2, ctrl_state='01'), [0, 1, 2]) | ||
|
|
||
| pass_ = ControlPatternSimplification() | ||
| # optimized = pass_(qc) | ||
|
|
||
Mostafa-Atallah2020 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| @unittest.skipUnless(optionals.HAS_SYMPY, "SymPy required for this test") | ||
| def test_subset_patterns(self): | ||
| """Test subset control patterns ('111' and '110' -> reduce control count).""" | ||
| # TODO: Implement test | ||
| pass | ||
|
|
||
| @unittest.skipUnless(optionals.HAS_SYMPY, "SymPy required for this test") | ||
| def test_xor_patterns(self): | ||
| """Test XOR control patterns ('110' and '101' -> CNOT optimization).""" | ||
| # TODO: Implement test | ||
| pass | ||
|
|
||
| @unittest.skipUnless(optionals.HAS_SYMPY, "SymPy required for this test") | ||
| def test_state_equivalence(self): | ||
| """Test that optimized circuit maintains state equivalence.""" | ||
| # TODO: Implement comprehensive fidelity test | ||
| pass | ||
|
|
||
| def test_pass_without_sympy(self): | ||
| """Test that the pass raises appropriate error without SymPy.""" | ||
| # TODO: Test optional dependency handling | ||
| pass | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.