From d96573e166be637f379be00a1e4ec7e736c8a70b Mon Sep 17 00:00:00 2001 From: changsookim <> Date: Mon, 19 Aug 2024 19:53:53 +0800 Subject: [PATCH 1/6] add cnot as native --- src/qibo/transpiler/decompositions.py | 6 ++++++ src/qibo/transpiler/unroller.py | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/qibo/transpiler/decompositions.py b/src/qibo/transpiler/decompositions.py index 780aa42c99..29d691402a 100644 --- a/src/qibo/transpiler/decompositions.py +++ b/src/qibo/transpiler/decompositions.py @@ -387,6 +387,12 @@ def _u3_to_gpi2(t, p, l): lambda gate: two_qubit_decomposition(0, 1, gate.matrix(backend), backend=backend), ) +# temporary CNOT decompositions for CNOT, CZ, SWAP +cnot_dec_temp = GateDecompositions() +cnot_dec_temp.add(gates.CNOT, [gates.CNOT(0, 1)]) +cnot_dec_temp.add(gates.CZ, [gates.H(1), gates.CNOT(0, 1), gates.H(1)]) +cnot_dec_temp.add(gates.SWAP, [gates.CNOT(0, 1), gates.CNOT(1, 0), gates.CNOT(0, 1)]) + # register other optimized gate decompositions opt_dec = GateDecompositions() opt_dec.add( diff --git a/src/qibo/transpiler/unroller.py b/src/qibo/transpiler/unroller.py index a14aca382d..25d691f4fe 100644 --- a/src/qibo/transpiler/unroller.py +++ b/src/qibo/transpiler/unroller.py @@ -4,7 +4,7 @@ from qibo.config import raise_error from qibo.models import Circuit from qibo.transpiler._exceptions import DecompositionError -from qibo.transpiler.decompositions import cz_dec, gpi2_dec, iswap_dec, opt_dec, u3_dec +from qibo.transpiler.decompositions import cz_dec, gpi2_dec, iswap_dec, opt_dec, u3_dec, cnot_dec_temp class NativeGates(Flag): @@ -32,6 +32,7 @@ class NativeGates(Flag): U3 = auto() CZ = auto() iSWAP = auto() + CNOT = auto() # For testing purposes @classmethod def default(cls): @@ -239,6 +240,12 @@ def _translate_two_qubit_gates(gate: gates.Gate, native_gates: NativeGates): for g_translated in translate_gate(g, native_gates=native_gates): iswap_decomposed.append(g_translated) return iswap_decomposed + + # For testing purposes + # No CZ, iSWAP gates in the native gate set + # Decompose CNOT, CZ, SWAP gates into CNOT gates + if native_gates & NativeGates.CNOT: + return cnot_dec_temp(gate) raise_error( DecompositionError, "Use only CZ and/or iSWAP as native gates" From 04598028ed8a9a2bcccd585d1eed5558cefcb064 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 11:58:02 +0000 Subject: [PATCH 2/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/qibo/transpiler/unroller.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/qibo/transpiler/unroller.py b/src/qibo/transpiler/unroller.py index 25d691f4fe..adc2e02d78 100644 --- a/src/qibo/transpiler/unroller.py +++ b/src/qibo/transpiler/unroller.py @@ -4,7 +4,14 @@ from qibo.config import raise_error from qibo.models import Circuit from qibo.transpiler._exceptions import DecompositionError -from qibo.transpiler.decompositions import cz_dec, gpi2_dec, iswap_dec, opt_dec, u3_dec, cnot_dec_temp +from qibo.transpiler.decompositions import ( + cnot_dec_temp, + cz_dec, + gpi2_dec, + iswap_dec, + opt_dec, + u3_dec, +) class NativeGates(Flag): @@ -32,7 +39,7 @@ class NativeGates(Flag): U3 = auto() CZ = auto() iSWAP = auto() - CNOT = auto() # For testing purposes + CNOT = auto() # For testing purposes @classmethod def default(cls): @@ -240,11 +247,11 @@ def _translate_two_qubit_gates(gate: gates.Gate, native_gates: NativeGates): for g_translated in translate_gate(g, native_gates=native_gates): iswap_decomposed.append(g_translated) return iswap_decomposed - + # For testing purposes # No CZ, iSWAP gates in the native gate set # Decompose CNOT, CZ, SWAP gates into CNOT gates - if native_gates & NativeGates.CNOT: + if native_gates & NativeGates.CNOT: return cnot_dec_temp(gate) raise_error( From 07d721da030a970a58ce9d8d6a00c865ad1f2218 Mon Sep 17 00:00:00 2001 From: changsookim <> Date: Tue, 20 Aug 2024 14:35:15 +0800 Subject: [PATCH 3/6] update test func --- tests/test_transpiler_unroller.py | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_transpiler_unroller.py b/tests/test_transpiler_unroller.py index 61e2c11fc1..d3bb88af44 100644 --- a/tests/test_transpiler_unroller.py +++ b/tests/test_transpiler_unroller.py @@ -121,3 +121,35 @@ def test_measurements_non_comp_basis(): assert isinstance(transpiled_circuit.queue[2], gates.M) # After transpiling the measurement gate should be in the computational basis assert transpiled_circuit.queue[2].basis == [] + +def test_temp_cnot_decomposition(): + from qibo.transpiler.pipeline import Passes + + circ = Circuit(2) + circ.add(gates.H(0)) + circ.add(gates.CNOT(0, 1)) + circ.add(gates.SWAP(0, 1)) + circ.add(gates.CZ(0, 1)) + circ.add(gates.M(0, 1)) + + glist = [gates.GPI2, gates.RZ, gates.Z, gates.M, gates.CNOT] + native_gates = NativeGates(0).from_gatelist(glist) + + custom_pipeline = Passes([Unroller(native_gates=native_gates)]) + transpiled_circuit, _ = custom_pipeline(circ) + + # H + assert transpiled_circuit.queue[0].name == 'z' + assert transpiled_circuit.queue[1].name == 'gpi2' + # CNOT + assert transpiled_circuit.queue[2].name == 'cx' + # SWAP + assert transpiled_circuit.queue[3].name == 'cx' + assert transpiled_circuit.queue[4].name == 'cx' + assert transpiled_circuit.queue[5].name == 'cx' + # CZ + assert transpiled_circuit.queue[6].name == 'z' + assert transpiled_circuit.queue[7].name == 'gpi2' + assert transpiled_circuit.queue[8].name == 'cx' + assert transpiled_circuit.queue[9].name == 'z' + assert transpiled_circuit.queue[10].name == 'gpi2' \ No newline at end of file From 96e5d0d5d78a0f4a4828325f92b1ff099bd859be Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 06:35:48 +0000 Subject: [PATCH 4/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_transpiler_unroller.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/test_transpiler_unroller.py b/tests/test_transpiler_unroller.py index d3bb88af44..474d2c50a3 100644 --- a/tests/test_transpiler_unroller.py +++ b/tests/test_transpiler_unroller.py @@ -122,6 +122,7 @@ def test_measurements_non_comp_basis(): # After transpiling the measurement gate should be in the computational basis assert transpiled_circuit.queue[2].basis == [] + def test_temp_cnot_decomposition(): from qibo.transpiler.pipeline import Passes @@ -134,22 +135,22 @@ def test_temp_cnot_decomposition(): glist = [gates.GPI2, gates.RZ, gates.Z, gates.M, gates.CNOT] native_gates = NativeGates(0).from_gatelist(glist) - + custom_pipeline = Passes([Unroller(native_gates=native_gates)]) transpiled_circuit, _ = custom_pipeline(circ) # H - assert transpiled_circuit.queue[0].name == 'z' - assert transpiled_circuit.queue[1].name == 'gpi2' + assert transpiled_circuit.queue[0].name == "z" + assert transpiled_circuit.queue[1].name == "gpi2" # CNOT - assert transpiled_circuit.queue[2].name == 'cx' + assert transpiled_circuit.queue[2].name == "cx" # SWAP - assert transpiled_circuit.queue[3].name == 'cx' - assert transpiled_circuit.queue[4].name == 'cx' - assert transpiled_circuit.queue[5].name == 'cx' + assert transpiled_circuit.queue[3].name == "cx" + assert transpiled_circuit.queue[4].name == "cx" + assert transpiled_circuit.queue[5].name == "cx" # CZ - assert transpiled_circuit.queue[6].name == 'z' - assert transpiled_circuit.queue[7].name == 'gpi2' - assert transpiled_circuit.queue[8].name == 'cx' - assert transpiled_circuit.queue[9].name == 'z' - assert transpiled_circuit.queue[10].name == 'gpi2' \ No newline at end of file + assert transpiled_circuit.queue[6].name == "z" + assert transpiled_circuit.queue[7].name == "gpi2" + assert transpiled_circuit.queue[8].name == "cx" + assert transpiled_circuit.queue[9].name == "z" + assert transpiled_circuit.queue[10].name == "gpi2" From d6d600068dac1c20e32efedb39e83203016e7756 Mon Sep 17 00:00:00 2001 From: changsookim <> Date: Mon, 26 Aug 2024 15:27:47 +0800 Subject: [PATCH 5/6] add error msg / docstring --- src/qibo/transpiler/unroller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qibo/transpiler/unroller.py b/src/qibo/transpiler/unroller.py index adc2e02d78..9c6630a11c 100644 --- a/src/qibo/transpiler/unroller.py +++ b/src/qibo/transpiler/unroller.py @@ -29,6 +29,7 @@ class NativeGates(Flag): - :class:`qibo.gates.gates.U3` - :class:`qibo.gates.gates.CZ` - :class:`qibo.gates.gates.iSWAP` + - :class:`qibo.gates.gates.CNOT` """ I = auto() @@ -255,5 +256,5 @@ def _translate_two_qubit_gates(gate: gates.Gate, native_gates: NativeGates): return cnot_dec_temp(gate) raise_error( - DecompositionError, "Use only CZ and/or iSWAP as native gates" + DecompositionError, "Use only CZ and/or iSWAP as native gates. CNOT is allowed in circuits where the two-qubit gates are limited to CZ, CNOT, and SWAP." ) # pragma: no cover From 3281871143a17015f9764ca0ddeae80d14579d23 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 07:28:19 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/qibo/transpiler/unroller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qibo/transpiler/unroller.py b/src/qibo/transpiler/unroller.py index 9c6630a11c..9032e5e306 100644 --- a/src/qibo/transpiler/unroller.py +++ b/src/qibo/transpiler/unroller.py @@ -256,5 +256,6 @@ def _translate_two_qubit_gates(gate: gates.Gate, native_gates: NativeGates): return cnot_dec_temp(gate) raise_error( - DecompositionError, "Use only CZ and/or iSWAP as native gates. CNOT is allowed in circuits where the two-qubit gates are limited to CZ, CNOT, and SWAP." + DecompositionError, + "Use only CZ and/or iSWAP as native gates. CNOT is allowed in circuits where the two-qubit gates are limited to CZ, CNOT, and SWAP.", ) # pragma: no cover