Skip to content

Commit 5029af4

Browse files
authored
Do not perform extra optimizations in "via B" decomposition (#3370)
Fixes #3050.
1 parent 0d961ad commit 5029af4

File tree

5 files changed

+41
-13
lines changed

5 files changed

+41
-13
lines changed

cirq/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
decompose_cphase_into_two_fsim,
295295
decompose_multi_controlled_x,
296296
decompose_multi_controlled_rotation,
297+
decompose_two_qubit_interaction_into_four_fsim_gates,
297298
decompose_two_qubit_interaction_into_four_fsim_gates_via_b,
298299
DropEmptyMoments,
299300
DropNegligible,

cirq/optimizers/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,6 @@
6767
two_qubit_matrix_to_operations,)
6868

6969
from cirq.optimizers.two_qubit_to_fsim import (
70-
decompose_two_qubit_interaction_into_four_fsim_gates_via_b,)
70+
decompose_two_qubit_interaction_into_four_fsim_gates,
71+
decompose_two_qubit_interaction_into_four_fsim_gates_via_b,
72+
)

cirq/optimizers/two_qubit_to_fsim.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,32 @@
1313

1414
from cirq import ops, linalg, circuits, devices
1515
from cirq.optimizers import merge_single_qubit_gates, drop_empty_moments
16+
from cirq._compat import deprecated
1617

1718
if TYPE_CHECKING:
1819
import cirq
1920

2021

22+
@deprecated(deadline='v0.10',
23+
fix='Use cirq.decompose_two_qubit_interaction_into_four_fsim_gates.'
24+
)
2125
def decompose_two_qubit_interaction_into_four_fsim_gates_via_b(
2226
interaction: Union['cirq.Operation', 'cirq.Gate', np.ndarray, Any],
2327
*,
2428
fsim_gate: Union['cirq.FSimGate', 'cirq.ISwapPowGate'],
2529
qubits: Sequence['cirq.Qid'] = None) -> 'cirq.Circuit':
30+
circuit = decompose_two_qubit_interaction_into_four_fsim_gates(
31+
interaction, fsim_gate=fsim_gate, qubits=qubits)
32+
merge_single_qubit_gates.MergeSingleQubitGates().optimize_circuit(circuit)
33+
drop_empty_moments.DropEmptyMoments().optimize_circuit(circuit)
34+
return circuit
35+
36+
37+
def decompose_two_qubit_interaction_into_four_fsim_gates(
38+
interaction: Union['cirq.Operation', 'cirq.Gate', np.ndarray, Any],
39+
*,
40+
fsim_gate: Union['cirq.FSimGate', 'cirq.ISwapPowGate'],
41+
qubits: Sequence['cirq.Qid'] = None) -> 'cirq.Circuit':
2642
"""Decomposes operations into an FSimGate near theta=pi/2, phi=0.
2743
2844
This decomposition is guaranteed to use exactly four of the given FSim
@@ -72,19 +88,18 @@ def decompose_two_qubit_interaction_into_four_fsim_gates_via_b(
7288

7389
b_decomposition = _decompose_b_gate_into_two_fsims(fsim_gate=mapped_gate,
7490
qubits=qubits)
75-
result = []
91+
b_decomposition = [
92+
fsim_gate(*op.qubits) if op.gate == mapped_gate else op
93+
for op in b_decomposition
94+
]
95+
96+
result = circuits.Circuit()
7697
for op in result_using_b_gates:
7798
if isinstance(op.gate, _BGate):
78-
result.extend(b_decomposition)
99+
result.append(b_decomposition)
79100
else:
80101
result.append(op)
81-
82-
circuit = circuits.Circuit(
83-
fsim_gate(*op.qubits) if op.gate == mapped_gate else op
84-
for op in result)
85-
merge_single_qubit_gates.MergeSingleQubitGates().optimize_circuit(circuit)
86-
drop_empty_moments.DropEmptyMoments().optimize_circuit(circuit)
87-
return circuit
102+
return result
88103

89104

90105
def _sticky_0_to_1(v: float, *, atol: float) -> Optional[float]:

cirq/optimizers/two_qubit_to_fsim_test.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail():
7676

7777
@pytest.mark.parametrize('obj,fsim_gate',
7878
itertools.product(UNITARY_OBJS, FEASIBLE_FSIM_GATES))
79-
def test_decompose_two_qubit_interaction_into_four_fsim_gates_via_b(
79+
def test_decompose_two_qubit_interaction_into_four_fsim_gates(
8080
obj: Any, fsim_gate: cirq.FSimGate):
8181
qubits = (obj.qubits
8282
if isinstance(obj, cirq.Operation) else cirq.LineQubit.range(2))
83-
circuit = cirq.decompose_two_qubit_interaction_into_four_fsim_gates_via_b(
83+
circuit = cirq.decompose_two_qubit_interaction_into_four_fsim_gates(
8484
obj, fsim_gate=fsim_gate)
8585
desired_unitary = obj if isinstance(obj, np.ndarray) else cirq.unitary(obj)
8686
for operation in circuit.all_operations():
8787
assert len(operation.qubits) < 2 or operation.gate == fsim_gate
88-
assert len(circuit) <= 4 + 5
88+
assert len(circuit) <= 4 * 3 + 5
8989
assert cirq.approx_eq(circuit.unitary(qubit_order=qubits),
9090
desired_unitary,
9191
atol=1e-6)
@@ -151,3 +151,12 @@ def test_sticky_0_to_1():
151151
assert _sticky_0_to_1(2, atol=1e-8) is None
152152

153153
assert _sticky_0_to_1(-0.1, atol=0.5) == 0
154+
155+
156+
def test_deprecated():
157+
iswap = cirq.FSimGate(theta=np.pi / 2, phi=0)
158+
with cirq.testing.assert_logs(
159+
'decompose_two_qubit_interaction_into_four_fsim_gates_via_b',
160+
'deprecated'):
161+
_ = cirq.decompose_two_qubit_interaction_into_four_fsim_gates_via_b(
162+
np.eye(4), fsim_gate=iswap)

rtd_docs/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ Classes and methods for rewriting circuits.
409409

410410
cirq.decompose_multi_controlled_rotation
411411
cirq.decompose_multi_controlled_x
412+
cirq.decompose_two_qubit_interaction_into_four_fsim_gates
412413
cirq.decompose_two_qubit_interaction_into_four_fsim_gates_via_b
413414
cirq.merge_single_qubit_gates_into_phased_x_z
414415
cirq.merge_single_qubit_gates_into_phxz

0 commit comments

Comments
 (0)