Skip to content

Commit e49b003

Browse files
authored
Merge branch 'master' into no-new-browser-tab-from-tests
2 parents e0ef2d6 + fec68ae commit e49b003

18 files changed

+112
-19
lines changed

.github/workflows/ci-daily.yml

+3-4
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,9 @@ jobs:
5858
- name: Install requirements
5959
run: |
6060
pip install --pre cirq &&
61-
pip install \
62-
-r dev_tools/requirements/deps/format.txt \
63-
-r dev_tools/requirements/deps/pylint.txt \
64-
-r dev_tools/requirements/deps/pytest.txt
61+
pip install -r dev_tools/requirements/deps/format.txt &&
62+
pip install -r dev_tools/requirements/deps/pylint.txt &&
63+
pip install -r dev_tools/requirements/deps/pytest.txt
6564
- name: Pytest Windows
6665
run: check/pytest -n auto --ignore=cirq-core/cirq/contrib --enable-slow-tests
6766
shell: bash

.github/workflows/ci.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ jobs:
168168
- name: Run Quil dependencies
169169
run: docker-compose -f cirq-rigetti/docker-compose.test.yaml up -d
170170
- name: Pytest check
171-
run: check/pytest -n auto --ignore=cirq-core/cirq/contrib --rigetti-integration
171+
run: check/pytest -n auto --durations=20 --ignore=cirq-core/cirq/contrib --rigetti-integration
172172
- name: Stop Quil dependencies
173173
run: docker-compose -f cirq-rigetti/docker-compose.test.yaml down
174174
pip-compile:
@@ -265,7 +265,7 @@ jobs:
265265
- name: Pytest Windows
266266
run: |
267267
source dev_tools/pypath
268-
check/pytest -n auto --ignore=cirq-core/cirq/contrib
268+
check/pytest -n auto --durations=20 --ignore=cirq-core/cirq/contrib
269269
shell: bash
270270
macos:
271271
name: Pytest MacOS
@@ -288,7 +288,7 @@ jobs:
288288
pip install wheel
289289
pip install --upgrade --upgrade-strategy eager -r dev_tools/requirements/no-contrib.env.txt
290290
- name: Pytest check
291-
run: check/pytest -n auto --ignore=cirq-core/cirq/contrib
291+
run: check/pytest -n auto --durations=20 --ignore=cirq-core/cirq/contrib
292292
notebooks-stable:
293293
name: Changed Notebooks Isolated Test against Cirq stable
294294
env:

cirq-core/cirq/protocols/has_stabilizer_effect_protocol.py

+52-6
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,18 @@
1515
from typing import Any, Optional
1616

1717
from cirq.ops.clifford_gate import SingleQubitCliffordGate
18+
from cirq.ops.dense_pauli_string import DensePauliString
19+
from cirq._import import LazyLoader
20+
import cirq.protocols.unitary_protocol as unitary_protocol
21+
import cirq.protocols.has_unitary_protocol as has_unitary_protocol
22+
import cirq.protocols.qid_shape_protocol as qid_shape_protocol
23+
import cirq.protocols.decompose_protocol as decompose_protocol
1824

19-
from cirq import protocols
25+
pauli_string_decomposition = LazyLoader(
26+
"pauli_string_decomposition",
27+
globals(),
28+
"cirq.transformers.analytical_decompositions.pauli_string_decomposition",
29+
)
2030

2131

2232
def has_stabilizer_effect(val: Any) -> bool:
@@ -29,6 +39,7 @@ def has_stabilizer_effect(val: Any) -> bool:
2939
_strat_has_stabilizer_effect_from_has_stabilizer_effect,
3040
_strat_has_stabilizer_effect_from_gate,
3141
_strat_has_stabilizer_effect_from_unitary,
42+
_strat_has_stabilizer_effect_from_decompose,
3243
]
3344
for strat in strats:
3445
result = strat(val)
@@ -62,9 +73,44 @@ def _strat_has_stabilizer_effect_from_unitary(val: Any) -> Optional[bool]:
6273
2x2 unitaries.
6374
"""
6475
# Do not try this strategy if there is no unitary or if the number of
65-
# qubits is not 1 since that would be expensive.
66-
qid_shape = protocols.qid_shape(val, default=None)
67-
if qid_shape is None or len(qid_shape) != 1 or not protocols.has_unitary(val):
76+
# qubits is greater than 3 since that would be expensive.
77+
qid_shape = qid_shape_protocol.qid_shape(val, default=None)
78+
if (
79+
qid_shape is None
80+
or len(qid_shape) > 3
81+
or qid_shape != (2,) * len(qid_shape)
82+
or not has_unitary_protocol.has_unitary(val)
83+
):
6884
return None
69-
unitary = protocols.unitary(val)
70-
return SingleQubitCliffordGate.from_unitary(unitary) is not None
85+
unitary = unitary_protocol.unitary(val)
86+
if len(qid_shape) == 1:
87+
return SingleQubitCliffordGate.from_unitary(unitary) is not None
88+
89+
# Check if the action of the unitary on each single qubit pauli string leads to a pauli product.
90+
# Source: https://quantumcomputing.stackexchange.com/a/13158
91+
for q_idx in range(len(qid_shape)):
92+
for g in 'XZ':
93+
pauli_string = ['I'] * len(qid_shape)
94+
pauli_string[q_idx] = g
95+
ps = DensePauliString(pauli_string)
96+
p = ps._unitary_()
97+
if not pauli_string_decomposition.unitary_to_pauli_string(
98+
(unitary @ p @ unitary.T.conj())
99+
):
100+
return False
101+
return True
102+
103+
104+
def _strat_has_stabilizer_effect_from_decompose(val: Any) -> Optional[bool]:
105+
qid_shape = qid_shape_protocol.qid_shape(val, default=None)
106+
if qid_shape is None or len(qid_shape) <= 3:
107+
return None
108+
109+
decomposition = decompose_protocol.decompose_once(val, default=None)
110+
if decomposition is None:
111+
return None
112+
for op in decomposition:
113+
res = has_stabilizer_effect(op)
114+
if not res:
115+
return res
116+
return True

cirq-core/cirq/protocols/has_stabilizer_effect_protocol_test.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ def __init__(self, unitary):
9292
def _unitary_(self):
9393
return self.unitary
9494

95+
@property
96+
def qubits(self):
97+
return cirq.LineQubit.range(self.unitary.shape[0].bit_length() - 1)
98+
9599

96100
def test_inconclusive():
97101
assert not cirq.has_stabilizer_effect(object())
@@ -125,9 +129,20 @@ def test_via_unitary():
125129
op3 = OpWithUnitary(np.array([[1, 0], [0, np.sqrt(1j)]]))
126130
assert not cirq.has_stabilizer_effect(op3)
127131

132+
# 2+ qubit cliffords
133+
assert cirq.has_stabilizer_effect(cirq.CNOT)
134+
assert cirq.has_stabilizer_effect(cirq.XX)
135+
assert cirq.has_stabilizer_effect(cirq.ZZ)
136+
137+
# Non Cliffords
138+
assert not cirq.has_stabilizer_effect(cirq.T)
139+
assert not cirq.has_stabilizer_effect(cirq.CCNOT)
140+
assert not cirq.has_stabilizer_effect(cirq.CCZ)
141+
128142

129-
def test_via_unitary_not_supported():
130-
# Unitaries larger than 2x2 are not yet supported.
131-
op = OpWithUnitary(cirq.unitary(cirq.CNOT))
132-
assert not cirq.has_stabilizer_effect(op)
133-
assert not cirq.has_stabilizer_effect(op)
143+
def test_via_decompose():
144+
assert cirq.has_stabilizer_effect(cirq.Circuit(cirq.H.on_each(cirq.LineQubit.range(4))))
145+
assert not cirq.has_stabilizer_effect(cirq.Circuit(cirq.T.on_each(cirq.LineQubit.range(4))))
146+
assert not cirq.has_stabilizer_effect(
147+
OpWithUnitary(cirq.unitary(cirq.Circuit(cirq.T.on_each(cirq.LineQubit.range(4)))))
148+
)

cirq-ft/cirq_ft/algos/and_gate_test.py

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import itertools
1616
import random
17+
import sys
1718
from typing import List, Tuple
1819

1920
import cirq
@@ -203,6 +204,7 @@ def test_and_gate_adjoint(cv: Tuple[int, int]):
203204
cirq_ft.testing.assert_circuit_inp_out_cirqsim(circuit, [c1, c2, t], inp, out)
204205

205206

207+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
206208
def test_notebook():
207209
execute_notebook('and_gate')
208210

cirq-ft/cirq_ft/algos/apply_gate_to_lth_target_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import cirq
1618
import cirq_ft
1719
import pytest
@@ -101,5 +103,6 @@ def test_apply_gate_to_lth_qubit_make_on():
101103
assert op.gate.control_regs == op2.gate.control_regs
102104

103105

106+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
104107
def test_notebook():
105108
execute_notebook('apply_gate_to_lth_target')

cirq-ft/cirq_ft/algos/generic_select_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
15+
import sys
1416
from typing import List, Sequence
1517

1618
import cirq
@@ -276,5 +278,6 @@ def test_generic_select_consistent_protocols_and_controlled():
276278
_ = gate.controlled(num_controls=2)
277279

278280

281+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
279282
def test_notebook():
280283
execute_notebook('generic_select')

cirq-ft/cirq_ft/algos/hubbard_model_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import cirq
1618
import cirq_ft
1719
import pytest
@@ -72,5 +74,6 @@ def test_hubbard_model_consistent_protocols():
7274
assert cirq.circuit_diagram_info(select_gate).wire_symbols == tuple(expected_symbols)
7375

7476

77+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
7578
def test_notebook():
7679
execute_notebook('hubbard_model')

cirq-ft/cirq_ft/algos/qrom_test.py

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import itertools
16+
import sys
1617

1718
import cirq
1819
import cirq_ft
@@ -114,6 +115,7 @@ def test_qrom_repr():
114115
cirq.testing.assert_equivalent_repr(qrom, setup_code="import cirq_ft\nimport numpy as np")
115116

116117

118+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
117119
def test_notebook():
118120
execute_notebook('qrom')
119121

cirq-ft/cirq_ft/algos/qubitization_walk_operator_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import cirq
1618
import cirq_ft
1719
import numpy as np
@@ -240,6 +242,7 @@ def test_qubitization_walk_operator_consistent_protocols_and_controlled():
240242
_ = gate.controlled(num_controls=2)
241243

242244

245+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
243246
def test_notebook():
244247
execute_notebook('qubitization_walk_operator')
245248
execute_notebook('phase_estimation_of_quantum_walk')

cirq-ft/cirq_ft/algos/state_preparation_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import cirq
1618
import cirq_ft
1719
import numpy as np
@@ -93,5 +95,6 @@ def test_state_preparation_via_coherent_alias_sampling_diagram():
9395
)
9496

9597

98+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
9699
def test_notebook():
97100
execute_notebook('state_preparation')

cirq-ft/cirq_ft/algos/swap_network_test.py

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import random
16+
import sys
1617

1718
import cirq
1819
import cirq_ft
@@ -146,6 +147,7 @@ def test_multi_target_cswap_make_on():
146147
assert cswap1 == cswap2
147148

148149

150+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
149151
def test_notebook():
150152
execute_notebook('swap_network')
151153

cirq-ft/cirq_ft/algos/unary_iteration_gate_test.py

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import itertools
16+
import sys
1617
from typing import Sequence, Tuple
1718

1819
import cirq
@@ -198,5 +199,6 @@ def test_unary_iteration_loop_empty_range():
198199
assert list(cirq_ft.unary_iteration(4, 3, [], [], [cirq.q('s')], qm)) == []
199200

200201

202+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
201203
def test_notebook():
202204
execute_notebook('unary_iteration')

cirq-ft/cirq_ft/infra/gate_with_registers_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import cirq
1618
import cirq_ft
1719
import numpy as np
@@ -169,5 +171,6 @@ def test_gate_with_registers():
169171
assert op1 == op2
170172

171173

174+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
172175
def test_notebook():
173176
execute_notebook('gate_with_registers')

cirq-ft/cirq_ft/infra/t_complexity_protocol.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def _is_clifford_or_t(stc: Any, fail_quietly: bool) -> Optional[TComplexity]:
8181
if isinstance(stc, cirq.ClassicallyControlledOperation):
8282
stc = stc.without_classical_controls()
8383

84-
if cirq.has_stabilizer_effect(stc):
84+
if cirq.num_qubits(stc) <= 2 and cirq.has_stabilizer_effect(stc):
8585
# Clifford operation.
8686
return TComplexity(clifford=1)
8787

cirq-ft/cirq_ft/infra/t_complexity_protocol_test.py

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import sys
16+
1517
import cirq
1618
import cirq_ft
1719
import pytest
@@ -207,5 +209,6 @@ def gate(self):
207209
cirq_ft.t_complexity.cache_clear()
208210

209211

212+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
210213
def test_notebook():
211214
execute_notebook('t_complexity')

dev_tools/notebooks/notebook_test.py

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import importlib.metadata
2323
import os
24+
import sys
2425
import tempfile
2526

2627
import pytest
@@ -86,6 +87,7 @@ def env_with_temporary_pip_target():
8687

8788

8889
@pytest.mark.slow
90+
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
8991
@pytest.mark.parametrize("notebook_path", filter_notebooks(list_all_notebooks(), SKIP_NOTEBOOKS))
9092
def test_notebooks_against_cirq_head(
9193
notebook_path, require_packages_not_changed, env_with_temporary_pip_target

dev_tools/packaging/isolated_packages_test.py

+2
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121

2222
from dev_tools import shell_tools
2323
from dev_tools.modules import list_modules
24+
from dev_tools.test_utils import only_on_posix
2425

2526
PACKAGES = ["-r", "dev_tools/requirements/isolated-base.env.txt"]
2627

2728

29+
@only_on_posix
2830
@pytest.mark.slow
2931
# ensure that no cirq packages are on the PYTHONPATH, this is important, otherwise
3032
# the "isolation" fails and for example cirq-core would be on the PATH

0 commit comments

Comments
 (0)