From 3e16e15a8296c926691dcf93bca7d63f428cda28 Mon Sep 17 00:00:00 2001 From: Renyi Chen Date: Tue, 7 Jan 2025 13:57:46 -0800 Subject: [PATCH] Apply as_sweep for iswap_gauge, spin_inversion_gauge, sqrt_iswap_gauge (#6911) --- .../gauge_compiling/gauge_compiling.py | 15 ++++++++++----- .../transformers/gauge_compiling/iswap_gauge.py | 8 +++++++- .../gauge_compiling/iswap_gauge_test.py | 1 + .../gauge_compiling/spin_inversion_gauge.py | 4 ++-- .../gauge_compiling/spin_inversion_gauge_test.py | 4 ++++ .../gauge_compiling/sqrt_iswap_gauge.py | 14 ++++++++++++-- .../gauge_compiling/sqrt_iswap_gauge_test.py | 1 + 7 files changed, 37 insertions(+), 10 deletions(-) diff --git a/cirq-core/cirq/transformers/gauge_compiling/gauge_compiling.py b/cirq-core/cirq/transformers/gauge_compiling/gauge_compiling.py index 2e0d5290f51..51915029e1f 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/gauge_compiling.py +++ b/cirq-core/cirq/transformers/gauge_compiling/gauge_compiling.py @@ -118,6 +118,7 @@ class SameGateGauge(Gauge): default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g) ) swap_qubits: bool = False + support_sweep: bool = False def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge: return ConstantGauge( @@ -127,6 +128,7 @@ def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge: post_q0=self.post_q0, post_q1=self.post_q1, swap_qubits=self.swap_qubits, + support_sweep=self.support_sweep, ) @@ -332,6 +334,13 @@ def _parameterize(num_qubits: int, symbol_id: int) -> Dict[str, sympy.Symbol]: def _gate_sequence_to_phxz_params( gates: Tuple[ops.Gate, ...], xza_by_symbols: Dict[str, sympy.Symbol] ) -> Dict[str, float]: + identity_gate_in_phxz = { + str(xza_by_symbols["x_exponent"]): 0.0, + str(xza_by_symbols["z_exponent"]): 0.0, + str(xza_by_symbols["axis_phase_exponent"]): 0.0, + } + if not gates: + return identity_gate_in_phxz for gate in gates: if not has_unitary(gate) or gate.num_qubits() != 1: raise ValueError( @@ -347,11 +356,7 @@ def _gate_sequence_to_phxz_params( or ops.I ) if phxz is ops.I: # Identity gate - return { - str(xza_by_symbols["x_exponent"]): 0.0, - str(xza_by_symbols["z_exponent"]): 0.0, - str(xza_by_symbols["axis_phase_exponent"]): 0.0, - } + return identity_gate_in_phxz # Check the gate type, needs to be a PhasedXZ gate. if not isinstance(phxz, ops.PhasedXZGate): raise ValueError("Failed to convert the gate sequence to a PhasedXZ gate.") diff --git a/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge.py b/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge.py index deaf3fe53bb..5fdb09ee225 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge.py +++ b/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge.py @@ -56,6 +56,7 @@ def _rz(self, theta, sgn: int) -> ConstantGauge: pre_q1=n_rz if flip_diangonal else rz, post_q0=rz if flip_diangonal else n_rz, post_q1=n_rz, + support_sweep=True, ) def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge: @@ -88,7 +89,12 @@ def _xy_gauge(self, a: float, b: float) -> ConstantGauge: xy_a = self._xy(a) xy_b = self._xy(b) return ConstantGauge( - two_qubit_gate=ops.ISWAP, pre_q0=xy_a, pre_q1=xy_b, post_q0=xy_b, post_q1=xy_a + two_qubit_gate=ops.ISWAP, + pre_q0=xy_a, + pre_q1=xy_b, + post_q0=xy_b, + post_q1=xy_a, + support_sweep=True, ) def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge: diff --git a/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge_test.py b/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge_test.py index c5fef2e70ad..bc0e8915066 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge_test.py +++ b/cirq-core/cirq/transformers/gauge_compiling/iswap_gauge_test.py @@ -21,3 +21,4 @@ class TestISWAPGauge(GaugeTester): two_qubit_gate = cirq.ISWAP gauge_transformer = ISWAPGaugeTransformer + sweep_must_pass = True diff --git a/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge.py b/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge.py index 88713ebba80..04f57a55fdc 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge.py +++ b/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge.py @@ -23,8 +23,8 @@ SpinInversionGaugeSelector = GaugeSelector( gauges=[ - SameGateGauge(pre_q0=ops.X, post_q0=ops.X, pre_q1=ops.X, post_q1=ops.X), - SameGateGauge(), + SameGateGauge(pre_q0=ops.X, post_q0=ops.X, pre_q1=ops.X, post_q1=ops.X, support_sweep=True), + SameGateGauge(support_sweep=True), ] ) diff --git a/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py b/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py index c599b328316..6630b37d5b5 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +++ b/cirq-core/cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py @@ -20,18 +20,22 @@ class TestSpinInversionGauge_0(GaugeTester): two_qubit_gate = cirq.ZZ gauge_transformer = SpinInversionGaugeTransformer + sweep_must_pass = True class TestSpinInversionGauge_1(GaugeTester): two_qubit_gate = cirq.ZZ**0.1 gauge_transformer = SpinInversionGaugeTransformer + sweep_must_pass = True class TestSpinInversionGauge_2(GaugeTester): two_qubit_gate = cirq.ZZ**-1 gauge_transformer = SpinInversionGaugeTransformer + sweep_must_pass = True class TestSpinInversionGauge_3(GaugeTester): two_qubit_gate = cirq.ZZ**0.3 gauge_transformer = SpinInversionGaugeTransformer + sweep_must_pass = True diff --git a/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py b/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py index bad1a50f9dc..5181169306b 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +++ b/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py @@ -49,7 +49,12 @@ def _rz(self, theta: float) -> ConstantGauge: rz = ops.rz(theta) n_rz = ops.rz(-theta) return ConstantGauge( - two_qubit_gate=ops.SQRT_ISWAP, pre_q0=rz, pre_q1=rz, post_q0=n_rz, post_q1=n_rz + two_qubit_gate=ops.SQRT_ISWAP, + pre_q0=rz, + pre_q1=rz, + post_q0=n_rz, + post_q1=n_rz, + support_sweep=True, ) def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge: @@ -80,7 +85,12 @@ def _xy(self, theta: float) -> ops.PhasedXZGate: def _xy_gauge(self, theta: float) -> ConstantGauge: xy = self._xy(theta) return ConstantGauge( - two_qubit_gate=ops.SQRT_ISWAP, pre_q0=xy, pre_q1=xy, post_q0=xy, post_q1=xy + two_qubit_gate=ops.SQRT_ISWAP, + pre_q0=xy, + pre_q1=xy, + post_q0=xy, + post_q1=xy, + support_sweep=True, ) def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge: diff --git a/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py b/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py index 2dba48cb6dc..e2778cc0e29 100644 --- a/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +++ b/cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py @@ -20,3 +20,4 @@ class TestSqrtISWAPGauge(GaugeTester): two_qubit_gate = cirq.SQRT_ISWAP gauge_transformer = SqrtISWAPGaugeTransformer + sweep_must_pass = True