mirror of https://github.com/Qiskit/qiskit.git
Fix `StatevectorSampler` to raise an error if a circuit with c_if is passed (#12842)
* fix StatevectorSampler with c_if * add comment
This commit is contained in:
parent
b985b96b9d
commit
239a669ab7
|
@ -207,7 +207,7 @@ def _preprocess_circuit(circuit: QuantumCircuit):
|
|||
qargs_index = {v: k for k, v in enumerate(qargs)}
|
||||
circuit = circuit.remove_final_measurements(inplace=False)
|
||||
if _has_control_flow(circuit):
|
||||
raise QiskitError("StatevectorSampler cannot handle ControlFlowOp")
|
||||
raise QiskitError("StatevectorSampler cannot handle ControlFlowOp and c_if")
|
||||
if _has_measure(circuit):
|
||||
raise QiskitError("StatevectorSampler cannot handle mid-circuit measurements")
|
||||
# num_qubits is used as sentinel to fill 0 in _samples_to_packed_array
|
||||
|
@ -283,4 +283,7 @@ def _final_measurement_mapping(circuit: QuantumCircuit) -> dict[tuple[ClassicalR
|
|||
|
||||
|
||||
def _has_control_flow(circuit: QuantumCircuit) -> bool:
|
||||
return any(isinstance(instruction.operation, ControlFlowOp) for instruction in circuit)
|
||||
return any(
|
||||
isinstance((op := instruction.operation), ControlFlowOp) or op.condition
|
||||
for instruction in circuit
|
||||
)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed a bug of :class:`.StatevectorSampler` that ignored gates with ``c_if``.
|
||||
It will raise an error because :class:`.Statevector` cannot handle ``c_if``.
|
|
@ -280,6 +280,11 @@ class TestStatevectorSampler(QiskitTestCase):
|
|||
qc3 = QuantumCircuit(1, 1)
|
||||
with qc3.for_loop(range(5)):
|
||||
qc3.h(0)
|
||||
qc4 = QuantumCircuit(2, 2)
|
||||
qc4.h(0)
|
||||
qc4.measure(1, 1)
|
||||
qc4.x(0).c_if(1, 1)
|
||||
qc4.measure(0, 0)
|
||||
|
||||
sampler = StatevectorSampler()
|
||||
with self.subTest("set parameter values to a non-parameterized circuit"):
|
||||
|
@ -301,6 +306,9 @@ class TestStatevectorSampler(QiskitTestCase):
|
|||
with self.subTest("with control flow"):
|
||||
with self.assertRaises(QiskitError):
|
||||
_ = sampler.run([qc3]).result()
|
||||
with self.subTest("with c_if"):
|
||||
with self.assertRaises(QiskitError):
|
||||
_ = sampler.run([qc4]).result()
|
||||
with self.subTest("negative shots, run arg"):
|
||||
with self.assertRaises(ValueError):
|
||||
_ = sampler.run([qc1], shots=-1).result()
|
||||
|
@ -584,17 +592,21 @@ class TestStatevectorSampler(QiskitTestCase):
|
|||
c2 = ClassicalRegister(1, "c2")
|
||||
|
||||
qc = QuantumCircuit(q, c1, c2)
|
||||
qc.ry(np.pi / 4, 2)
|
||||
qc.cx(2, 1)
|
||||
qc.cx(0, 1)
|
||||
qc.h(0)
|
||||
qc.measure(0, c1)
|
||||
qc.measure(1, c2)
|
||||
qc.z(2).c_if(c1, 1)
|
||||
qc.x(2).c_if(c2, 1)
|
||||
qc2 = QuantumCircuit(5, 5)
|
||||
qc2.compose(qc, [0, 2, 3], [2, 4], inplace=True)
|
||||
cregs = [creg.name for creg in qc2.cregs]
|
||||
# Note: qc2 has aliased cregs, c0 -> c[2] and c1 -> c[4].
|
||||
# copy_empty_like copies the aliased cregs of qc2 to qc3.
|
||||
qc3 = QuantumCircuit.copy_empty_like(qc2)
|
||||
qc3.ry(np.pi / 4, 2)
|
||||
qc3.cx(2, 1)
|
||||
qc3.cx(0, 1)
|
||||
qc3.h(0)
|
||||
qc3.measure(0, 2)
|
||||
qc3.measure(1, 4)
|
||||
self.assertEqual(len(qc3.cregs), 3)
|
||||
cregs = [creg.name for creg in qc3.cregs]
|
||||
target = {
|
||||
cregs[0]: {0: 4255, 4: 4297, 16: 720, 20: 726},
|
||||
cregs[1]: {0: 5000, 1: 5000},
|
||||
|
@ -602,7 +614,7 @@ class TestStatevectorSampler(QiskitTestCase):
|
|||
}
|
||||
|
||||
sampler = StatevectorSampler(seed=self._seed)
|
||||
result = sampler.run([qc2], shots=self._shots).result()
|
||||
result = sampler.run([qc3], shots=self._shots).result()
|
||||
self.assertEqual(len(result), 1)
|
||||
data = result[0].data
|
||||
self.assertEqual(len(data), 3)
|
||||
|
|
Loading…
Reference in New Issue