Skip to content

Commit ef339bb

Browse files
committed
Clarify memory qubit tracking in Cirq interop.
1 parent 0f31c20 commit ef339bb

2 files changed

Lines changed: 23 additions & 20 deletions

File tree

source/pip/qsharp/qre/interop/_cirq.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def trace_from_cirq(
7171
*,
7272
classical_control_probability: float = 0.5,
7373
rotation_threshold: float = 1e-6,
74-
memory_compute: bool = True,
74+
track_memory_qubits: bool = True,
7575
) -> Trace:
7676
"""Convert a Cirq circuit into a resource estimation Trace.
7777
@@ -89,9 +89,12 @@ def trace_from_cirq(
8989
trace. This applies to single-qubit rotations (RX, RY, RZ) as
9090
well as to the rotation components of controlled-Z
9191
decompositions. Defaults to 1e-6.
92-
memory_compute (bool): When True, memory qubits are tracked
93-
separately from compute qubits. When False, all qubits are
94-
treated as compute qubits. Defaults to True.
92+
track_memory_qubits (bool): When True, memory qubits are tracked
93+
separately from compute qubits. When False, all qubits are treated
94+
as compute qubits. Also, if True, read-from-memory and
95+
write-to-memory instructions are preserved in the trace, otherwise,
96+
they are decompsed into SWAP and RESET instructions. Defaults to
97+
True.
9598
9699
Returns:
97100
Trace: A Trace representing an execution profile of the circuit.
@@ -107,7 +110,7 @@ def trace_from_cirq(
107110
circuit = cirq.Circuit(circuit)
108111

109112
context = _CirqTraceBuilder(
110-
circuit, classical_control_probability, rotation_threshold, memory_compute
113+
circuit, classical_control_probability, rotation_threshold, track_memory_qubits
111114
)
112115

113116
for moment in circuit:
@@ -145,13 +148,13 @@ def __init__(
145148
circuit: cirq.Circuit,
146149
classical_control_probability: float,
147150
rotation_threshold: float,
148-
memory_compute: bool = True,
151+
track_memory_qubits: bool = True,
149152
):
150153
self._circuit = circuit
151154
self._trace = Trace(0)
152155
self._classical_control_probability = classical_control_probability
153156
self._rotation_threshold = rotation_threshold
154-
self._memory_compute = memory_compute
157+
self._track_memory_qubits = track_memory_qubits
155158
self._blocks = [self._trace.root_block()]
156159
self._q_to_id = _QidToTraceId(circuit.all_qubits())
157160
self._decomp_context = cirq.DecompositionContext(
@@ -179,7 +182,7 @@ def trace(self) -> Trace:
179182

180183
for q in self._circuit.all_qubits():
181184
if (
182-
self._memory_compute
185+
self._track_memory_qubits
183186
and isinstance(q, TypedQubit)
184187
and q.qubit_type == QubitType.MEMORY
185188
):
@@ -188,14 +191,14 @@ def trace(self) -> Trace:
188191
# Untyped qubits are considered COMPUTE by default.
189192
num_compute_qubits += 1
190193

191-
if self._memory_compute:
194+
if self._track_memory_qubits:
192195
num_memory_qubits += qm.memory_qubit_count()
193196
else:
194197
num_compute_qubits += qm.memory_qubit_count()
195198
num_compute_qubits += qm.compute_qubit_count()
196199

197200
self._trace.compute_qubits = num_compute_qubits
198-
if self._memory_compute and num_memory_qubits > 0:
201+
if self._track_memory_qubits and num_memory_qubits > 0:
199202
self._trace.memory_qubits = num_memory_qubits
200203

201204
return self._trace
@@ -735,7 +738,7 @@ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.Operation]:
735738

736739
def _to_trace(self, context: _CirqTraceBuilder, op: cirq.Operation, **_kwargs):
737740
"""Convert this gate into trace instructions."""
738-
if context._memory_compute:
741+
if context._track_memory_qubits:
739742
comp_qs, mem_qs = self._get_qubits(op.qubits)
740743
for i in range(self.n):
741744
yield TraceGate(READ_FROM_MEMORY, [mem_qs[i], comp_qs[i]])
@@ -778,7 +781,7 @@ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.Operation]:
778781

779782
def _to_trace(self, context: _CirqTraceBuilder, op: cirq.Operation, **_kwargs):
780783
"""Convert this gate into trace instructions."""
781-
if context._memory_compute:
784+
if context._track_memory_qubits:
782785
comp_qs, mem_qs = self._get_qubits(op.qubits)
783786
for i in range(self.n):
784787
yield TraceGate(WRITE_TO_MEMORY, [comp_qs[i], mem_qs[i]])

source/pip/tests/qre/test_cirq_interop.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def _make_memory_circuit(*ops):
121121
def test_write_to_memory_memory_compute_true():
122122
"""Test WriteToMemoryGate produces WRITE_TO_MEMORY instructions when memory_compute is True."""
123123
circuit = _make_memory_circuit(write_to_memory)
124-
trace = trace_from_cirq(circuit, memory_compute=True)
124+
trace = trace_from_cirq(circuit, track_memory_qubits=True)
125125

126126
assert trace.compute_qubits == 2
127127
assert trace.memory_qubits == 2
@@ -138,7 +138,7 @@ def test_write_to_memory_memory_compute_true():
138138
def test_write_to_memory_memory_compute_false():
139139
"""Test WriteToMemoryGate decomposes into SWAPs when memory_compute is False."""
140140
circuit = _make_memory_circuit(write_to_memory)
141-
trace = trace_from_cirq(circuit, memory_compute=False)
141+
trace = trace_from_cirq(circuit, track_memory_qubits=False)
142142

143143
assert trace.compute_qubits == 4
144144
assert trace.memory_qubits is None
@@ -155,7 +155,7 @@ def test_write_to_memory_memory_compute_false():
155155
def test_read_from_memory_memory_compute_true():
156156
"""Test ReadFromMemoryGate produces READ_FROM_MEMORY instructions when memory_compute is True."""
157157
circuit = _make_memory_circuit(read_from_memory)
158-
trace = trace_from_cirq(circuit, memory_compute=True)
158+
trace = trace_from_cirq(circuit, track_memory_qubits=True)
159159

160160
assert trace.compute_qubits == 2
161161
assert trace.memory_qubits == 2
@@ -172,7 +172,7 @@ def test_read_from_memory_memory_compute_true():
172172
def test_read_from_memory_memory_compute_false():
173173
"""Test ReadFromMemoryGate decomposes into SWAPs when memory_compute is False."""
174174
circuit = _make_memory_circuit(read_from_memory)
175-
trace = trace_from_cirq(circuit, memory_compute=False)
175+
trace = trace_from_cirq(circuit, track_memory_qubits=False)
176176

177177
assert trace.compute_qubits == 4
178178
assert trace.memory_qubits is None
@@ -189,7 +189,7 @@ def test_read_from_memory_memory_compute_false():
189189
def test_read_write_memory_round_trip_memory_compute_true():
190190
"""Test a write followed by a read produces both instruction types with memory_compute True."""
191191
circuit = _make_memory_circuit(write_to_memory, read_from_memory)
192-
trace = trace_from_cirq(circuit, memory_compute=True)
192+
trace = trace_from_cirq(circuit, track_memory_qubits=True)
193193

194194
assert trace.compute_qubits == 2
195195
assert trace.memory_qubits == 2
@@ -206,7 +206,7 @@ def test_read_write_memory_round_trip_memory_compute_true():
206206
def test_read_write_memory_round_trip_memory_compute_false():
207207
"""Test a write followed by a read decomposes fully with memory_compute False."""
208208
circuit = _make_memory_circuit(write_to_memory, read_from_memory)
209-
trace = trace_from_cirq(circuit, memory_compute=False)
209+
trace = trace_from_cirq(circuit, track_memory_qubits=False)
210210

211211
assert trace.compute_qubits == 4
212212
assert trace.memory_qubits is None
@@ -224,8 +224,8 @@ def test_plain_circuit_unaffected_by_memory_compute():
224224
"""Test that memory_compute has no effect on circuits without memory qubits."""
225225
circuit = cirq.H.on_each(*cirq.LineQubit.range(3))
226226

227-
trace_true = trace_from_cirq(circuit, memory_compute=True)
228-
trace_false = trace_from_cirq(circuit, memory_compute=False)
227+
trace_true = trace_from_cirq(circuit, track_memory_qubits=True)
228+
trace_false = trace_from_cirq(circuit, track_memory_qubits=False)
229229

230230
assert trace_true.compute_qubits == trace_false.compute_qubits == 3
231231
assert trace_true.memory_qubits is None

0 commit comments

Comments
 (0)