diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 1ac4e8448edf..8132630b1dbc 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -1623,7 +1623,6 @@ def qasm( "sx", "sxdg", "cz", - "ccz", "cy", "swap", "ch", @@ -1636,8 +1635,6 @@ def qasm( "cp", "cu3", "csx", - "cs", - "csdg", "cu", "rxx", "rzz", diff --git a/releasenotes/notes/fix_9559-ec05304e52ff841f.yaml b/releasenotes/notes/fix_9559-ec05304e52ff841f.yaml new file mode 100644 index 000000000000..4e0cb1918f6c --- /dev/null +++ b/releasenotes/notes/fix_9559-ec05304e52ff841f.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + The Qiskit gates :class:`~.CCZGate`, :class:`~.CSGate`, :class:`~.CSdgGate` are not defined in + ``qelib1.inc`` and, therefore, when dump as OpenQASM 2.0, their definition should be inserted in the file. + Fixes `#9559 `__, + `#9721 `__, and + `#9722 `__. diff --git a/test/python/circuit/test_circuit_qasm.py b/test/python/circuit/test_circuit_qasm.py index b8089e7756f0..8924bd1f4051 100644 --- a/test/python/circuit/test_circuit_qasm.py +++ b/test/python/circuit/test_circuit_qasm.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Test Qiskit's QuantumCircuit class.""" +"""Test Qiskit's gates in QASM2.""" import unittest from math import pi @@ -19,7 +19,7 @@ from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.test import QiskitTestCase from qiskit.circuit import Parameter, Qubit, Clbit, Gate -from qiskit.circuit.library import C3SXGate +from qiskit.circuit.library import C3SXGate, CCZGate, CSGate, CSdgGate, RZXGate from qiskit.qasm.exceptions import QasmError # Regex pattern to match valid OpenQASM identifiers @@ -27,7 +27,7 @@ class TestCircuitQasm(QiskitTestCase): - """QuantumCircuit Qasm tests.""" + """QuantumCircuit QASM2 tests.""" def test_circuit_qasm(self): """Test circuit qasm() method.""" @@ -249,7 +249,9 @@ def test_circuit_qasm_with_composite_circuit_with_many_params_and_qubits(self): self.assertEqual(original_str, qc.qasm()) def test_c3sxgate_roundtrips(self): - """Test that C3SXGate correctly round trips. Qiskit gives this gate a different name + """Test that C3SXGate correctly round trips. + + Qiskit gives this gate a different name ('c3sx') to the name in Qiskit's version of qelib1.inc ('c3sqrtx') gate, which can lead to resolution issues.""" qc = QuantumCircuit(4) @@ -264,6 +266,58 @@ def test_c3sxgate_roundtrips(self): parsed = QuantumCircuit.from_qasm_str(qasm) self.assertIsInstance(parsed.data[0].operation, C3SXGate) + def test_cczgate_qasm(self): + """Test that CCZ dumps definition as a non-qelib1 gate.""" + qc = QuantumCircuit(3) + qc.append(CCZGate(), qc.qubits, []) + qasm = qc.qasm() + expected = """OPENQASM 2.0; +include "qelib1.inc"; +gate ccz q0,q1,q2 { h q2; ccx q0,q1,q2; h q2; } +qreg q[3]; +ccz q[0],q[1],q[2]; +""" + self.assertEqual(qasm, expected) + + def test_csgate_qasm(self): + """Test that CS dumps definition as a non-qelib1 gate.""" + qc = QuantumCircuit(2) + qc.append(CSGate(), qc.qubits, []) + qasm = qc.qasm() + expected = """OPENQASM 2.0; +include "qelib1.inc"; +gate cs q0,q1 { p(pi/4) q0; cx q0,q1; p(-pi/4) q1; cx q0,q1; p(pi/4) q1; } +qreg q[2]; +cs q[0],q[1]; +""" + self.assertEqual(qasm, expected) + + def test_csdggate_qasm(self): + """Test that CSdg dumps definition as a non-qelib1 gate.""" + qc = QuantumCircuit(2) + qc.append(CSdgGate(), qc.qubits, []) + qasm = qc.qasm() + expected = """OPENQASM 2.0; +include "qelib1.inc"; +gate csdg q0,q1 { p(-pi/4) q0; cx q0,q1; p(pi/4) q1; cx q0,q1; p(-pi/4) q1; } +qreg q[2]; +csdg q[0],q[1]; +""" + self.assertEqual(qasm, expected) + + def test_rzxgate_qasm(self): + """Test that RZX dumps definition as a non-qelib1 gate.""" + qc = QuantumCircuit(2) + qc.append(RZXGate(0), qc.qubits, []) + qasm = qc.qasm() + expected = """OPENQASM 2.0; +include "qelib1.inc"; +gate rzx(param0) q0,q1 { h q1; cx q0,q1; rz(0) q1; cx q0,q1; h q1; } +qreg q[2]; +rzx(0) q[0],q[1]; +""" + self.assertEqual(qasm, expected) + def test_unbound_circuit_raises(self): """Test circuits with unbound parameters raises.""" qc = QuantumCircuit(1)