cirq-core 1.2.0.dev20230717232332__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cirq/__init__.py +5 -0
- cirq/_compat.py +26 -11
- cirq/_compat_test.py +37 -3
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/circuit.py +106 -32
- cirq/circuits/circuit_operation.py +2 -2
- cirq/circuits/circuit_operation_test.py +1 -1
- cirq/circuits/circuit_test.py +109 -3
- cirq/circuits/frozen_circuit.py +80 -5
- cirq/circuits/frozen_circuit_test.py +47 -2
- cirq/circuits/qasm_output_test.py +9 -9
- cirq/conftest.py +1 -2
- cirq/contrib/acquaintance/devices.py +1 -1
- cirq/contrib/hacks/disable_validation_test.py +1 -1
- cirq/contrib/noise_models/noise_models.py +1 -2
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_target_gateset_test.py +4 -4
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -1
- cirq/contrib/quimb/density_matrix.py +2 -3
- cirq/contrib/quimb/grid_circuits.py +3 -3
- cirq/contrib/quimb/state_vector.py +3 -5
- cirq/contrib/routing/utils.py +1 -2
- cirq/contrib/svg/svg.py +4 -6
- cirq/devices/grid_qubit.py +49 -38
- cirq/devices/grid_qubit_test.py +1 -3
- cirq/devices/insertion_noise_model.py +21 -1
- cirq/devices/insertion_noise_model_test.py +6 -0
- cirq/devices/line_qubit.py +67 -40
- cirq/devices/named_topologies.py +8 -14
- cirq/devices/noise_properties.py +1 -1
- cirq/devices/noise_utils.py +7 -5
- cirq/devices/noise_utils_test.py +7 -0
- cirq/experiments/fidelity_estimation_test.py +1 -1
- cirq/experiments/qubit_characterizations.py +6 -5
- cirq/experiments/random_quantum_circuit_generation.py +1 -1
- cirq/experiments/random_quantum_circuit_generation_test.py +28 -1
- cirq/experiments/readout_confusion_matrix.py +6 -6
- cirq/experiments/xeb_fitting.py +3 -5
- cirq/experiments/xeb_fitting_test.py +2 -2
- cirq/experiments/xeb_sampling.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +40 -38
- cirq/json_resolver_cache.py +2 -0
- cirq/linalg/decompositions.py +6 -5
- cirq/ops/__init__.py +2 -0
- cirq/ops/classically_controlled_operation.py +1 -1
- cirq/ops/clifford_gate.py +9 -9
- cirq/ops/clifford_gate_test.py +3 -4
- cirq/ops/common_channels.py +2 -5
- cirq/ops/common_channels_test.py +3 -5
- cirq/ops/common_gates_test.py +7 -7
- cirq/ops/controlled_operation_test.py +2 -2
- cirq/ops/dense_pauli_string.py +3 -0
- cirq/ops/eigen_gate_test.py +1 -3
- cirq/ops/fourier_transform.py +1 -2
- cirq/ops/fsim_gate.py +1 -1
- cirq/ops/gate_features_test.py +2 -2
- cirq/ops/gate_operation_test.py +1 -2
- cirq/ops/greedy_qubit_manager.py +86 -0
- cirq/ops/greedy_qubit_manager_test.py +98 -0
- cirq/ops/linear_combinations.py +1 -1
- cirq/ops/named_qubit.py +55 -18
- cirq/ops/parity_gates.py +65 -18
- cirq/ops/parity_gates_test.py +41 -2
- cirq/ops/pauli_gates.py +2 -2
- cirq/ops/pauli_string.py +3 -4
- cirq/ops/pauli_string_raw_types_test.py +3 -3
- cirq/ops/pauli_string_test.py +3 -4
- cirq/ops/random_gate_channel_test.py +3 -3
- cirq/ops/raw_types.py +1 -1
- cirq/ops/raw_types_test.py +5 -5
- cirq/ops/three_qubit_gates.py +12 -8
- cirq/protocols/act_on_protocol_test.py +9 -9
- cirq/protocols/apply_channel_protocol.py +9 -6
- cirq/protocols/apply_unitary_protocol_test.py +1 -1
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +2 -2
- cirq/protocols/has_stabilizer_effect_protocol.py +52 -6
- cirq/protocols/has_stabilizer_effect_protocol_test.py +21 -8
- cirq/protocols/has_unitary_protocol_test.py +1 -3
- cirq/protocols/json_serialization.py +6 -6
- cirq/protocols/json_serialization_test.py +7 -14
- cirq/protocols/json_test_data/InsertionNoiseModel.json +91 -0
- cirq/protocols/json_test_data/InsertionNoiseModel.repr +4 -0
- cirq/protocols/json_test_data/OpIdentifier.json +45 -10
- cirq/protocols/json_test_data/OpIdentifier.repr +7 -1
- cirq/protocols/json_test_data/spec.py +4 -0
- cirq/protocols/measurement_key_protocol_test.py +1 -1
- cirq/protocols/unitary_protocol_test.py +13 -16
- cirq/qis/clifford_tableau.py +7 -8
- cirq/qis/measures.py +1 -1
- cirq/qis/states.py +2 -3
- cirq/sim/__init__.py +2 -0
- cirq/sim/classical_simulator.py +107 -0
- cirq/sim/classical_simulator_test.py +207 -0
- cirq/sim/clifford/clifford_simulator_test.py +7 -7
- cirq/sim/clifford/stabilizer_simulation_state.py +2 -2
- cirq/sim/clifford/stabilizer_state_ch_form.py +7 -7
- cirq/sim/density_matrix_simulation_state.py +19 -4
- cirq/sim/density_matrix_simulator_test.py +5 -13
- cirq/sim/simulation_state_test.py +13 -14
- cirq/sim/simulator_test.py +6 -9
- cirq/sim/state_vector_simulation_state.py +1 -1
- cirq/study/resolver.py +41 -41
- cirq/study/resolver_test.py +13 -12
- cirq/testing/__init__.py +4 -1
- cirq/testing/circuit_compare.py +1 -1
- cirq/testing/circuit_compare_test.py +11 -11
- cirq/testing/consistent_controlled_gate_op.py +15 -1
- cirq/testing/consistent_controlled_gate_op_test.py +12 -3
- cirq/testing/consistent_decomposition.py +0 -1
- cirq/testing/consistent_protocols.py +6 -1
- cirq/testing/consistent_protocols_test.py +5 -10
- cirq/testing/consistent_qasm.py +2 -4
- cirq/testing/consistent_qasm_test.py +2 -3
- cirq/testing/consistent_specified_has_unitary_test.py +1 -3
- cirq/testing/equals_tester.py +1 -1
- cirq/testing/equals_tester_test.py +5 -5
- cirq/testing/equivalent_repr_eval_test.py +1 -3
- cirq/testing/gate_features_test.py +6 -6
- cirq/testing/order_tester_test.py +1 -3
- cirq/testing/random_circuit_test.py +1 -3
- cirq/transformers/__init__.py +3 -0
- cirq/transformers/analytical_decompositions/__init__.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +1 -2
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +2 -5
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +38 -0
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +18 -0
- cirq/transformers/expand_composite_test.py +4 -4
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +1 -2
- cirq/transformers/merge_k_qubit_gates_test.py +2 -2
- cirq/transformers/qubit_management_transformers.py +177 -0
- cirq/transformers/qubit_management_transformers_test.py +250 -0
- cirq/transformers/routing/route_circuit_cqc.py +23 -4
- cirq/transformers/routing/route_circuit_cqc_test.py +42 -0
- cirq/transformers/stratify.py +10 -11
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +10 -10
- cirq/transformers/target_gatesets/cz_gateset_test.py +8 -10
- cirq/transformers/transformer_primitives.py +138 -28
- cirq/value/abc_alt_test.py +4 -4
- cirq/value/duration.py +68 -37
- cirq/value/duration_test.py +2 -0
- cirq/value/measurement_key_test.py +1 -1
- cirq/value/product_state.py +4 -8
- cirq/value/value_equality_attr.py +12 -5
- cirq/vis/heatmap.py +7 -4
- cirq/vis/heatmap_test.py +14 -4
- cirq/vis/histogram.py +4 -4
- cirq/vis/state_histogram.py +10 -6
- cirq/vis/state_histogram_test.py +2 -0
- cirq/work/observable_measurement_data_test.py +1 -1
- cirq/work/observable_measurement_test.py +2 -2
- cirq/work/zeros_sampler.py +1 -1
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/METADATA +11 -19
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/RECORD +158 -150
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/WHEEL +1 -1
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/top_level.txt +0 -0
|
@@ -20,7 +20,7 @@ import pytest
|
|
|
20
20
|
import cirq
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class
|
|
23
|
+
class ExampleQuantumState(cirq.QuantumStateRepresentation):
|
|
24
24
|
def copy(self, deep_copy_buffers=True):
|
|
25
25
|
pass
|
|
26
26
|
|
|
@@ -28,9 +28,9 @@ class DummyQuantumState(cirq.QuantumStateRepresentation):
|
|
|
28
28
|
pass
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
class
|
|
31
|
+
class ExampleSimulationState(cirq.SimulationState):
|
|
32
32
|
def __init__(self, fallback_result: Any = NotImplemented):
|
|
33
|
-
super().__init__(prng=np.random.RandomState(), state=
|
|
33
|
+
super().__init__(prng=np.random.RandomState(), state=ExampleQuantumState())
|
|
34
34
|
self.fallback_result = fallback_result
|
|
35
35
|
|
|
36
36
|
def _act_on_fallback_(
|
|
@@ -43,18 +43,18 @@ op = cirq.X(cirq.LineQubit(0))
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def test_act_on_fallback_succeeds():
|
|
46
|
-
state =
|
|
46
|
+
state = ExampleSimulationState(fallback_result=True)
|
|
47
47
|
cirq.act_on(op, state)
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def test_act_on_fallback_fails():
|
|
51
|
-
state =
|
|
51
|
+
state = ExampleSimulationState(fallback_result=NotImplemented)
|
|
52
52
|
with pytest.raises(TypeError, match='Failed to act'):
|
|
53
53
|
cirq.act_on(op, state)
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
def test_act_on_fallback_errors():
|
|
57
|
-
state =
|
|
57
|
+
state = ExampleSimulationState(fallback_result=False)
|
|
58
58
|
with pytest.raises(ValueError, match='_act_on_fallback_ must return True or NotImplemented'):
|
|
59
59
|
cirq.act_on(op, state)
|
|
60
60
|
|
|
@@ -71,7 +71,7 @@ def test_act_on_errors():
|
|
|
71
71
|
def _act_on_(self, sim_state):
|
|
72
72
|
return False
|
|
73
73
|
|
|
74
|
-
state =
|
|
74
|
+
state = ExampleSimulationState(fallback_result=True)
|
|
75
75
|
with pytest.raises(ValueError, match='_act_on_ must return True or NotImplemented'):
|
|
76
76
|
cirq.act_on(Op(), state)
|
|
77
77
|
|
|
@@ -85,7 +85,7 @@ def test_qubits_not_allowed_for_operations():
|
|
|
85
85
|
def with_qubits(self, *new_qubits: 'cirq.Qid') -> Self: # type: ignore[empty-body]
|
|
86
86
|
pass
|
|
87
87
|
|
|
88
|
-
state =
|
|
88
|
+
state = ExampleSimulationState()
|
|
89
89
|
with pytest.raises(
|
|
90
90
|
ValueError, match='Calls to act_on should not supply qubits if the action is an Operation'
|
|
91
91
|
):
|
|
@@ -93,6 +93,6 @@ def test_qubits_not_allowed_for_operations():
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
def test_qubits_should_be_defined_for_operations():
|
|
96
|
-
state =
|
|
96
|
+
state = ExampleSimulationState()
|
|
97
97
|
with pytest.raises(ValueError, match='Calls to act_on should'):
|
|
98
98
|
cirq.act_on(cirq.KrausChannel([np.array([[1, 0], [0, 0]])]), state, qubits=None)
|
|
@@ -41,13 +41,16 @@ class ApplyChannelArgs:
|
|
|
41
41
|
r"""Arguments for efficiently performing a channel.
|
|
42
42
|
|
|
43
43
|
A channel performs the mapping
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
|
|
45
|
+
$$
|
|
46
|
+
X \rightarrow \sum_i A_i X A_i^\dagger
|
|
47
|
+
$$
|
|
48
|
+
|
|
47
49
|
for operators $A_i$ that satisfy the normalization condition
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
|
|
51
|
+
$$
|
|
52
|
+
\sum_i A_i^\dagger A_i = I.
|
|
53
|
+
$$
|
|
51
54
|
|
|
52
55
|
The receiving object is expected to mutate `target_tensor` so that it
|
|
53
56
|
contains the density matrix after multiplication, and then return
|
|
@@ -201,7 +201,7 @@ def test_apply_unitary_args_tensor_manipulation():
|
|
|
201
201
|
)
|
|
202
202
|
* 1j
|
|
203
203
|
) # yapf: disable
|
|
204
|
-
# Flatten last two axes and add
|
|
204
|
+
# Flatten last two axes and add another fake index to the end of
|
|
205
205
|
# target_tensor so np.matmul treats it like an array of two-qubit
|
|
206
206
|
# column vectors.
|
|
207
207
|
new_shape = args.target_tensor.shape[:-2] + (4, 1)
|
|
@@ -83,7 +83,7 @@ def test_equal_up_to_global_mixed_array_types():
|
|
|
83
83
|
assert not cirq.equal_up_to_global_phase([], [[]], atol=0.0)
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
#
|
|
86
|
+
# Example container class implementing _equal_up_to_global_phase_
|
|
87
87
|
# for homogeneous comparison, with nontrivial getter.
|
|
88
88
|
class A:
|
|
89
89
|
def __init__(self, val):
|
|
@@ -95,7 +95,7 @@ class A:
|
|
|
95
95
|
return cirq.equal_up_to_global_phase(self.val[0], other.val[0], atol=atol)
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
#
|
|
98
|
+
# Example container class implementing _equal_up_to_global_phase_
|
|
99
99
|
# for heterogeneous comparison.
|
|
100
100
|
class B:
|
|
101
101
|
def __init__(self, val):
|
|
@@ -15,8 +15,18 @@
|
|
|
15
15
|
from typing import Any, Optional
|
|
16
16
|
|
|
17
17
|
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
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
pauli_string_decomposition = LazyLoader(
|
|
26
|
+
"pauli_string_decomposition",
|
|
27
|
+
globals(),
|
|
28
|
+
"cirq.transformers.analytical_decompositions.pauli_string_decomposition",
|
|
29
|
+
)
|
|
20
30
|
|
|
21
31
|
|
|
22
32
|
def has_stabilizer_effect(val: Any) -> bool:
|
|
@@ -29,6 +39,7 @@ def has_stabilizer_effect(val: Any) -> bool:
|
|
|
29
39
|
_strat_has_stabilizer_effect_from_has_stabilizer_effect,
|
|
30
40
|
_strat_has_stabilizer_effect_from_gate,
|
|
31
41
|
_strat_has_stabilizer_effect_from_unitary,
|
|
42
|
+
_strat_has_stabilizer_effect_from_decompose,
|
|
32
43
|
]
|
|
33
44
|
for strat in strats:
|
|
34
45
|
result = strat(val)
|
|
@@ -62,9 +73,44 @@ def _strat_has_stabilizer_effect_from_unitary(val: Any) -> Optional[bool]:
|
|
|
62
73
|
2x2 unitaries.
|
|
63
74
|
"""
|
|
64
75
|
# Do not try this strategy if there is no unitary or if the number of
|
|
65
|
-
# qubits is
|
|
66
|
-
qid_shape =
|
|
67
|
-
if
|
|
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
|
+
):
|
|
68
84
|
return None
|
|
69
|
-
unitary =
|
|
70
|
-
|
|
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
|
|
@@ -49,11 +49,9 @@ class EmptyOp(cirq.Operation):
|
|
|
49
49
|
|
|
50
50
|
@property
|
|
51
51
|
def qubits(self):
|
|
52
|
-
# coverage: ignore
|
|
53
52
|
return (q,)
|
|
54
53
|
|
|
55
|
-
def with_qubits(self, *new_qubits):
|
|
56
|
-
# coverage: ignore
|
|
54
|
+
def with_qubits(self, *new_qubits): # pragma: no cover
|
|
57
55
|
return self
|
|
58
56
|
|
|
59
57
|
|
|
@@ -94,6 +92,10 @@ class OpWithUnitary(EmptyOp):
|
|
|
94
92
|
def _unitary_(self):
|
|
95
93
|
return self.unitary
|
|
96
94
|
|
|
95
|
+
@property
|
|
96
|
+
def qubits(self):
|
|
97
|
+
return cirq.LineQubit.range(self.unitary.shape[0].bit_length() - 1)
|
|
98
|
+
|
|
97
99
|
|
|
98
100
|
def test_inconclusive():
|
|
99
101
|
assert not cirq.has_stabilizer_effect(object())
|
|
@@ -127,9 +129,20 @@ def test_via_unitary():
|
|
|
127
129
|
op3 = OpWithUnitary(np.array([[1, 0], [0, np.sqrt(1j)]]))
|
|
128
130
|
assert not cirq.has_stabilizer_effect(op3)
|
|
129
131
|
|
|
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
|
+
|
|
130
142
|
|
|
131
|
-
def
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
assert not cirq.has_stabilizer_effect(
|
|
135
|
-
|
|
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
|
+
)
|
|
@@ -213,9 +213,7 @@ class EmptyOp(cirq.Operation):
|
|
|
213
213
|
|
|
214
214
|
@property
|
|
215
215
|
def qubits(self):
|
|
216
|
-
# coverage: ignore
|
|
217
216
|
return ()
|
|
218
217
|
|
|
219
|
-
def with_qubits(self, *new_qubits):
|
|
220
|
-
# coverage: ignore
|
|
218
|
+
def with_qubits(self, *new_qubits): # pragma: no cover
|
|
221
219
|
return self
|
|
@@ -113,7 +113,7 @@ def _register_resolver(dict_factory: Callable[[], Dict[str, ObjectFactory]]) ->
|
|
|
113
113
|
class SupportsJSON(Protocol):
|
|
114
114
|
"""An object that can be turned into JSON dictionaries.
|
|
115
115
|
|
|
116
|
-
The magic method _json_dict_ must return a trivially json-serializable
|
|
116
|
+
The magic method `_json_dict_` must return a trivially json-serializable
|
|
117
117
|
type or other objects that support the SupportsJSON protocol.
|
|
118
118
|
|
|
119
119
|
During deserialization, a class must be able to be resolved (see
|
|
@@ -150,7 +150,7 @@ def obj_to_dict_helper(obj: Any, attribute_names: Iterable[str]) -> Dict[str, An
|
|
|
150
150
|
"""Construct a dictionary containing attributes from obj
|
|
151
151
|
|
|
152
152
|
This is useful as a helper function in objects implementing the
|
|
153
|
-
SupportsJSON protocol, particularly in the _json_dict_ method.
|
|
153
|
+
SupportsJSON protocol, particularly in the `_json_dict_` method.
|
|
154
154
|
|
|
155
155
|
In addition to keys and values specified by `attribute_names`, the
|
|
156
156
|
returned dictionary has an additional key "cirq_type" whose value
|
|
@@ -169,7 +169,7 @@ def obj_to_dict_helper(obj: Any, attribute_names: Iterable[str]) -> Dict[str, An
|
|
|
169
169
|
|
|
170
170
|
# pylint: enable=redefined-builtin
|
|
171
171
|
def dataclass_json_dict(obj: Any) -> Dict[str, Any]:
|
|
172
|
-
"""Return a dictionary suitable for _json_dict_ from a dataclass.
|
|
172
|
+
"""Return a dictionary suitable for `_json_dict_` from a dataclass.
|
|
173
173
|
|
|
174
174
|
Dataclasses keep track of their relevant fields, so we can automatically generate these.
|
|
175
175
|
|
|
@@ -303,7 +303,7 @@ class CirqEncoder(json.JSONEncoder):
|
|
|
303
303
|
if isinstance(o, datetime.datetime):
|
|
304
304
|
return {'cirq_type': 'datetime.datetime', 'timestamp': o.timestamp()}
|
|
305
305
|
|
|
306
|
-
return super().default(o) #
|
|
306
|
+
return super().default(o) # pragma: no cover
|
|
307
307
|
|
|
308
308
|
|
|
309
309
|
def _cirq_object_hook(d, resolvers: Sequence[JsonResolver], context_map: Dict[str, Any]):
|
|
@@ -607,7 +607,7 @@ def to_json(
|
|
|
607
607
|
cls: Passed to json.dump; the default value of CirqEncoder
|
|
608
608
|
enables the serialization of Cirq objects which implement
|
|
609
609
|
the SupportsJSON protocol. To support serialization of 3rd
|
|
610
|
-
party classes, prefer adding the _json_dict_ magic method
|
|
610
|
+
party classes, prefer adding the `_json_dict_` magic method
|
|
611
611
|
to your classes rather than overriding this default.
|
|
612
612
|
"""
|
|
613
613
|
if has_serializable_by_keys(obj):
|
|
@@ -631,7 +631,7 @@ def to_json(
|
|
|
631
631
|
return _json_dict_with_cirq_type(candidate.obj)
|
|
632
632
|
else:
|
|
633
633
|
return _json_dict_with_cirq_type(_SerializedKey(candidate.key))
|
|
634
|
-
raise ValueError("Object mutated during serialization.") #
|
|
634
|
+
raise ValueError("Object mutated during serialization.") # pragma: no cover
|
|
635
635
|
|
|
636
636
|
cls = ContextualEncoder
|
|
637
637
|
|
|
@@ -237,7 +237,7 @@ def test_not_yet_serializable_no_superfluous(mod_spec: ModuleJsonTestSpec):
|
|
|
237
237
|
|
|
238
238
|
|
|
239
239
|
@pytest.mark.parametrize('mod_spec', MODULE_TEST_SPECS, ids=repr)
|
|
240
|
-
def
|
|
240
|
+
def test_mutually_exclusive_lists(mod_spec: ModuleJsonTestSpec):
|
|
241
241
|
common = set(mod_spec.should_not_be_serialized) & set(mod_spec.not_yet_serializable)
|
|
242
242
|
assert len(common) == 0, (
|
|
243
243
|
f"Defined in both {mod_spec.name} 'Not yet serializable' "
|
|
@@ -489,8 +489,7 @@ def test_json_test_data_coverage(mod_spec: ModuleJsonTestSpec, cirq_obj_name: st
|
|
|
489
489
|
json_path2 = test_data_path / f'{cirq_obj_name}.json_inward'
|
|
490
490
|
deprecation_deadline = mod_spec.deprecated.get(cirq_obj_name)
|
|
491
491
|
|
|
492
|
-
if not json_path.exists() and not json_path2.exists():
|
|
493
|
-
# coverage: ignore
|
|
492
|
+
if not json_path.exists() and not json_path2.exists(): # pragma: no cover
|
|
494
493
|
pytest.fail(
|
|
495
494
|
f"Hello intrepid developer. There is a new public or "
|
|
496
495
|
f"serializable object named '{cirq_obj_name}' in the module '{mod_spec.name}' "
|
|
@@ -634,10 +633,9 @@ def test_to_from_json_gzip():
|
|
|
634
633
|
def _eval_repr_data_file(path: pathlib.Path, deprecation_deadline: Optional[str]):
|
|
635
634
|
content = path.read_text()
|
|
636
635
|
ctx_managers: List[contextlib.AbstractContextManager] = [contextlib.suppress()]
|
|
637
|
-
if deprecation_deadline:
|
|
636
|
+
if deprecation_deadline: # pragma: no cover
|
|
638
637
|
# we ignore coverage here, because sometimes there are no deprecations at all in any of the
|
|
639
638
|
# modules
|
|
640
|
-
# coverage: ignore
|
|
641
639
|
ctx_managers = [cirq.testing.assert_deprecated(deadline=deprecation_deadline, count=None)]
|
|
642
640
|
|
|
643
641
|
for deprecation in TESTED_MODULES.values():
|
|
@@ -681,12 +679,10 @@ def assert_repr_and_json_test_data_agree(
|
|
|
681
679
|
)
|
|
682
680
|
with ctx_manager:
|
|
683
681
|
json_obj = cirq.read_json(json_text=json_from_file)
|
|
684
|
-
except ValueError as ex: #
|
|
685
|
-
# coverage: ignore
|
|
682
|
+
except ValueError as ex: # pragma: no cover
|
|
686
683
|
if "Could not resolve type" in str(ex):
|
|
687
684
|
mod_path = mod_spec.name.replace(".", "/")
|
|
688
685
|
rel_resolver_cache_path = f"{mod_path}/json_resolver_cache.py"
|
|
689
|
-
# coverage: ignore
|
|
690
686
|
pytest.fail(
|
|
691
687
|
f"{rel_json_path} can't be parsed to JSON.\n"
|
|
692
688
|
f"Maybe an entry is missing from the "
|
|
@@ -694,17 +690,14 @@ def assert_repr_and_json_test_data_agree(
|
|
|
694
690
|
)
|
|
695
691
|
else:
|
|
696
692
|
raise ValueError(f"deprecation: {deprecation_deadline} - got error: {ex}")
|
|
697
|
-
except AssertionError as ex: #
|
|
698
|
-
# coverage: ignore
|
|
693
|
+
except AssertionError as ex: # pragma: no cover
|
|
699
694
|
raise ex
|
|
700
|
-
except Exception as ex: #
|
|
701
|
-
# coverage: ignore
|
|
695
|
+
except Exception as ex: # pragma: no cover
|
|
702
696
|
raise IOError(f'Failed to parse test json data from {rel_json_path}.') from ex
|
|
703
697
|
|
|
704
698
|
try:
|
|
705
699
|
repr_obj = _eval_repr_data_file(repr_path, deprecation_deadline)
|
|
706
|
-
except Exception as ex: #
|
|
707
|
-
# coverage: ignore
|
|
700
|
+
except Exception as ex: # pragma: no cover
|
|
708
701
|
raise IOError(f'Failed to parse test repr data from {rel_repr_path}.') from ex
|
|
709
702
|
|
|
710
703
|
assert proper_eq(json_obj, repr_obj), (
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"cirq_type": "InsertionNoiseModel",
|
|
4
|
+
"ops_added": [
|
|
5
|
+
[
|
|
6
|
+
{
|
|
7
|
+
"cirq_type": "OpIdentifier",
|
|
8
|
+
"gate_type": "XPowGate",
|
|
9
|
+
"qubits": [
|
|
10
|
+
{
|
|
11
|
+
"cirq_type": "LineQubit",
|
|
12
|
+
"x": 0
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"cirq_type": "GateOperation",
|
|
18
|
+
"gate": {
|
|
19
|
+
"cirq_type": "BitFlipChannel",
|
|
20
|
+
"p": 0.2
|
|
21
|
+
},
|
|
22
|
+
"qubits": [
|
|
23
|
+
{
|
|
24
|
+
"cirq_type": "LineQubit",
|
|
25
|
+
"x": 0
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
],
|
|
31
|
+
"prepend": false,
|
|
32
|
+
"require_physical_tag": false
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"cirq_type": "InsertionNoiseModel",
|
|
36
|
+
"ops_added": [
|
|
37
|
+
[
|
|
38
|
+
{
|
|
39
|
+
"cirq_type": "OpIdentifier",
|
|
40
|
+
"gate_type": "XPowGate",
|
|
41
|
+
"qubits": [
|
|
42
|
+
{
|
|
43
|
+
"cirq_type": "LineQubit",
|
|
44
|
+
"x": 0
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"cirq_type": "GateOperation",
|
|
50
|
+
"gate": {
|
|
51
|
+
"cirq_type": "BitFlipChannel",
|
|
52
|
+
"p": 0.2
|
|
53
|
+
},
|
|
54
|
+
"qubits": [
|
|
55
|
+
{
|
|
56
|
+
"cirq_type": "LineQubit",
|
|
57
|
+
"x": 0
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
{
|
|
64
|
+
"cirq_type": "OpIdentifier",
|
|
65
|
+
"gate_type": "HPowGate",
|
|
66
|
+
"qubits": [
|
|
67
|
+
{
|
|
68
|
+
"cirq_type": "LineQubit",
|
|
69
|
+
"x": 1
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"cirq_type": "GateOperation",
|
|
75
|
+
"gate": {
|
|
76
|
+
"cirq_type": "BitFlipChannel",
|
|
77
|
+
"p": 0.1
|
|
78
|
+
},
|
|
79
|
+
"qubits": [
|
|
80
|
+
{
|
|
81
|
+
"cirq_type": "LineQubit",
|
|
82
|
+
"x": 1
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
],
|
|
88
|
+
"prepend": false,
|
|
89
|
+
"require_physical_tag": false
|
|
90
|
+
}
|
|
91
|
+
]
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
[
|
|
2
|
+
cirq.devices.InsertionNoiseModel(ops_added={cirq.devices.noise_utils.OpIdentifier(cirq.ops.common_gates.XPowGate, cirq.LineQubit(0)): cirq.bit_flip(p=0.2).on(cirq.LineQubit(0))}, prepend=False, require_physical_tag=False),
|
|
3
|
+
cirq.devices.InsertionNoiseModel(ops_added={cirq.devices.noise_utils.OpIdentifier(cirq.ops.common_gates.XPowGate, cirq.LineQubit(0)): cirq.bit_flip(p=0.2).on(cirq.LineQubit(0)), cirq.devices.noise_utils.OpIdentifier(cirq.ops.common_gates.HPowGate, cirq.LineQubit(1)): cirq.bit_flip(p=0.1).on(cirq.LineQubit(1))}, prepend=False, require_physical_tag=False)
|
|
4
|
+
]
|
|
@@ -1,10 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"cirq_type": "OpIdentifier",
|
|
4
|
+
"gate_type": "XPowGate",
|
|
5
|
+
"qubits": [
|
|
6
|
+
{
|
|
7
|
+
"cirq_type": "LineQubit",
|
|
8
|
+
"x": 1
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"cirq_type": "OpIdentifier",
|
|
14
|
+
"gate_type": {
|
|
15
|
+
"cirq_type": "CliffordGate",
|
|
16
|
+
"n": 1,
|
|
17
|
+
"rs": [
|
|
18
|
+
false,
|
|
19
|
+
false
|
|
20
|
+
],
|
|
21
|
+
"xs": [
|
|
22
|
+
[
|
|
23
|
+
true
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
false
|
|
27
|
+
]
|
|
28
|
+
],
|
|
29
|
+
"zs": [
|
|
30
|
+
[
|
|
31
|
+
false
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
true
|
|
35
|
+
]
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"qubits": [
|
|
39
|
+
{
|
|
40
|
+
"cirq_type": "LineQubit",
|
|
41
|
+
"x": 0
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
]
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
[
|
|
1
2
|
cirq.devices.noise_utils.OpIdentifier(
|
|
2
3
|
cirq.ops.common_gates.XPowGate,
|
|
3
4
|
cirq.LineQubit(1)
|
|
4
|
-
)
|
|
5
|
+
),
|
|
6
|
+
cirq.devices.noise_utils.OpIdentifier(
|
|
7
|
+
cirq.CliffordGate.from_clifford_tableau(cirq.CliffordTableau(1,rs=np.array([False, False],dtype=np.dtype('bool')), xs=np.array([[True], [False]], dtype=np.dtype('bool')),zs=np.array([[False], [True]], dtype=np.dtype('bool')), initial_state=0)),
|
|
8
|
+
cirq.LineQubit(0)
|
|
9
|
+
)
|
|
10
|
+
]
|
|
@@ -58,6 +58,7 @@ TestSpec = ModuleJsonTestSpec(
|
|
|
58
58
|
'ZerosSampler',
|
|
59
59
|
],
|
|
60
60
|
should_not_be_serialized=[
|
|
61
|
+
'ClassicalStateSimulator',
|
|
61
62
|
# Heatmaps
|
|
62
63
|
'Heatmap',
|
|
63
64
|
'TwoQubitInteractionHeatmap',
|
|
@@ -89,6 +90,9 @@ TestSpec = ModuleJsonTestSpec(
|
|
|
89
90
|
'LineInitialMapper',
|
|
90
91
|
'MappingManager',
|
|
91
92
|
'RouteCQC',
|
|
93
|
+
# Qubit Managers,
|
|
94
|
+
'SimpleQubitManager',
|
|
95
|
+
'GreedyQubitManager',
|
|
92
96
|
# global objects
|
|
93
97
|
'CONTROL_TAG',
|
|
94
98
|
'PAULI_BASIS',
|
|
@@ -64,7 +64,7 @@ class ReturnsMatrix(cirq.Gate):
|
|
|
64
64
|
return m1
|
|
65
65
|
|
|
66
66
|
def num_qubits(self):
|
|
67
|
-
return 1 #
|
|
67
|
+
return 1 # pragma: no cover
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
class FullyImplemented(cirq.Gate):
|
|
@@ -131,7 +131,7 @@ class DecomposableNoUnitary(cirq.Operation):
|
|
|
131
131
|
yield ReturnsNotImplemented()(q)
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
class
|
|
134
|
+
class ExampleOperation(cirq.Operation):
|
|
135
135
|
qubits = ()
|
|
136
136
|
with_qubits = NotImplemented
|
|
137
137
|
|
|
@@ -142,7 +142,7 @@ class DummyOperation(cirq.Operation):
|
|
|
142
142
|
return ()
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
class
|
|
145
|
+
class ExampleComposite:
|
|
146
146
|
def _decompose_(self):
|
|
147
147
|
return ()
|
|
148
148
|
|
|
@@ -209,7 +209,6 @@ def _test_gate_that_allocates_qubits(gate):
|
|
|
209
209
|
def test_decompose_gate_that_allocates_clean_qubits(
|
|
210
210
|
theta: float, phase_state: int, target_bitsize: int, ancilla_bitsize: int
|
|
211
211
|
):
|
|
212
|
-
|
|
213
212
|
gate = testing.PhaseUsingCleanAncilla(theta, phase_state, target_bitsize, ancilla_bitsize)
|
|
214
213
|
_test_gate_that_allocates_qubits(gate)
|
|
215
214
|
|
|
@@ -220,7 +219,6 @@ def test_decompose_gate_that_allocates_clean_qubits(
|
|
|
220
219
|
def test_decompose_gate_that_allocates_dirty_qubits(
|
|
221
220
|
phase_state: int, target_bitsize: int, ancilla_bitsize: int
|
|
222
221
|
):
|
|
223
|
-
|
|
224
222
|
gate = testing.PhaseUsingDirtyAncilla(phase_state, target_bitsize, ancilla_bitsize)
|
|
225
223
|
_test_gate_that_allocates_qubits(gate)
|
|
226
224
|
|
|
@@ -233,9 +231,9 @@ def test_decompose_and_get_unitary():
|
|
|
233
231
|
_strat_unitary_from_decompose(DecomposableOperation((a, b), True)), m2
|
|
234
232
|
)
|
|
235
233
|
np.testing.assert_allclose(_strat_unitary_from_decompose(DecomposableOrder((a, b, c))), m3)
|
|
236
|
-
np.testing.assert_allclose(_strat_unitary_from_decompose(
|
|
237
|
-
np.testing.assert_allclose(_strat_unitary_from_decompose(
|
|
238
|
-
np.testing.assert_allclose(_strat_unitary_from_decompose(
|
|
234
|
+
np.testing.assert_allclose(_strat_unitary_from_decompose(ExampleOperation((a,))), np.eye(2))
|
|
235
|
+
np.testing.assert_allclose(_strat_unitary_from_decompose(ExampleOperation((a, b))), np.eye(4))
|
|
236
|
+
np.testing.assert_allclose(_strat_unitary_from_decompose(ExampleComposite()), np.eye(1))
|
|
239
237
|
np.testing.assert_allclose(_strat_unitary_from_decompose(OtherComposite()), m2)
|
|
240
238
|
|
|
241
239
|
|
|
@@ -250,11 +248,11 @@ def test_decomposed_has_unitary():
|
|
|
250
248
|
|
|
251
249
|
# Operations
|
|
252
250
|
assert cirq.has_unitary(DecomposableOperation((a, b), True))
|
|
253
|
-
assert cirq.has_unitary(
|
|
254
|
-
assert cirq.has_unitary(
|
|
251
|
+
assert cirq.has_unitary(ExampleOperation((a,)))
|
|
252
|
+
assert cirq.has_unitary(ExampleOperation((a, b)))
|
|
255
253
|
|
|
256
254
|
# No qid shape
|
|
257
|
-
assert cirq.has_unitary(
|
|
255
|
+
assert cirq.has_unitary(ExampleComposite())
|
|
258
256
|
assert cirq.has_unitary(OtherComposite())
|
|
259
257
|
|
|
260
258
|
|
|
@@ -269,12 +267,12 @@ def test_decomposed_unitary():
|
|
|
269
267
|
np.testing.assert_allclose(cirq.unitary(DecomposableOperation((a,), True)), m1)
|
|
270
268
|
np.testing.assert_allclose(cirq.unitary(DecomposableOperation((a, b), True)), m2)
|
|
271
269
|
np.testing.assert_allclose(cirq.unitary(DecomposableOrder((a, b, c))), m3)
|
|
272
|
-
np.testing.assert_allclose(cirq.unitary(
|
|
273
|
-
np.testing.assert_allclose(cirq.unitary(
|
|
270
|
+
np.testing.assert_allclose(cirq.unitary(ExampleOperation((a,))), np.eye(2))
|
|
271
|
+
np.testing.assert_allclose(cirq.unitary(ExampleOperation((a, b))), np.eye(4))
|
|
274
272
|
assert cirq.unitary(DecomposableNoUnitary((a,)), None) is None
|
|
275
273
|
|
|
276
274
|
# No qid shape
|
|
277
|
-
np.testing.assert_allclose(cirq.unitary(
|
|
275
|
+
np.testing.assert_allclose(cirq.unitary(ExampleComposite()), np.eye(1))
|
|
278
276
|
np.testing.assert_allclose(cirq.unitary(OtherComposite()), m2)
|
|
279
277
|
|
|
280
278
|
|
|
@@ -305,8 +303,7 @@ def test_unitary_from_apply_unitary():
|
|
|
305
303
|
def qubits(self):
|
|
306
304
|
return (self.q,)
|
|
307
305
|
|
|
308
|
-
def with_qubits(self, *new_qubits):
|
|
309
|
-
# coverage: ignore
|
|
306
|
+
def with_qubits(self, *new_qubits): # pragma: no cover
|
|
310
307
|
return ApplyOp(*new_qubits)
|
|
311
308
|
|
|
312
309
|
def _apply_unitary_(self, args):
|