From 6bc122d653c7410a681699d503d1bb42f756e582 Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Mon, 26 Jun 2023 20:37:18 -0400 Subject: [PATCH 1/6] Add support for cut `CYGate`s --- circuit_knitting/cutting/qpd/qpd.py | 13 +++++++++---- .../notes/additional-gates-f4ed6c0e8dc3a9be.yaml | 4 ++++ test/cutting/qpd/test_qpd.py | 4 +++- test/cutting/test_cutting_roundtrip.py | 2 ++ 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml diff --git a/circuit_knitting/cutting/qpd/qpd.py b/circuit_knitting/cutting/qpd/qpd.py index 995f5d781..c25d3d052 100644 --- a/circuit_knitting/cutting/qpd/qpd.py +++ b/circuit_knitting/cutting/qpd/qpd.py @@ -37,6 +37,7 @@ RYGate, RZGate, CXGate, + CYGate, CZGate, RXXGate, RYYGate, @@ -199,6 +200,7 @@ def qpdbasis_from_gate(gate: Gate) -> QPDBasis: - :class:`~qiskit.circuit.library.CRYGate` - :class:`~qiskit.circuit.library.CRZGate` - :class:`~qiskit.circuit.library.CXGate` + - :class:`~qiskit.circuit.library.CYGate` - :class:`~qiskit.circuit.library.CZGate` Returns: @@ -304,8 +306,8 @@ def _(gate: RXXGate | RYYGate | RZZGate | CRXGate | CRYGate | CRZGate): return QPDBasis(maps, coeffs) -@_register_qpdbasis_from_gate("cz", "cx") -def _(gate: CZGate | CXGate): +@_register_qpdbasis_from_gate("cx", "cy", "cz") +def _(gate: CXGate | CYGate | CZGate): # Constructing a virtual two-qubit gate by sampling single-qubit operations - Mitarai et al # https://iopscience.iop.org/article/10.1088/1367-2630/abd7bc/pdf measurement_0 = [SdgGate(), QPDMeasure()] @@ -323,12 +325,15 @@ def _(gate: CZGate | CXGate): ([ZGate()], measurement_1), ] - if gate.name == "cx": - # Modify `maps` to sandwich the target operations inside of Hadamards + if gate.name != "cz": + # Modify `maps` to sandwich the target operations inside of basis rotations for operations in {id(m[1]): m[1] for m in maps}.values(): if operations: operations.insert(0, HGate()) operations.append(HGate()) + if gate.name == "cy": + operations.insert(0, SdgGate()) + operations.append(SGate()) coeffs = [0.5, 0.5, 0.5, -0.5, 0.5, -0.5] diff --git a/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml new file mode 100644 index 000000000..7f14294ec --- /dev/null +++ b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Added support for cut :class:``~qiskit.circuit.library.CYGate`\ s. diff --git a/test/cutting/qpd/test_qpd.py b/test/cutting/qpd/test_qpd.py index 56f4fc555..c1a6d90e8 100644 --- a/test/cutting/qpd/test_qpd.py +++ b/test/cutting/qpd/test_qpd.py @@ -282,4 +282,6 @@ def test_qpdbasis_from_gate_unique_maps( def test_supported_gates(self): gates = supported_gates() - self.assertEqual({"rxx", "ryy", "rzz", "crx", "cry", "crz", "cx", "cz"}, gates) + self.assertEqual( + {"rxx", "ryy", "rzz", "crx", "cry", "crz", "cx", "cy", "cz"}, gates + ) diff --git a/test/cutting/test_cutting_roundtrip.py b/test/cutting/test_cutting_roundtrip.py index be6eeea13..8371715bf 100644 --- a/test/cutting/test_cutting_roundtrip.py +++ b/test/cutting/test_cutting_roundtrip.py @@ -22,6 +22,7 @@ RYYGate, RZZGate, CXGate, + CYGate, CZGate, CRXGate, CRYGate, @@ -49,6 +50,7 @@ def append_random_unitary(circuit: QuantumCircuit, qubits): @pytest.fixture( params=[ [CXGate()], + [CYGate()], [CZGate()], [RYYGate(0.0)], [RZZGate(np.pi)], From 2c2da1df107ea09d5e92c623f63928cf2caf78ce Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Mon, 26 Jun 2023 20:42:35 -0400 Subject: [PATCH 2/6] Fix release note syntax --- releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml index 7f14294ec..a69f51f9d 100644 --- a/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml +++ b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml @@ -1,4 +1,4 @@ --- features: - | - Added support for cut :class:``~qiskit.circuit.library.CYGate`\ s. + Added support for cut :class:`~qiskit.circuit.library.CYGate`\ s. From 58a65f99420f535548a5aaa014cd9935a537bb54 Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Mon, 26 Jun 2023 21:00:28 -0400 Subject: [PATCH 3/6] Add support for cut `CHGate`s --- circuit_knitting/cutting/qpd/qpd.py | 12 +++++++++--- .../notes/additional-gates-f4ed6c0e8dc3a9be.yaml | 4 +++- test/cutting/qpd/test_qpd.py | 2 +- test/cutting/test_cutting_roundtrip.py | 2 ++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/circuit_knitting/cutting/qpd/qpd.py b/circuit_knitting/cutting/qpd/qpd.py index c25d3d052..7f9f5b9e1 100644 --- a/circuit_knitting/cutting/qpd/qpd.py +++ b/circuit_knitting/cutting/qpd/qpd.py @@ -39,6 +39,7 @@ CXGate, CYGate, CZGate, + CHGate, RXXGate, RYYGate, RZZGate, @@ -306,8 +307,8 @@ def _(gate: RXXGate | RYYGate | RZZGate | CRXGate | CRYGate | CRZGate): return QPDBasis(maps, coeffs) -@_register_qpdbasis_from_gate("cx", "cy", "cz") -def _(gate: CXGate | CYGate | CZGate): +@_register_qpdbasis_from_gate("cx", "cy", "cz", "ch") +def _(gate: CXGate | CYGate | CZGate | CHGate): # Constructing a virtual two-qubit gate by sampling single-qubit operations - Mitarai et al # https://iopscience.iop.org/article/10.1088/1367-2630/abd7bc/pdf measurement_0 = [SdgGate(), QPDMeasure()] @@ -325,7 +326,7 @@ def _(gate: CXGate | CYGate | CZGate): ([ZGate()], measurement_1), ] - if gate.name != "cz": + if gate.name in ("cx", "cy"): # Modify `maps` to sandwich the target operations inside of basis rotations for operations in {id(m[1]): m[1] for m in maps}.values(): if operations: @@ -334,6 +335,11 @@ def _(gate: CXGate | CYGate | CZGate): if gate.name == "cy": operations.insert(0, SdgGate()) operations.append(SGate()) + elif gate.name == "ch": + for operations in {id(m[1]): m[1] for m in maps}.values(): + if operations: + operations.insert(0, RYGate(-np.pi / 4)) + operations.append(RYGate(np.pi / 4)) coeffs = [0.5, 0.5, 0.5, -0.5, 0.5, -0.5] diff --git a/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml index a69f51f9d..a69953cc8 100644 --- a/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml +++ b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml @@ -1,4 +1,6 @@ --- features: - | - Added support for cut :class:`~qiskit.circuit.library.CYGate`\ s. + This release adds support for additional cut gates: + - :class:`~qiskit.circuit.library.CHGate` + - :class:`~qiskit.circuit.library.CYGate` diff --git a/test/cutting/qpd/test_qpd.py b/test/cutting/qpd/test_qpd.py index c1a6d90e8..144b2849d 100644 --- a/test/cutting/qpd/test_qpd.py +++ b/test/cutting/qpd/test_qpd.py @@ -283,5 +283,5 @@ def test_qpdbasis_from_gate_unique_maps( def test_supported_gates(self): gates = supported_gates() self.assertEqual( - {"rxx", "ryy", "rzz", "crx", "cry", "crz", "cx", "cy", "cz"}, gates + {"rxx", "ryy", "rzz", "crx", "cry", "crz", "cx", "cy", "cz", "ch"}, gates ) diff --git a/test/cutting/test_cutting_roundtrip.py b/test/cutting/test_cutting_roundtrip.py index 8371715bf..be36cbacd 100644 --- a/test/cutting/test_cutting_roundtrip.py +++ b/test/cutting/test_cutting_roundtrip.py @@ -21,6 +21,7 @@ RXXGate, RYYGate, RZZGate, + CHGate, CXGate, CYGate, CZGate, @@ -52,6 +53,7 @@ def append_random_unitary(circuit: QuantumCircuit, qubits): [CXGate()], [CYGate()], [CZGate()], + [CHGate()], [RYYGate(0.0)], [RZZGate(np.pi)], [RXXGate(np.pi / 3)], From 7b01b3b0cdb4edf0d14fb66be286a802680db23a Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Mon, 26 Jun 2023 21:02:08 -0400 Subject: [PATCH 4/6] Update docstring --- circuit_knitting/cutting/qpd/qpd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/circuit_knitting/cutting/qpd/qpd.py b/circuit_knitting/cutting/qpd/qpd.py index 7f9f5b9e1..cc6896a54 100644 --- a/circuit_knitting/cutting/qpd/qpd.py +++ b/circuit_knitting/cutting/qpd/qpd.py @@ -203,6 +203,7 @@ def qpdbasis_from_gate(gate: Gate) -> QPDBasis: - :class:`~qiskit.circuit.library.CXGate` - :class:`~qiskit.circuit.library.CYGate` - :class:`~qiskit.circuit.library.CZGate` + - :class:`~qiskit.circuit.library.CHGate` Returns: The newly-instantiated :class:`QPDBasis` object From 75b88f539c02444e152322029d64dac3b368600b Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Mon, 26 Jun 2023 21:18:15 -0400 Subject: [PATCH 5/6] Fix number in docstring --- circuit_knitting/cutting/qpd/qpd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/qpd/qpd.py b/circuit_knitting/cutting/qpd/qpd.py index cc6896a54..01f491e41 100644 --- a/circuit_knitting/cutting/qpd/qpd.py +++ b/circuit_knitting/cutting/qpd/qpd.py @@ -193,7 +193,7 @@ def qpdbasis_from_gate(gate: Gate) -> QPDBasis: """ Generate a QPDBasis object, given a supported operation. - This method currently supports 8 operations: + This method currently supports 10 operations: - :class:`~qiskit.circuit.library.RXXGate` - :class:`~qiskit.circuit.library.RYYGate` - :class:`~qiskit.circuit.library.RZZGate` From 5e4ca52649916566f8a13e7f9abb29178f3c006a Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Mon, 26 Jun 2023 21:19:50 -0400 Subject: [PATCH 6/6] DRY --- circuit_knitting/cutting/qpd/qpd.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/circuit_knitting/cutting/qpd/qpd.py b/circuit_knitting/cutting/qpd/qpd.py index 01f491e41..6771798c0 100644 --- a/circuit_knitting/cutting/qpd/qpd.py +++ b/circuit_knitting/cutting/qpd/qpd.py @@ -327,20 +327,19 @@ def _(gate: CXGate | CYGate | CZGate | CHGate): ([ZGate()], measurement_1), ] - if gate.name in ("cx", "cy"): + if gate.name != "cz": # Modify `maps` to sandwich the target operations inside of basis rotations for operations in {id(m[1]): m[1] for m in maps}.values(): if operations: - operations.insert(0, HGate()) - operations.append(HGate()) - if gate.name == "cy": - operations.insert(0, SdgGate()) - operations.append(SGate()) - elif gate.name == "ch": - for operations in {id(m[1]): m[1] for m in maps}.values(): - if operations: - operations.insert(0, RYGate(-np.pi / 4)) - operations.append(RYGate(np.pi / 4)) + if gate.name in ("cx", "cy"): + operations.insert(0, HGate()) + operations.append(HGate()) + if gate.name == "cy": + operations.insert(0, SdgGate()) + operations.append(SGate()) + elif gate.name == "ch": + operations.insert(0, RYGate(-np.pi / 4)) + operations.append(RYGate(np.pi / 4)) coeffs = [0.5, 0.5, 0.5, -0.5, 0.5, -0.5]