cirq-core 1.1.0.dev20221220224914__py3-none-any.whl → 1.2.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 +8 -0
- cirq/_compat.py +29 -4
- cirq/_compat_test.py +24 -26
- cirq/_version.py +32 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/_block_diagram_drawer_test.py +4 -3
- cirq/circuits/circuit.py +109 -63
- cirq/circuits/circuit_operation.py +2 -3
- cirq/circuits/circuit_operation_test.py +4 -4
- cirq/circuits/circuit_test.py +11 -0
- cirq/circuits/frozen_circuit.py +13 -1
- cirq/circuits/frozen_circuit_test.py +5 -1
- cirq/circuits/moment.py +39 -14
- cirq/circuits/moment_test.py +7 -0
- cirq/circuits/text_diagram_drawer.py +1 -1
- cirq/circuits/text_diagram_drawer_test.py +3 -7
- cirq/contrib/acquaintance/bipartite.py +1 -1
- cirq/contrib/acquaintance/devices.py +2 -2
- cirq/contrib/acquaintance/executor.py +5 -2
- cirq/contrib/acquaintance/gates.py +3 -2
- cirq/contrib/acquaintance/permutation.py +13 -2
- cirq/contrib/acquaintance/testing.py +3 -5
- cirq/contrib/paulistring/recombine.py +3 -6
- cirq/contrib/qasm_import/_parser.py +17 -21
- cirq/contrib/qasm_import/_parser_test.py +30 -45
- cirq/contrib/qcircuit/qcircuit_test.py +3 -7
- cirq/contrib/quantum_volume/quantum_volume.py +3 -3
- cirq/contrib/quimb/mps_simulator.py +1 -1
- cirq/contrib/quimb/state_vector.py +2 -0
- cirq/contrib/quirk/quirk_gate.py +1 -0
- cirq/contrib/svg/svg.py +4 -7
- cirq/contrib/svg/svg_test.py +29 -1
- cirq/devices/grid_qubit.py +26 -28
- cirq/devices/grid_qubit_test.py +21 -5
- cirq/devices/line_qubit.py +10 -12
- cirq/devices/line_qubit_test.py +9 -2
- cirq/devices/named_topologies.py +1 -1
- cirq/devices/noise_model.py +4 -1
- cirq/devices/superconducting_qubits_noise_properties.py +1 -3
- cirq/experiments/n_qubit_tomography.py +1 -1
- cirq/experiments/qubit_characterizations.py +2 -2
- cirq/experiments/single_qubit_readout_calibration.py +1 -1
- cirq/experiments/t2_decay_experiment.py +1 -1
- cirq/experiments/xeb_simulation_test.py +2 -2
- cirq/interop/quirk/cells/testing.py +1 -1
- cirq/json_resolver_cache.py +1 -0
- cirq/linalg/__init__.py +2 -0
- cirq/linalg/decompositions_test.py +4 -4
- cirq/linalg/diagonalize_test.py +5 -6
- cirq/linalg/transformations.py +72 -9
- cirq/linalg/transformations_test.py +23 -7
- cirq/ops/__init__.py +4 -0
- cirq/ops/arithmetic_operation.py +4 -6
- cirq/ops/classically_controlled_operation.py +10 -3
- cirq/ops/clifford_gate.py +1 -7
- cirq/ops/common_channels.py +21 -15
- cirq/ops/common_gate_families.py +2 -3
- cirq/ops/common_gates.py +48 -11
- cirq/ops/common_gates_test.py +4 -0
- cirq/ops/controlled_gate.py +44 -18
- cirq/ops/controlled_operation.py +13 -5
- cirq/ops/dense_pauli_string.py +14 -19
- cirq/ops/diagonal_gate.py +3 -4
- cirq/ops/eigen_gate.py +8 -10
- cirq/ops/eigen_gate_test.py +6 -0
- cirq/ops/gate_operation.py +11 -6
- cirq/ops/gate_operation_test.py +11 -2
- cirq/ops/gateset.py +2 -1
- cirq/ops/gateset_test.py +38 -5
- cirq/ops/global_phase_op.py +28 -2
- cirq/ops/global_phase_op_test.py +21 -0
- cirq/ops/identity.py +1 -1
- cirq/ops/kraus_channel_test.py +2 -2
- cirq/ops/linear_combinations.py +7 -6
- cirq/ops/linear_combinations_test.py +26 -10
- cirq/ops/matrix_gates.py +8 -4
- cirq/ops/matrix_gates_test.py +25 -3
- cirq/ops/measure_util.py +13 -5
- cirq/ops/measure_util_test.py +8 -2
- cirq/ops/measurement_gate.py +1 -1
- cirq/ops/measurement_gate_test.py +9 -4
- cirq/ops/mixed_unitary_channel_test.py +4 -4
- cirq/ops/named_qubit.py +2 -4
- cirq/ops/parity_gates.py +5 -1
- cirq/ops/parity_gates_test.py +6 -0
- cirq/ops/pauli_gates.py +9 -9
- cirq/ops/pauli_string.py +4 -2
- cirq/ops/pauli_string_raw_types.py +4 -11
- cirq/ops/pauli_string_test.py +13 -13
- cirq/ops/pauli_sum_exponential.py +6 -1
- cirq/ops/qubit_manager.py +97 -0
- cirq/ops/qubit_manager_test.py +66 -0
- cirq/ops/raw_types.py +75 -33
- cirq/ops/raw_types_test.py +34 -0
- cirq/ops/three_qubit_gates.py +16 -10
- cirq/ops/three_qubit_gates_test.py +4 -2
- cirq/ops/two_qubit_diagonal_gate.py +3 -3
- cirq/ops/wait_gate.py +1 -1
- cirq/protocols/__init__.py +1 -0
- cirq/protocols/act_on_protocol.py +3 -3
- cirq/protocols/act_on_protocol_test.py +5 -5
- cirq/protocols/apply_channel_protocol.py +9 -8
- cirq/protocols/apply_mixture_protocol.py +8 -8
- cirq/protocols/apply_mixture_protocol_test.py +1 -1
- cirq/protocols/apply_unitary_protocol.py +66 -19
- cirq/protocols/apply_unitary_protocol_test.py +50 -0
- cirq/protocols/circuit_diagram_info_protocol.py +7 -9
- cirq/protocols/decompose_protocol.py +167 -125
- cirq/protocols/decompose_protocol_test.py +132 -2
- cirq/protocols/has_stabilizer_effect_protocol.py +2 -1
- cirq/protocols/inverse_protocol.py +2 -2
- cirq/protocols/json_serialization_test.py +3 -3
- cirq/protocols/json_test_data/Linspace.json +20 -7
- cirq/protocols/json_test_data/Linspace.repr +4 -1
- cirq/protocols/json_test_data/Points.json +19 -8
- cirq/protocols/json_test_data/Points.repr +4 -1
- cirq/protocols/json_test_data/Result.repr_inward +1 -1
- cirq/protocols/json_test_data/ResultDict.repr +1 -1
- cirq/protocols/json_test_data/ResultDict.repr_inward +1 -1
- cirq/protocols/json_test_data/TrialResult.repr_inward +1 -1
- cirq/protocols/json_test_data/XPowGate.json +13 -5
- cirq/protocols/json_test_data/XPowGate.repr +1 -1
- cirq/protocols/json_test_data/ZPowGate.json +13 -5
- cirq/protocols/json_test_data/ZPowGate.repr +1 -1
- cirq/protocols/json_test_data/ZipLongest.json +19 -0
- cirq/protocols/json_test_data/ZipLongest.repr +1 -0
- cirq/protocols/json_test_data/spec.py +1 -0
- cirq/protocols/kraus_protocol.py +3 -4
- cirq/protocols/measurement_key_protocol.py +3 -1
- cirq/protocols/mixture_protocol.py +3 -2
- cirq/protocols/phase_protocol.py +3 -3
- cirq/protocols/pow_protocol.py +1 -2
- cirq/protocols/qasm.py +4 -4
- cirq/protocols/qid_shape_protocol.py +8 -8
- cirq/protocols/resolve_parameters.py +8 -3
- cirq/protocols/resolve_parameters_test.py +3 -3
- cirq/protocols/unitary_protocol.py +19 -11
- cirq/protocols/unitary_protocol_test.py +37 -0
- cirq/qis/channels.py +1 -1
- cirq/qis/clifford_tableau.py +4 -5
- cirq/qis/quantum_state_representation.py +7 -9
- cirq/qis/states.py +21 -13
- cirq/qis/states_test.py +7 -0
- cirq/sim/clifford/clifford_simulator.py +3 -3
- cirq/sim/density_matrix_simulation_state.py +2 -1
- cirq/sim/density_matrix_simulator.py +1 -1
- cirq/sim/density_matrix_simulator_test.py +9 -5
- cirq/sim/density_matrix_utils.py +7 -32
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +58 -18
- cirq/sim/simulation_state_base.py +5 -2
- cirq/sim/simulation_state_test.py +121 -9
- cirq/sim/simulation_utils.py +59 -0
- cirq/sim/simulation_utils_test.py +32 -0
- cirq/sim/simulator.py +2 -1
- cirq/sim/simulator_base_test.py +3 -3
- cirq/sim/sparse_simulator.py +1 -1
- cirq/sim/sparse_simulator_test.py +5 -5
- cirq/sim/state_vector.py +7 -36
- cirq/sim/state_vector_simulation_state.py +18 -1
- cirq/sim/state_vector_simulator.py +3 -2
- cirq/sim/state_vector_simulator_test.py +24 -2
- cirq/sim/state_vector_test.py +46 -15
- cirq/study/__init__.py +1 -0
- cirq/study/flatten_expressions.py +2 -2
- cirq/study/resolver.py +2 -0
- cirq/study/resolver_test.py +1 -1
- cirq/study/result.py +1 -1
- cirq/study/sweeps.py +103 -9
- cirq/study/sweeps_test.py +64 -0
- cirq/testing/__init__.py +4 -0
- cirq/testing/circuit_compare.py +15 -18
- cirq/testing/consistent_act_on.py +4 -4
- cirq/testing/consistent_controlled_gate_op_test.py +1 -1
- cirq/testing/consistent_decomposition.py +11 -2
- cirq/testing/consistent_decomposition_test.py +8 -1
- cirq/testing/consistent_protocols.py +2 -0
- cirq/testing/consistent_protocols_test.py +8 -4
- cirq/testing/consistent_qasm.py +8 -15
- cirq/testing/consistent_specified_has_unitary.py +1 -1
- cirq/testing/consistent_unitary.py +85 -0
- cirq/testing/consistent_unitary_test.py +96 -0
- cirq/testing/equivalent_repr_eval.py +10 -10
- cirq/testing/json.py +3 -3
- cirq/testing/logs.py +1 -1
- cirq/testing/order_tester.py +4 -5
- cirq/testing/random_circuit.py +3 -5
- cirq/testing/sample_gates.py +79 -0
- cirq/testing/sample_gates_test.py +59 -0
- cirq/transformers/__init__.py +2 -0
- cirq/transformers/analytical_decompositions/__init__.py +8 -0
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +130 -0
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +58 -0
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +230 -0
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +112 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -3
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/expand_composite.py +1 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +4 -4
- cirq/transformers/measurement_transformers.py +4 -4
- cirq/transformers/merge_single_qubit_gates.py +17 -4
- cirq/transformers/routing/route_circuit_cqc.py +2 -2
- cirq/transformers/stratify.py +125 -62
- cirq/transformers/stratify_test.py +20 -16
- cirq/transformers/transformer_api.py +1 -1
- cirq/transformers/transformer_primitives.py +3 -2
- cirq/transformers/transformer_primitives_test.py +11 -0
- cirq/value/abc_alt.py +3 -2
- cirq/value/abc_alt_test.py +1 -0
- cirq/value/classical_data.py +10 -10
- cirq/value/digits.py +2 -2
- cirq/value/linear_dict.py +18 -19
- cirq/value/product_state.py +7 -6
- cirq/value/value_equality_attr.py +2 -2
- cirq/vis/heatmap.py +1 -1
- cirq/vis/heatmap_test.py +2 -2
- cirq/work/collector.py +2 -2
- cirq/work/observable_measurement_data.py +5 -5
- cirq/work/observable_readout_calibration.py +3 -1
- cirq/work/observable_settings.py +1 -1
- cirq/work/pauli_sum_collector.py +9 -8
- cirq/work/sampler.py +2 -0
- cirq/work/zeros_sampler.py +2 -2
- {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/METADATA +7 -15
- {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/RECORD +228 -214
- {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/WHEEL +1 -1
- {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.1.0.dev20221220224914.dist-info → cirq_core-1.2.0.dist-info}/top_level.txt +0 -0
cirq/circuits/frozen_circuit.py
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""An immutable version of the Circuit data structure."""
|
|
15
|
-
from typing import FrozenSet, Iterable, Iterator, Sequence, Tuple, TYPE_CHECKING, Union
|
|
15
|
+
from typing import AbstractSet, FrozenSet, Iterable, Iterator, Sequence, Tuple, TYPE_CHECKING, Union
|
|
16
16
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
|
|
@@ -83,6 +83,10 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
83
83
|
def _qid_shape_(self) -> Tuple[int, ...]:
|
|
84
84
|
return super()._qid_shape_()
|
|
85
85
|
|
|
86
|
+
@_compat.cached_method
|
|
87
|
+
def _has_unitary_(self) -> bool:
|
|
88
|
+
return super()._has_unitary_()
|
|
89
|
+
|
|
86
90
|
@_compat.cached_method
|
|
87
91
|
def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
|
|
88
92
|
return super()._unitary_()
|
|
@@ -124,6 +128,14 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
124
128
|
def all_measurement_key_names(self) -> FrozenSet[str]:
|
|
125
129
|
return frozenset(str(key) for key in self.all_measurement_key_objs())
|
|
126
130
|
|
|
131
|
+
@_compat.cached_method
|
|
132
|
+
def _is_parameterized_(self) -> bool:
|
|
133
|
+
return super()._is_parameterized_()
|
|
134
|
+
|
|
135
|
+
@_compat.cached_method
|
|
136
|
+
def _parameter_names_(self) -> AbstractSet[str]:
|
|
137
|
+
return super()._parameter_names_()
|
|
138
|
+
|
|
127
139
|
def _measurement_key_names_(self) -> FrozenSet[str]:
|
|
128
140
|
return self.all_measurement_key_names()
|
|
129
141
|
|
|
@@ -68,5 +68,9 @@ def test_immutable():
|
|
|
68
68
|
q = cirq.LineQubit(0)
|
|
69
69
|
c = cirq.FrozenCircuit(cirq.X(q), cirq.H(q))
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
# Match one of two strings. The second one is message returned since python 3.11.
|
|
72
|
+
with pytest.raises(
|
|
73
|
+
AttributeError,
|
|
74
|
+
match="(can't set attribute)|(property 'moments' of 'FrozenCircuit' object has no setter)",
|
|
75
|
+
):
|
|
72
76
|
c.moments = (cirq.Moment(cirq.H(q)), cirq.Moment(cirq.X(q)))
|
cirq/circuits/moment.py
CHANGED
|
@@ -19,6 +19,7 @@ from typing import (
|
|
|
19
19
|
AbstractSet,
|
|
20
20
|
Any,
|
|
21
21
|
Callable,
|
|
22
|
+
cast,
|
|
22
23
|
Dict,
|
|
23
24
|
FrozenSet,
|
|
24
25
|
Iterable,
|
|
@@ -30,13 +31,13 @@ from typing import (
|
|
|
30
31
|
Sequence,
|
|
31
32
|
Tuple,
|
|
32
33
|
TYPE_CHECKING,
|
|
33
|
-
TypeVar,
|
|
34
34
|
Union,
|
|
35
35
|
)
|
|
36
|
+
from typing_extensions import Self
|
|
36
37
|
|
|
37
38
|
import numpy as np
|
|
38
39
|
|
|
39
|
-
from cirq import protocols, ops, qis
|
|
40
|
+
from cirq import protocols, ops, qis, _compat
|
|
40
41
|
from cirq._import import LazyLoader
|
|
41
42
|
from cirq.ops import raw_types, op_tree
|
|
42
43
|
from cirq.protocols import circuit_diagram_info_protocol
|
|
@@ -52,8 +53,6 @@ text_diagram_drawer = LazyLoader(
|
|
|
52
53
|
"text_diagram_drawer", globals(), "cirq.circuits.text_diagram_drawer"
|
|
53
54
|
)
|
|
54
55
|
|
|
55
|
-
TSelf_Moment = TypeVar('TSelf_Moment', bound='Moment')
|
|
56
|
-
|
|
57
56
|
|
|
58
57
|
def _default_breakdown(qid: 'cirq.Qid') -> Tuple[Any, Any]:
|
|
59
58
|
# Attempt to convert into a position on the complex plane.
|
|
@@ -82,17 +81,26 @@ class Moment:
|
|
|
82
81
|
are no such operations, returns an empty Moment.
|
|
83
82
|
"""
|
|
84
83
|
|
|
85
|
-
def __init__(self, *contents: 'cirq.OP_TREE') -> None:
|
|
84
|
+
def __init__(self, *contents: 'cirq.OP_TREE', _flatten_contents: bool = True) -> None:
|
|
86
85
|
"""Constructs a moment with the given operations.
|
|
87
86
|
|
|
88
87
|
Args:
|
|
89
88
|
contents: The operations applied within the moment.
|
|
90
89
|
Will be flattened and frozen into a tuple before storing.
|
|
90
|
+
_flatten_contents: If True, use flatten_to_ops to convert
|
|
91
|
+
the OP_TREE of contents into a tuple of Operation. If False,
|
|
92
|
+
we skip flattening and assume that contents already consists
|
|
93
|
+
of individual operations. This is used internally by helper
|
|
94
|
+
methods to avoid unnecessary validation.
|
|
91
95
|
|
|
92
96
|
Raises:
|
|
93
97
|
ValueError: A qubit appears more than once.
|
|
94
98
|
"""
|
|
95
|
-
self._operations =
|
|
99
|
+
self._operations = (
|
|
100
|
+
tuple(op_tree.flatten_to_ops(contents))
|
|
101
|
+
if _flatten_contents
|
|
102
|
+
else cast(Tuple['cirq.Operation'], contents)
|
|
103
|
+
)
|
|
96
104
|
self._sorted_operations: Optional[Tuple['cirq.Operation', ...]] = None
|
|
97
105
|
|
|
98
106
|
# An internal dictionary to support efficient operation access by qubit.
|
|
@@ -108,6 +116,20 @@ class Moment:
|
|
|
108
116
|
self._measurement_key_objs: Optional[FrozenSet['cirq.MeasurementKey']] = None
|
|
109
117
|
self._control_keys: Optional[FrozenSet['cirq.MeasurementKey']] = None
|
|
110
118
|
|
|
119
|
+
@classmethod
|
|
120
|
+
def from_ops(cls, *ops: 'cirq.Operation') -> 'cirq.Moment':
|
|
121
|
+
"""Construct a Moment from the given operations.
|
|
122
|
+
|
|
123
|
+
This avoids calling `flatten_to_ops` in the moment constructor, which
|
|
124
|
+
results in better performance in cases where the contents of the moment
|
|
125
|
+
are already in the form of a sequence of operations rather than an
|
|
126
|
+
arbitrary OP_TREE.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
*ops: Operations to include in the Moment.
|
|
130
|
+
"""
|
|
131
|
+
return cls(*ops, _flatten_contents=False)
|
|
132
|
+
|
|
111
133
|
@property
|
|
112
134
|
def operations(self) -> Tuple['cirq.Operation', ...]:
|
|
113
135
|
return self._operations
|
|
@@ -148,8 +170,7 @@ class Moment:
|
|
|
148
170
|
"""
|
|
149
171
|
if self.operates_on([qubit]):
|
|
150
172
|
return self.__getitem__(qubit)
|
|
151
|
-
|
|
152
|
-
return None
|
|
173
|
+
return None
|
|
153
174
|
|
|
154
175
|
def with_operation(self, operation: 'cirq.Operation') -> 'cirq.Moment':
|
|
155
176
|
"""Returns an equal moment, but with the given op added.
|
|
@@ -167,7 +188,7 @@ class Moment:
|
|
|
167
188
|
raise ValueError(f'Overlapping operations: {operation}')
|
|
168
189
|
|
|
169
190
|
# Use private variables to facilitate a quick copy.
|
|
170
|
-
m = Moment()
|
|
191
|
+
m = Moment(_flatten_contents=False)
|
|
171
192
|
m._operations = self._operations + (operation,)
|
|
172
193
|
m._sorted_operations = None
|
|
173
194
|
m._qubits = self._qubits.union(operation.qubits)
|
|
@@ -197,7 +218,7 @@ class Moment:
|
|
|
197
218
|
if not flattened_contents:
|
|
198
219
|
return self
|
|
199
220
|
|
|
200
|
-
m = Moment()
|
|
221
|
+
m = Moment(_flatten_contents=False)
|
|
201
222
|
# Use private variables to facilitate a quick copy.
|
|
202
223
|
m._qubit_to_op = self._qubit_to_op.copy()
|
|
203
224
|
qubits = set(self._qubits)
|
|
@@ -238,9 +259,11 @@ class Moment:
|
|
|
238
259
|
if qubits.isdisjoint(frozenset(operation.qubits))
|
|
239
260
|
)
|
|
240
261
|
|
|
262
|
+
@_compat.cached_method()
|
|
241
263
|
def _is_parameterized_(self) -> bool:
|
|
242
264
|
return any(protocols.is_parameterized(op) for op in self)
|
|
243
265
|
|
|
266
|
+
@_compat.cached_method()
|
|
244
267
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
245
268
|
return {name for op in self for name in protocols.parameter_names(op)}
|
|
246
269
|
|
|
@@ -266,6 +289,7 @@ class Moment:
|
|
|
266
289
|
for op in self.operations
|
|
267
290
|
)
|
|
268
291
|
|
|
292
|
+
@_compat.cached_method()
|
|
269
293
|
def _measurement_key_names_(self) -> FrozenSet[str]:
|
|
270
294
|
return frozenset(str(key) for key in self._measurement_key_objs_())
|
|
271
295
|
|
|
@@ -333,6 +357,7 @@ class Moment:
|
|
|
333
357
|
def __ne__(self, other) -> bool:
|
|
334
358
|
return not self == other
|
|
335
359
|
|
|
360
|
+
@_compat.cached_method()
|
|
336
361
|
def __hash__(self):
|
|
337
362
|
return hash((Moment, self._sorted_operations_()))
|
|
338
363
|
|
|
@@ -370,9 +395,8 @@ class Moment:
|
|
|
370
395
|
return self._operations
|
|
371
396
|
|
|
372
397
|
def transform_qubits(
|
|
373
|
-
self:
|
|
374
|
-
|
|
375
|
-
) -> TSelf_Moment:
|
|
398
|
+
self, qubit_map: Union[Dict['cirq.Qid', 'cirq.Qid'], Callable[['cirq.Qid'], 'cirq.Qid']]
|
|
399
|
+
) -> Self:
|
|
376
400
|
"""Returns the same moment, but with different qubits.
|
|
377
401
|
|
|
378
402
|
Args:
|
|
@@ -406,6 +430,7 @@ class Moment:
|
|
|
406
430
|
operations.append(ops.I(q))
|
|
407
431
|
return Moment(*operations)
|
|
408
432
|
|
|
433
|
+
@_compat.cached_method()
|
|
409
434
|
def _has_kraus_(self) -> bool:
|
|
410
435
|
"""Returns True if self has a Kraus representation and self uses <= 10 qubits."""
|
|
411
436
|
return all(protocols.has_kraus(op) for op in self.operations) and len(self.qubits) <= 10
|
|
@@ -482,7 +507,7 @@ class Moment:
|
|
|
482
507
|
|
|
483
508
|
@classmethod
|
|
484
509
|
def _from_json_dict_(cls, operations, **kwargs):
|
|
485
|
-
return
|
|
510
|
+
return cls.from_ops(*operations)
|
|
486
511
|
|
|
487
512
|
def __add__(self, other: 'cirq.OP_TREE') -> 'cirq.Moment':
|
|
488
513
|
|
cirq/circuits/moment_test.py
CHANGED
|
@@ -170,6 +170,13 @@ def test_operation_at():
|
|
|
170
170
|
assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).operation_at(a) == cirq.CZ(a, b)
|
|
171
171
|
|
|
172
172
|
|
|
173
|
+
def test_from_ops():
|
|
174
|
+
a = cirq.NamedQubit('a')
|
|
175
|
+
b = cirq.NamedQubit('b')
|
|
176
|
+
|
|
177
|
+
assert cirq.Moment.from_ops(cirq.X(a), cirq.Y(b)) == cirq.Moment(cirq.X(a), cirq.Y(b))
|
|
178
|
+
|
|
179
|
+
|
|
173
180
|
def test_with_operation():
|
|
174
181
|
a = cirq.NamedQubit('a')
|
|
175
182
|
b = cirq.NamedQubit('b')
|
|
@@ -292,7 +292,7 @@ class TextDiagramDrawer:
|
|
|
292
292
|
self,
|
|
293
293
|
horizontal_spacing: int = 1,
|
|
294
294
|
vertical_spacing: int = 1,
|
|
295
|
-
crossing_char: str = None,
|
|
295
|
+
crossing_char: Optional[str] = None,
|
|
296
296
|
use_unicode_characters: bool = True,
|
|
297
297
|
) -> str:
|
|
298
298
|
"""Outputs text containing the diagram."""
|
|
@@ -46,17 +46,13 @@ def assert_has_rendering(actual: TextDiagramDrawer, desired: str, **kwargs) -> N
|
|
|
46
46
|
"Diagram's rendering differs from the desired rendering.\n"
|
|
47
47
|
'\n'
|
|
48
48
|
'Actual rendering:\n'
|
|
49
|
-
'{}\n'
|
|
49
|
+
f'{actual_diagram}\n'
|
|
50
50
|
'\n'
|
|
51
51
|
'Desired rendering:\n'
|
|
52
|
-
'{}\n'
|
|
52
|
+
f'{desired_diagram}\n'
|
|
53
53
|
'\n'
|
|
54
54
|
'Highlighted differences:\n'
|
|
55
|
-
'{}\n'
|
|
56
|
-
actual_diagram,
|
|
57
|
-
desired_diagram,
|
|
58
|
-
ct.highlight_text_differences(actual_diagram, desired_diagram),
|
|
59
|
-
)
|
|
55
|
+
f'{ct.highlight_text_differences(actual_diagram, desired_diagram)}\n'
|
|
60
56
|
)
|
|
61
57
|
|
|
62
58
|
|
|
@@ -133,7 +133,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
|
|
|
133
133
|
if self.subgraph == BipartiteGraphType.MATCHING:
|
|
134
134
|
name = 'Matching'
|
|
135
135
|
elif self.subgraph == BipartiteGraphType.COMPLETE:
|
|
136
|
-
name = 'K_{{{
|
|
136
|
+
name = f'K_{{{self.part_size}, {self.part_size}}}'
|
|
137
137
|
# NB: self.subgraph not in BipartiteGraphType caught by self.permutation
|
|
138
138
|
arrow = '↦' if args.use_unicode_characters else '->'
|
|
139
139
|
|
|
@@ -36,8 +36,8 @@ class AcquaintanceDevice(devices.Device, metaclass=abc.ABCMeta):
|
|
|
36
36
|
isinstance(operation, ops.GateOperation) and isinstance(operation.gate, self.gate_types)
|
|
37
37
|
):
|
|
38
38
|
raise ValueError(
|
|
39
|
-
'not (isinstance({
|
|
40
|
-
'ininstance({
|
|
39
|
+
f'not (isinstance({operation!r}, {ops.Operation!r}) and '
|
|
40
|
+
f'ininstance({operation!r}.gate, {self.gate_types!r})'
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
|
|
@@ -34,7 +34,7 @@ if TYPE_CHECKING:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class ExecutionStrategy(metaclass=abc.ABCMeta):
|
|
37
|
-
"""Tells `
|
|
37
|
+
"""Tells `StrategyExecutorTransformer` how to execute an acquaintance strategy.
|
|
38
38
|
|
|
39
39
|
An execution strategy tells `StrategyExecutorTransformer` how to execute
|
|
40
40
|
an acquaintance strategy, i.e. what gates to implement at the available
|
|
@@ -174,7 +174,10 @@ class GreedyExecutionStrategy(ExecutionStrategy):
|
|
|
174
174
|
"""
|
|
175
175
|
|
|
176
176
|
def __init__(
|
|
177
|
-
self,
|
|
177
|
+
self,
|
|
178
|
+
gates: LogicalGates,
|
|
179
|
+
initial_mapping: LogicalMapping,
|
|
180
|
+
device: Optional['cirq.Device'] = None,
|
|
178
181
|
) -> None:
|
|
179
182
|
"""Inits GreedyExecutionStrategy.
|
|
180
183
|
|
|
@@ -347,8 +347,9 @@ class SwapNetworkGate(PermutationGate):
|
|
|
347
347
|
return {i: j for i, j in enumerate(reversed(range(sum(self.part_lens))))}
|
|
348
348
|
|
|
349
349
|
def __repr__(self) -> str:
|
|
350
|
-
return
|
|
351
|
-
|
|
350
|
+
return (
|
|
351
|
+
'cirq.contrib.acquaintance.SwapNetworkGate('
|
|
352
|
+
f'{self.part_lens!r}, {self.acquaintance_size!r})'
|
|
352
353
|
)
|
|
353
354
|
|
|
354
355
|
def _value_equality_values_(self):
|
|
@@ -13,7 +13,18 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import abc
|
|
16
|
-
from typing import
|
|
16
|
+
from typing import (
|
|
17
|
+
Any,
|
|
18
|
+
cast,
|
|
19
|
+
Dict,
|
|
20
|
+
Iterable,
|
|
21
|
+
Optional,
|
|
22
|
+
Sequence,
|
|
23
|
+
Tuple,
|
|
24
|
+
TypeVar,
|
|
25
|
+
Union,
|
|
26
|
+
TYPE_CHECKING,
|
|
27
|
+
)
|
|
17
28
|
|
|
18
29
|
from cirq import circuits, ops, protocols, transformers, value
|
|
19
30
|
from cirq.type_workarounds import NotImplementedType
|
|
@@ -72,7 +83,7 @@ class PermutationGate(ops.Gate, metaclass=abc.ABCMeta):
|
|
|
72
83
|
mapping[new_key] = old_element
|
|
73
84
|
|
|
74
85
|
@staticmethod
|
|
75
|
-
def validate_permutation(permutation: Dict[int, int], n_elements: int = None) -> None:
|
|
86
|
+
def validate_permutation(permutation: Dict[int, int], n_elements: Optional[int] = None) -> None:
|
|
76
87
|
if not permutation:
|
|
77
88
|
return
|
|
78
89
|
if set(permutation.values()) != set(permutation):
|
|
@@ -29,13 +29,11 @@ def assert_permutation_decomposition_equivalence(gate: PermutationGate, n_qubits
|
|
|
29
29
|
update_mapping(mapping, operations)
|
|
30
30
|
expected_mapping = {qubits[j]: i for i, j in gate.permutation().items()}
|
|
31
31
|
assert mapping == expected_mapping, (
|
|
32
|
-
"{!r}.permutation({}) doesn't match decomposition.\n"
|
|
32
|
+
f"{gate!r}.permutation({n_qubits}) doesn't match decomposition.\n"
|
|
33
33
|
'\n'
|
|
34
34
|
'Actual mapping:\n'
|
|
35
|
-
'{}\n'
|
|
35
|
+
f'{[mapping[q] for q in qubits]}\n'
|
|
36
36
|
'\n'
|
|
37
37
|
'Expected mapping:\n'
|
|
38
|
-
'{}\n'
|
|
39
|
-
gate, n_qubits, [mapping[q] for q in qubits], [expected_mapping[q] for q in qubits]
|
|
40
|
-
)
|
|
38
|
+
f'{[expected_mapping[q] for q in qubits]}\n'
|
|
41
39
|
)
|
|
@@ -27,7 +27,6 @@ def _sorted_best_string_placements(
|
|
|
27
27
|
output_ops: Sequence[ops.Operation],
|
|
28
28
|
key: Callable[[Any], ops.PauliStringPhasor] = lambda node: node.val,
|
|
29
29
|
) -> List[Tuple[ops.PauliStringPhasor, int, circuitdag.Unique[ops.PauliStringPhasor]]]:
|
|
30
|
-
|
|
31
30
|
sort_key = lambda placement: (-len(placement[0].pauli_string), placement[1])
|
|
32
31
|
|
|
33
32
|
node_maxes = []
|
|
@@ -84,11 +83,9 @@ def move_pauli_strings_into_circuit(
|
|
|
84
83
|
# Pick the Pauli string that can be moved furthest through
|
|
85
84
|
# the Clifford circuit
|
|
86
85
|
for best_string_op, best_index, best_node in placements:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
best_index
|
|
90
|
-
), "Unexpected insertion index order, {} >= {}, len: {}".format(
|
|
91
|
-
best_index, last_index, len(output_ops)
|
|
86
|
+
assert best_index <= last_index, (
|
|
87
|
+
"Unexpected insertion index order, "
|
|
88
|
+
f"{best_index} >= {last_index}, len: {len(output_ops)}"
|
|
92
89
|
)
|
|
93
90
|
|
|
94
91
|
last_index = best_index
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
import functools
|
|
15
16
|
import operator
|
|
16
17
|
from typing import Any, Callable, cast, Dict, Iterable, List, Optional, Union, TYPE_CHECKING
|
|
@@ -82,16 +83,15 @@ class QasmGateStatement:
|
|
|
82
83
|
def _validate_args(self, args: List[List[ops.Qid]], lineno: int):
|
|
83
84
|
if len(args) != self.num_args:
|
|
84
85
|
raise QasmException(
|
|
85
|
-
"{} only takes {} arg(s) (qubits and/or registers), "
|
|
86
|
-
"got: {}, at line {}"
|
|
86
|
+
f"{self.qasm_gate} only takes {self.num_args} arg(s) (qubits and/or registers), "
|
|
87
|
+
f"got: {len(args)}, at line {lineno}"
|
|
87
88
|
)
|
|
88
89
|
|
|
89
90
|
def _validate_params(self, params: List[float], lineno: int):
|
|
90
91
|
if len(params) != self.num_params:
|
|
91
92
|
raise QasmException(
|
|
92
|
-
"{} takes {} parameter(s),
|
|
93
|
-
|
|
94
|
-
)
|
|
93
|
+
f"{self.qasm_gate} takes {self.num_params} parameter(s), "
|
|
94
|
+
f"got: {len(params)}, at line {lineno}"
|
|
95
95
|
)
|
|
96
96
|
|
|
97
97
|
def on(
|
|
@@ -141,7 +141,7 @@ class QasmParser:
|
|
|
141
141
|
parsedQasm = QasmParser().parse(qasm)
|
|
142
142
|
"""
|
|
143
143
|
|
|
144
|
-
def __init__(self):
|
|
144
|
+
def __init__(self) -> None:
|
|
145
145
|
self.parser = yacc.yacc(module=self, debug=False, write_tables=False)
|
|
146
146
|
self.circuit = Circuit()
|
|
147
147
|
self.qregs: Dict[str, int] = {}
|
|
@@ -287,8 +287,7 @@ class QasmParser:
|
|
|
287
287
|
"""format : FORMAT_SPEC"""
|
|
288
288
|
if p[1] != "2.0":
|
|
289
289
|
raise QasmException(
|
|
290
|
-
"Unsupported OpenQASM version: {}, "
|
|
291
|
-
"only 2.0 is supported currently by Cirq".format(p[1])
|
|
290
|
+
f"Unsupported OpenQASM version: {p[1]}, only 2.0 is supported currently by Cirq"
|
|
292
291
|
)
|
|
293
292
|
|
|
294
293
|
# circuit : new_reg circuit
|
|
@@ -345,11 +344,8 @@ class QasmParser:
|
|
|
345
344
|
):
|
|
346
345
|
gate_set = self.basic_gates if not self.qelibinc else self.all_gates
|
|
347
346
|
if gate not in gate_set.keys():
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
p.lineno(1),
|
|
351
|
-
", did you forget to include qelib1.inc?" if not self.qelibinc else "",
|
|
352
|
-
)
|
|
347
|
+
tip = ", did you forget to include qelib1.inc?" if not self.qelibinc else ""
|
|
348
|
+
msg = f'Unknown gate "{gate}" at line {p.lineno(1)}{tip}'
|
|
353
349
|
raise QasmException(msg)
|
|
354
350
|
p[0] = gate_set[gate].on(args=args, params=params, lineno=p.lineno(1))
|
|
355
351
|
|
|
@@ -460,9 +456,9 @@ class QasmParser:
|
|
|
460
456
|
size = self.qregs[reg]
|
|
461
457
|
if idx >= size:
|
|
462
458
|
raise QasmException(
|
|
463
|
-
'Out of bounds qubit index {} '
|
|
464
|
-
'on register {} of size {} '
|
|
465
|
-
'at line {
|
|
459
|
+
f'Out of bounds qubit index {idx} '
|
|
460
|
+
f'on register {reg} of size {size} '
|
|
461
|
+
f'at line {p.lineno(1)}'
|
|
466
462
|
)
|
|
467
463
|
if arg_name not in self.qubits.keys():
|
|
468
464
|
self.qubits[arg_name] = NamedQubit(arg_name)
|
|
@@ -479,9 +475,9 @@ class QasmParser:
|
|
|
479
475
|
size = self.cregs[reg]
|
|
480
476
|
if idx >= size:
|
|
481
477
|
raise QasmException(
|
|
482
|
-
'Out of bounds bit index {} '
|
|
483
|
-
'on classical register {} of size {} '
|
|
484
|
-
'at line {
|
|
478
|
+
f'Out of bounds bit index {idx} '
|
|
479
|
+
f'on classical register {reg} of size {size} '
|
|
480
|
+
f'at line {p.lineno(1)}'
|
|
485
481
|
)
|
|
486
482
|
p[0] = [arg_name]
|
|
487
483
|
|
|
@@ -495,8 +491,8 @@ class QasmParser:
|
|
|
495
491
|
|
|
496
492
|
if len(qreg) != len(creg):
|
|
497
493
|
raise QasmException(
|
|
498
|
-
'mismatched register sizes {} -> {} for measurement '
|
|
499
|
-
'at line {
|
|
494
|
+
f'mismatched register sizes {len(qreg)} -> {len(creg)} for measurement '
|
|
495
|
+
f'at line {p.lineno(1)}'
|
|
500
496
|
)
|
|
501
497
|
|
|
502
498
|
p[0] = [
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
from typing import Callable
|
|
15
16
|
|
|
16
17
|
import numpy as np
|
|
@@ -489,14 +490,12 @@ single_qubit_gates = [
|
|
|
489
490
|
|
|
490
491
|
@pytest.mark.parametrize('qasm_gate,cirq_gate', rotation_gates)
|
|
491
492
|
def test_rotation_gates(qasm_gate: str, cirq_gate: Callable[[float], cirq.Gate]):
|
|
492
|
-
qasm = """OPENQASM 2.0;
|
|
493
|
+
qasm = f"""OPENQASM 2.0;
|
|
493
494
|
include "qelib1.inc";
|
|
494
495
|
qreg q[2];
|
|
495
|
-
{
|
|
496
|
-
{
|
|
497
|
-
"""
|
|
498
|
-
qasm_gate
|
|
499
|
-
)
|
|
496
|
+
{qasm_gate}(pi/2) q[0];
|
|
497
|
+
{qasm_gate}(pi) q;
|
|
498
|
+
"""
|
|
500
499
|
|
|
501
500
|
parser = QasmParser()
|
|
502
501
|
|
|
@@ -527,7 +526,7 @@ def test_rotation_gates_wrong_number_of_args(qasm_gate: str):
|
|
|
527
526
|
|
|
528
527
|
parser = QasmParser()
|
|
529
528
|
|
|
530
|
-
with pytest.raises(QasmException, match=
|
|
529
|
+
with pytest.raises(QasmException, match=f".*{qasm_gate}.* takes 1.*got.*2.*line 5"):
|
|
531
530
|
parser.parse(qasm)
|
|
532
531
|
|
|
533
532
|
|
|
@@ -541,7 +540,7 @@ def test_rotation_gates_zero_params_error(qasm_gate: str):
|
|
|
541
540
|
|
|
542
541
|
parser = QasmParser()
|
|
543
542
|
|
|
544
|
-
with pytest.raises(QasmException, match=
|
|
543
|
+
with pytest.raises(QasmException, match=f".*{qasm_gate}.* takes 1.*got.*0.*line 4"):
|
|
545
544
|
parser.parse(qasm)
|
|
546
545
|
|
|
547
546
|
|
|
@@ -867,9 +866,7 @@ def test_standard_gates_wrong_params_error(qasm_gate: str, num_params: int):
|
|
|
867
866
|
|
|
868
867
|
parser = QasmParser()
|
|
869
868
|
|
|
870
|
-
with pytest.raises(
|
|
871
|
-
QasmException, match=r".*{}.* takes {}.*got.*5.*line 4".format(qasm_gate, num_params)
|
|
872
|
-
):
|
|
869
|
+
with pytest.raises(QasmException, match=f".*{qasm_gate}.* takes {num_params}.*got.*5.*line 4"):
|
|
873
870
|
parser.parse(qasm)
|
|
874
871
|
|
|
875
872
|
if num_params == 0:
|
|
@@ -883,9 +880,7 @@ def test_standard_gates_wrong_params_error(qasm_gate: str, num_params: int):
|
|
|
883
880
|
|
|
884
881
|
parser = QasmParser()
|
|
885
882
|
|
|
886
|
-
with pytest.raises(
|
|
887
|
-
QasmException, match=r".*{}.* takes {}.*got.*0.*line 4".format(qasm_gate, num_params)
|
|
888
|
-
):
|
|
883
|
+
with pytest.raises(QasmException, match=f".*{qasm_gate}.* takes {num_params}.*got.*0.*line 4"):
|
|
889
884
|
parser.parse(qasm)
|
|
890
885
|
|
|
891
886
|
|
|
@@ -901,17 +896,15 @@ two_qubit_gates = [
|
|
|
901
896
|
|
|
902
897
|
@pytest.mark.parametrize('qasm_gate,cirq_gate', two_qubit_gates)
|
|
903
898
|
def test_two_qubit_gates(qasm_gate: str, cirq_gate: cirq.testing.TwoQubitGate):
|
|
904
|
-
qasm = """
|
|
905
|
-
OPENQASM 2.0;
|
|
906
|
-
include "qelib1.inc";
|
|
899
|
+
qasm = f"""
|
|
900
|
+
OPENQASM 2.0;
|
|
901
|
+
include "qelib1.inc";
|
|
907
902
|
qreg q1[2];
|
|
908
903
|
qreg q2[2];
|
|
909
|
-
{
|
|
910
|
-
{
|
|
911
|
-
{
|
|
912
|
-
"""
|
|
913
|
-
qasm_gate
|
|
914
|
-
)
|
|
904
|
+
{qasm_gate} q1[0], q1[1];
|
|
905
|
+
{qasm_gate} q1, q2[0];
|
|
906
|
+
{qasm_gate} q2, q1;
|
|
907
|
+
"""
|
|
915
908
|
parser = QasmParser()
|
|
916
909
|
|
|
917
910
|
q1_0 = cirq.NamedQubit('q1_0')
|
|
@@ -949,9 +942,7 @@ def test_two_qubit_gates_not_enough_args(qasm_gate: str):
|
|
|
949
942
|
|
|
950
943
|
parser = QasmParser()
|
|
951
944
|
|
|
952
|
-
with pytest.raises(
|
|
953
|
-
QasmException, match=r".*{}.* takes 2 arg\(s\).*got.*1.*line 5".format(qasm_gate)
|
|
954
|
-
):
|
|
945
|
+
with pytest.raises(QasmException, match=rf".*{qasm_gate}.* takes 2 arg\(s\).*got.*1.*line 5"):
|
|
955
946
|
parser.parse(qasm)
|
|
956
947
|
|
|
957
948
|
|
|
@@ -967,7 +958,7 @@ def test_two_qubit_gates_with_too_much_parameters(qasm_gate: str):
|
|
|
967
958
|
parser = QasmParser()
|
|
968
959
|
|
|
969
960
|
with pytest.raises(
|
|
970
|
-
QasmException, match=
|
|
961
|
+
QasmException, match=rf".*{qasm_gate}.* takes 0 parameter\(s\).*got.*1.*line 5"
|
|
971
962
|
):
|
|
972
963
|
parser.parse(qasm)
|
|
973
964
|
|
|
@@ -977,18 +968,16 @@ three_qubit_gates = [('ccx', cirq.TOFFOLI), ('cswap', cirq.CSWAP)]
|
|
|
977
968
|
|
|
978
969
|
@pytest.mark.parametrize('qasm_gate,cirq_gate', three_qubit_gates)
|
|
979
970
|
def test_three_qubit_gates(qasm_gate: str, cirq_gate: cirq.testing.TwoQubitGate):
|
|
980
|
-
qasm = """
|
|
971
|
+
qasm = f"""
|
|
981
972
|
OPENQASM 2.0;
|
|
982
|
-
include "qelib1.inc";
|
|
973
|
+
include "qelib1.inc";
|
|
983
974
|
qreg q1[2];
|
|
984
975
|
qreg q2[2];
|
|
985
976
|
qreg q3[2];
|
|
986
|
-
{
|
|
987
|
-
{
|
|
988
|
-
{
|
|
989
|
-
"""
|
|
990
|
-
qasm_gate
|
|
991
|
-
)
|
|
977
|
+
{qasm_gate} q1[0], q1[1], q2[0];
|
|
978
|
+
{qasm_gate} q1, q2[0], q3[0];
|
|
979
|
+
{qasm_gate} q1, q2, q3;
|
|
980
|
+
"""
|
|
992
981
|
parser = QasmParser()
|
|
993
982
|
|
|
994
983
|
q1_0 = cirq.NamedQubit('q1_0')
|
|
@@ -1027,9 +1016,7 @@ def test_three_qubit_gates_not_enough_args(qasm_gate: str):
|
|
|
1027
1016
|
|
|
1028
1017
|
parser = QasmParser()
|
|
1029
1018
|
|
|
1030
|
-
with pytest.raises(
|
|
1031
|
-
QasmException, match=r""".*{}.* takes 3 arg\(s\).*got.*1.*line 4""".format(qasm_gate)
|
|
1032
|
-
):
|
|
1019
|
+
with pytest.raises(QasmException, match=rf".*{qasm_gate}.* takes 3 arg\(s\).*got.*1.*line 4"):
|
|
1033
1020
|
parser.parse(qasm)
|
|
1034
1021
|
|
|
1035
1022
|
|
|
@@ -1043,20 +1030,18 @@ def test_three_qubit_gates_with_too_much_parameters(qasm_gate: str):
|
|
|
1043
1030
|
|
|
1044
1031
|
parser = QasmParser()
|
|
1045
1032
|
|
|
1046
|
-
with pytest.raises(QasmException, match=
|
|
1033
|
+
with pytest.raises(QasmException, match=f".*{qasm_gate}.*parameter.*line 4.*"):
|
|
1047
1034
|
parser.parse(qasm)
|
|
1048
1035
|
|
|
1049
1036
|
|
|
1050
1037
|
@pytest.mark.parametrize('qasm_gate,cirq_gate', single_qubit_gates)
|
|
1051
1038
|
def test_single_qubit_gates(qasm_gate: str, cirq_gate: cirq.Gate):
|
|
1052
|
-
qasm = """OPENQASM 2.0;
|
|
1039
|
+
qasm = f"""OPENQASM 2.0;
|
|
1053
1040
|
include "qelib1.inc";
|
|
1054
1041
|
qreg q[2];
|
|
1055
|
-
{
|
|
1056
|
-
{
|
|
1057
|
-
"""
|
|
1058
|
-
qasm_gate
|
|
1059
|
-
)
|
|
1042
|
+
{qasm_gate} q[0];
|
|
1043
|
+
{qasm_gate} q;
|
|
1044
|
+
"""
|
|
1060
1045
|
|
|
1061
1046
|
parser = QasmParser()
|
|
1062
1047
|
|