diff --git a/qiskit/circuit/singleton_gate.py b/qiskit/circuit/singleton_gate.py index 3d24247e31ca..2fafa867b7f3 100644 --- a/qiskit/circuit/singleton_gate.py +++ b/qiskit/circuit/singleton_gate.py @@ -80,6 +80,11 @@ def __init__(self, *args, _condition=None, **kwargs): super().__init__(*args, **kwargs) self._condition = _condition + def __getnewargs_ex__(self): + if not self.mutable: + return ((), {}) + return ((self.label, self._condition, self.duration, self.unit), {}) + def c_if(self, classical, val): if not isinstance(classical, (ClassicalRegister, Clbit)): raise CircuitError("c_if must be used with a classical register or classical bit") diff --git a/test/python/circuit/test_singleton_gate.py b/test/python/circuit/test_singleton_gate.py index d8c80661d675..695216be450d 100644 --- a/test/python/circuit/test_singleton_gate.py +++ b/test/python/circuit/test_singleton_gate.py @@ -18,6 +18,8 @@ """ import copy +import io +import pickle from qiskit.circuit.library import HGate, SXGate from qiskit.circuit import Clbit, QuantumCircuit, QuantumRegister, ClassicalRegister @@ -251,3 +253,27 @@ def test_positional_label(self): label_gate = SXGate("I am a little label") self.assertIsNot(gate, label_gate) self.assertEqual(label_gate.label, "I am a little label") + + def test_immutable_pickle(self): + gate = SXGate() + self.assertFalse(gate.mutable) + with io.BytesIO() as fd: + pickle.dump(gate, fd) + fd.seek(0) + copied = pickle.load(fd) + self.assertFalse(copied.mutable) + self.assertIs(copied, gate) + + def test_mutable_pickle(self): + gate = SXGate() + clbit = Clbit() + condition_gate = gate.c_if(clbit, 0) + self.assertIsNot(gate, condition_gate) + self.assertEqual(condition_gate.condition, (clbit, 0)) + self.assertTrue(condition_gate.mutable) + with io.BytesIO() as fd: + pickle.dump(condition_gate, fd) + fd.seek(0) + copied = pickle.load(fd) + self.assertEqual(copied, condition_gate) + self.assertTrue(copied.mutable) diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index 0be4922cb5b7..6d9555c15a49 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -2173,6 +2173,20 @@ def run(self, dag): added_cal = qc_test.calibrations["sx"][((0,), ())] self.assertEqual(added_cal, ref_cal) + @data(0, 1, 2, 3) + def test_parallel_singleton_conditional_gate(self, opt_level): + """Test that singleton mutable instance doesn't lose state in parallel.""" + backend = FakeNairobiV2() + circ = QuantumCircuit(2, 1) + circ.h(0) + circ.measure(0, circ.clbits[0]) + circ.z(1).c_if(circ.clbits[0], 1) + res = transpile( + [circ, circ], backend, optimization_level=opt_level, seed_transpiler=123456769 + ) + self.assertTrue(res[0].data[-1].operation.mutable) + self.assertEqual(res[0].data[-1].operation.condition, (res[0].clbits[0], 1)) + @data(0, 1, 2, 3) def test_backendv2_and_basis_gates(self, opt_level): """Test transpile() with BackendV2 and basis_gates set."""