Skip to content

Commit

Permalink
Resolve issue 1073 handle unsupported gates (#2585)
Browse files Browse the repository at this point in the history
* check cases for issue 1073

* attempted to resolve issue 1073, added tests

* added comment

* changed constant name

* simplified the from_qiskit and removed folding related tests

* removed folding tests, changed from_qiskit logic to optimal

* formatted

* editted ryy test + added operator conversion test

* changed test name for consistency

* removed unused packages
  • Loading branch information
gluonhiggs authored Dec 12, 2024
1 parent 85a8418 commit 7d510d6
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 38 deletions.
33 changes: 29 additions & 4 deletions mitiq/interface/mitiq_qiskit/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,42 @@ def from_qiskit(circuit: qiskit.QuantumCircuit) -> cirq.Circuit:
Returns:
Mitiq circuit representation equivalent to the input Qiskit circuit.
"""

try:
mitiq_circuit = from_qasm(qasm2.dumps(circuit))

except QasmException:
# Try to decompose circuit before running
# This is necessary for converting qiskit circuits with
# custom packaged gates, e.g., QFT gates
GATES_TO_DECOMPOSE = ["rxx", "rzz", "rzx", "ryy", "QFT"]
circuit = circuit.decompose(gates_to_decompose=GATES_TO_DECOMPOSE)
BASIS_GATES = [
"sx",
"sxdg",
"rx",
"ry",
"rz",
"id",
"u1",
"u2",
"u3",
"r",
"x",
"y",
"z",
"h",
"s",
"t",
"cx",
"cy",
"cz",
"ch",
"swap",
"cswap",
"ccx",
"sdg",
"tdg",
]
circuit = qiskit.transpile(circuit, basis_gates=BASIS_GATES)
mitiq_circuit = from_qasm(qasm2.dumps(circuit))

return mitiq_circuit


Expand Down
135 changes: 135 additions & 0 deletions mitiq/interface/mitiq_qiskit/tests/test_conversions_qiskit.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,3 +484,138 @@ def test_convert_to_mitiq_with_rx_and_rzz():
test_qc.rx(0.1, 0)
test_qc.rzz(0.1, 0, 1)
assert convert_to_mitiq(test_qc)


def test_convert_to_mitiq_with_rx_and_ryy():
"""
Tests that convert_to_mitiq works with RX and RYY gates.
"""
test_qc = qiskit.QuantumCircuit(2)
test_qc.rx(0.1, 0)
test_qc.ryy(0.1, 0, 1)
assert convert_to_mitiq(test_qc)


def test_convert_to_mitiq_with_sx():
"""
Tests that convert_to_mitiq works with SX gates.
"""
test_qc = qiskit.QuantumCircuit(1)
test_qc.sx(0)
assert convert_to_mitiq(test_qc)


def test_convert_to_mitiq_with_u():
"""
Tests that convert_to_mitiq works with U gates.
"""

test_qc = qiskit.QuantumCircuit(1)
test_qc.u(0.1, 0.2, 0.3, 0)
assert convert_to_mitiq(test_qc)


def test_convert_to_mitiq_with_p():
"""
Tests that convert_to_mitiq works with P gates.
"""
circuit = qiskit.QuantumCircuit(1)
circuit.p(np.pi / 4, 0)

assert convert_to_mitiq(circuit)


def test_convert_to_mitiq_with_cu1():
"""
Tests that convert_to_mitiq works with CU1 gates.
"""
test_qc = qiskit.QuantumCircuit(2)
test_qc.h(0)
test_qc.h(1)
cu1_gate = qiskit.circuit.library.CU1Gate(np.pi / 4)
test_qc.append(cu1_gate, [0, 1])
assert convert_to_mitiq(test_qc)


def test_convert_to_mitiq_with_ecrgate():
"""
Tests that convert_to_mitiq works with ECR gates.
"""
circuit = qiskit.QuantumCircuit(2)
circuit.h(0)
circuit.h(1)
circuit.append(qiskit.circuit.library.ECRGate(), [0, 1])
assert convert_to_mitiq(circuit)


def test_convert_to_mitiq_with_rxx_rzz_ecr():
"""
Tests that convert_to_mitiq works with RXX, RZZ, and ECR gates.
"""
circuit = qiskit.QuantumCircuit(2)
circuit.sx(0)
circuit.append(qiskit.circuit.library.RXXGate(np.pi / 3), [0, 1])
circuit.append(qiskit.circuit.library.RZZGate(np.pi / 4), [0, 1])
circuit.append(qiskit.circuit.library.ECRGate(), [0, 1])
assert convert_to_mitiq(circuit)


def test_convert_to_mitiq_with_rzx_ryy_p():
"""
Tests that convert_to_mitiq works with RZX, RYY, and P gates.
"""
rotation_circuit = qiskit.QuantumCircuit(2)
rotation_circuit.p(np.pi / 8, 0)
rotation_circuit.append(qiskit.circuit.library.RZXGate(np.pi / 6), [0, 1])
rotation_circuit.append(qiskit.circuit.library.RYYGate(np.pi / 5), [0, 1])
assert convert_to_mitiq(rotation_circuit)


def test_convert_to_mitiq_with_qft_cu1_rzx():
"""
Tests that convert_to_mitiq works with QFT, CU1, and RZX gates.
"""
circuit = qiskit.QuantumCircuit(2)
circuit.h(0)
circuit.h(1)
circuit.append(qiskit.circuit.library.QFT(2), [0, 1])
circuit.append(qiskit.circuit.library.CU1Gate(np.pi / 3), [0, 1])
circuit.append(qiskit.circuit.library.RZXGate(np.pi / 4), [0, 1])
assert convert_to_mitiq(circuit)


def test_convert_to_mitiq_with_rzz_u_p_ecr():
"""
Tests that convert_to_mitiq works with RZZ, U, P, and ECR gates.
"""
circuit = qiskit.QuantumCircuit(2)
circuit.append(qiskit.circuit.library.RZZGate(np.pi / 4), [0, 1])
circuit.u(0.1, 0.2, 0.3, 0)
circuit.p(np.pi / 4, 0)
circuit.append(qiskit.circuit.library.ECRGate(), [0, 1])
circuit.append(qiskit.circuit.library.RZZGate(np.pi / 2), [0, 1])
assert convert_to_mitiq(circuit)


def test_convert_to_mitiq_with_rxx_ryy_sx_cu1():
"""
Tests that convert_to_mitiq works with RXX, RYY, SX, and CU1 gates.
"""
circuit = qiskit.QuantumCircuit(2)
circuit.sx(0)
circuit.append(qiskit.circuit.library.RXXGate(np.pi / 4), [0, 1])
circuit.append(qiskit.circuit.library.RYYGate(np.pi / 6), [0, 1])
circuit.append(qiskit.circuit.library.CU1Gate(np.pi / 8), [0, 1])
circuit.u(0.5, 0.7, 0.2, 0)
assert convert_to_mitiq(circuit)


def test_convert_to_mitiq_with_custom_operator():
"""
Tests that convert_to_mitiq works with a custom operator.
"""
gate = qiskit.quantum_info.Operator([[0.0, 1.0], [-1.0, 0.0]])
qreg = qiskit.QuantumRegister(1)
circ = qiskit.QuantumCircuit(qreg)
circ.unitary(gate, [0])
assert convert_to_mitiq(circ)
34 changes: 0 additions & 34 deletions mitiq/zne/scaling/tests/test_folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from pyquil import Program, gates
from pyquil.quilbase import Pragma
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister
from qiskit.quantum_info.operators import Operator
from sympy import Symbol

from mitiq.interface import (
Expand Down Expand Up @@ -1149,19 +1148,6 @@ def test_convert_from_mitiq_circuit_conversion_error(conversion_type):
convert_from_mitiq(noisy, conversion_type)


def test_convert_qiskit_to_mitiq_circuit_conversion_error():
# Custom gates are not supported in conversions
gate = Operator([[0.0, 1.0], [-1.0, 0.0]])
qreg = QuantumRegister(1)
circ = QuantumCircuit(qreg)
circ.unitary(gate, [0])

with pytest.raises(
CircuitConversionError, match="Circuit could not be converted to"
):
convert_to_mitiq(circ)


def test_convert_pyquil_to_mitiq_circuit_conversion_error():
# Pragmas are not supported in conversions
prog = Program(Pragma("INITIAL_REWIRING", ['"Partial"']))
Expand All @@ -1172,26 +1158,6 @@ def test_convert_pyquil_to_mitiq_circuit_conversion_error():
convert_to_mitiq(prog)


@pytest.mark.parametrize(
"fold_method",
(
fold_gates_at_random,
fold_global,
),
)
def test_folding_circuit_conversion_error_qiskit(fold_method):
# Custom gates are not supported in conversions
gate = Operator([[0.0, 1.0], [-1.0, 0.0]])
qreg = QuantumRegister(1)
circ = QuantumCircuit(qreg)
circ.unitary(gate, [0])

with pytest.raises(
CircuitConversionError, match="Circuit could not be converted to"
):
fold_method(circ, scale_factor=2.0)


@pytest.mark.parametrize(
"fold_method",
(
Expand Down

0 comments on commit 7d510d6

Please sign in to comment.