Skip to content

Commit 0ef05bc

Browse files
committed
Fix order preservation in align_right
Order was not preserved for non-commutable measurements and controls in the same moment. Reversing the circuit's moments did not reverse the ops within those moments. The subsequent `align_left` could split those ops into separate moments. Then reversing the moments again would have the end result of reversing the order of those operations in the final circuit. This PR makes sure to reverse the order of ops within the moment prior to the call to `align_left`.
1 parent 686766f commit 0ef05bc

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

cirq-core/cirq/transformers/align.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,11 @@ def align_right(
7373
"""
7474
if context is not None and context.deep is True:
7575
context = dataclasses.replace(context, deep=False)
76-
return align_left(circuit[::-1], context=context)[::-1]
76+
backwards = []
77+
for moment in circuit[::-1]:
78+
backwards.append(circuits.Moment(reversed(moment.operations)))
79+
aligned_backwards = align_left(circuits.Circuit(backwards), context=context)
80+
forwards = []
81+
for moment in aligned_backwards[::-1]:
82+
forwards.append(circuits.Moment(reversed(moment.operations)))
83+
return circuits.Circuit(forwards)

cirq-core/cirq/transformers/align_test.py

+13
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,16 @@ def test_classical_control():
208208
)
209209
cirq.testing.assert_same_circuits(cirq.align_left(circuit), circuit)
210210
cirq.testing.assert_same_circuits(cirq.align_right(circuit), circuit)
211+
212+
213+
def test_measurement_and_classical_control_same_moment_preserve_order():
214+
q0, q1 = cirq.LineQubit.range(2)
215+
circuit = cirq.Circuit()
216+
op_measure = cirq.measure(q0, key='m')
217+
op_controlled = cirq.X(q1).with_classical_controls('m')
218+
circuit.append(op_measure)
219+
circuit.append(op_controlled, cirq.InsertStrategy.INLINE)
220+
circuit = cirq.align_right(circuit)
221+
ops_in_order = list(circuit.all_operations())
222+
assert ops_in_order[0] == op_measure
223+
assert ops_in_order[1] == op_controlled

0 commit comments

Comments
 (0)