Skip to content

Commit 6b82834

Browse files
committed
Update demo file
1 parent d6a3508 commit 6b82834

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

test_midcircuit.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import io
2+
3+
from qiskit import QuantumCircuit
4+
from qiskit.circuit import Instruction, Measure
5+
from qiskit.circuit.singleton import SingletonInstruction, stdlib_singleton_key
6+
from qiskit.circuit.exceptions import CircuitError
7+
from qiskit._accelerate.circuit import StandardInstructionType
8+
from qiskit.qpy import dump, load
9+
from qiskit.transpiler.passes import ResetAfterMeasureSimplification
10+
11+
12+
# IDEA 1: Subclass Measure
13+
# Pitfall: can't change name
14+
class MidCircuitMeasureSubclass(Measure):
15+
pass
16+
17+
# IDEA 1.2: Subclass Measure
18+
class CustomMeasurement(Measure):
19+
"""A custom specialized measurement."""
20+
21+
def __init__(self, label=None):
22+
super().__init__(label=label)
23+
if label:
24+
self.name= label
25+
else:
26+
self.name="measure_2"
27+
28+
29+
# IDEA 2: Just build an instruction
30+
# Pitfall: the transpiler doesn't detect it as a measurement
31+
class MidCircuitMeasureInstruction(Instruction):
32+
def __init__(self, label=None):
33+
super().__init__("mid_circuit_measure", 1, 1, [], label=label)
34+
35+
36+
# IDEA 3: copy Measure() definition. Works!
37+
# Pitfall:
38+
# - setting the standard instruction type like this looks a bit sketchy
39+
# - if we do this from outside qiskit (qiskit-ibm-runtime), we'd have to import
40+
# StandardInstructionType from qiskit._accelerate.circuit
41+
class NamedMeasure(SingletonInstruction):
42+
"""Quantum measurement in the computational basis."""
43+
44+
# Just force the standard instruction type?
45+
_standard_instruction_type = StandardInstructionType.Measure
46+
47+
def __init__(self, name="measure_2", label=None):
48+
"""
49+
Args:
50+
label: optional string label for this instruction.
51+
"""
52+
super().__init__(name, 1, 1, [], label=label)
53+
54+
def __init_subclass__(cls, **kwargs):
55+
super().__init_subclass__(**kwargs)
56+
# Subclasses of Measure are not "standard", so we set this to None to
57+
# prevent the Rust code from treating them as such.
58+
cls._standard_instruction_type = None
59+
60+
_singleton_lookup_key = stdlib_singleton_key()
61+
62+
def broadcast_arguments(self, qargs, cargs):
63+
qarg = qargs[0]
64+
carg = cargs[0]
65+
66+
if len(carg) == len(qarg):
67+
for qarg, carg in zip(qarg, carg):
68+
yield [qarg], [carg]
69+
elif len(qarg) == 1 and carg:
70+
for each_carg in carg:
71+
yield qarg, [each_carg]
72+
else:
73+
raise CircuitError("register size error")
74+
75+
loaded = {}
76+
for cls in [CustomMeasurement]:
77+
circ = QuantumCircuit(2, 2)
78+
circ.append(cls(), [0], [0])
79+
circ.append(cls("measure_3"), [0], [1])
80+
circ.measure_all()
81+
print(circ.draw())
82+
83+
with io.BytesIO() as f:
84+
dump(circ, f)
85+
f.seek(0)
86+
loaded[str(cls)] = load(f)
87+
88+
89+
for cls, loaded_circ in loaded.items():
90+
print(cls)
91+
print(list(loaded_circ[0].data))
92+
93+
def test_bv_circuit():
94+
"""Test Bernstein Vazirani circuit with midcircuit measurement."""
95+
bitstring = "11111"
96+
qc = QuantumCircuit(2, len(bitstring))
97+
qc.x(1)
98+
qc.h(1)
99+
for idx, bit in enumerate(bitstring[::-1]):
100+
qc.h(0)
101+
if int(bit):
102+
qc.cx(0, 1)
103+
qc.h(0)
104+
qc.append(CustomMeasurement(label="measure_3"), [0], [idx])
105+
# qc.measure(0, idx)
106+
if idx != len(bitstring) - 1:
107+
qc.reset(0)
108+
# reset control
109+
qc.reset(1)
110+
qc.x(1)
111+
qc.h(1)
112+
print(qc.draw())
113+
new_qc = ResetAfterMeasureSimplification()(qc)
114+
print(new_qc.draw())
115+
116+
for op in new_qc.data:
117+
if op.operation.name == "reset":
118+
print(op.qubits[0] == new_qc.qubits[1])
119+
# self.assertEqual(op.qubits[0], new_qc.qubits[1])
120+
121+
# test_bv_circuit()

0 commit comments

Comments
 (0)