Skip to content

Commit 10ff83d

Browse files
authored
Merge branch 'main' into mh-fix-size-labeler
2 parents 7f4a83b + c054b90 commit 10ff83d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+645
-2025
lines changed

.github/workflows/pr-labeler.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151
timeout-minutes: 5
5252
permissions:
5353
contents: read
54+
issues: write
5455
pull-requests: write
5556
env:
5657
PR_NUMBER: ${{inputs.pr-number || github.event.pull_request.number}}

cirq-core/cirq/devices/noise_model_test.py

Lines changed: 3 additions & 1 deletion
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+
from __future__ import annotations
16+
1517
from typing import Sequence
1618

1719
import numpy as np
@@ -77,7 +79,7 @@ def noisy_moment(self, moment, system_qubits):
7779
)
7880

7981
class NoiseModelWithNoisyOperationMethod(cirq.NoiseModel):
80-
def noisy_operation(self, operation: 'cirq.Operation'):
82+
def noisy_operation(self, operation: cirq.Operation):
8183
return cirq.Z(operation.qubits[0]).with_tags(ops.VirtualTag())
8284

8385
c = NoiseModelWithNoisyOperationMethod()

cirq-core/cirq/devices/noise_properties.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
noise models to produce a single noise model which replicates device noise.
2020
"""
2121

22+
from __future__ import annotations
23+
2224
import abc
2325
from typing import Iterable, List, Sequence, TYPE_CHECKING
2426

@@ -35,7 +37,7 @@ class NoiseProperties(abc.ABC):
3537
"""Noise-defining properties for a quantum device."""
3638

3739
@abc.abstractmethod
38-
def build_noise_models(self) -> List['cirq.NoiseModel']:
40+
def build_noise_models(self) -> List[cirq.NoiseModel]:
3941
"""Construct all NoiseModels associated with this NoiseProperties."""
4042

4143

@@ -52,7 +54,7 @@ def __init__(self, noise_properties: NoiseProperties) -> None:
5254
self._noise_properties = noise_properties
5355
self.noise_models = self._noise_properties.build_noise_models()
5456

55-
def is_virtual(self, op: 'cirq.Operation') -> bool:
57+
def is_virtual(self, op: cirq.Operation) -> bool:
5658
"""Returns True if an operation is virtual.
5759
5860
Device-specific subclasses should implement this method to mark any
@@ -67,8 +69,8 @@ def is_virtual(self, op: 'cirq.Operation') -> bool:
6769
return False
6870

6971
def noisy_moments(
70-
self, moments: Iterable['cirq.Moment'], system_qubits: Sequence['cirq.Qid']
71-
) -> Sequence['cirq.OP_TREE']:
72+
self, moments: Iterable[cirq.Moment], system_qubits: Sequence[cirq.Qid]
73+
) -> Sequence[cirq.OP_TREE]:
7274
# Split multi-qubit measurements into single-qubit measurements.
7375
# These will be recombined after noise is applied.
7476
split_measure_moments = []

cirq-core/cirq/devices/noise_utils.py

Lines changed: 8 additions & 6 deletions
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+
from __future__ import annotations
16+
1517
from typing import Any, Dict, Tuple, Type, TYPE_CHECKING, Union
1618

1719
from cirq import ops, protocols, qis, value
@@ -29,24 +31,24 @@
2931
class OpIdentifier:
3032
"""Identifies an operation by gate and (optionally) target qubits."""
3133

32-
def __init__(self, gate_type: Type['cirq.Gate'], *qubits: 'cirq.Qid'):
34+
def __init__(self, gate_type: Type[cirq.Gate], *qubits: cirq.Qid):
3335
self._gate_type = gate_type
3436
self._gate_family = ops.GateFamily(gate_type)
35-
self._qubits: Tuple['cirq.Qid', ...] = tuple(qubits)
37+
self._qubits: Tuple[cirq.Qid, ...] = tuple(qubits)
3638

3739
@property
38-
def gate_type(self) -> Type['cirq.Gate']:
40+
def gate_type(self) -> Type[cirq.Gate]:
3941
# set to a type during initialization, never modified
4042
return self._gate_type
4143

4244
@property
43-
def qubits(self) -> Tuple['cirq.Qid', ...]:
45+
def qubits(self) -> Tuple[cirq.Qid, ...]:
4446
return self._qubits
4547

4648
def _predicate(self, *args, **kwargs):
4749
return self._gate_family._predicate(*args, **kwargs)
4850

49-
def is_proper_subtype_of(self, op_id: 'OpIdentifier'):
51+
def is_proper_subtype_of(self, op_id: OpIdentifier):
5052
"""Returns true if this is contained within op_id, but not equal to it.
5153
5254
If this returns true, (x in self) implies (x in op_id), but the reverse
@@ -90,7 +92,7 @@ def _json_dict_(self) -> Dict[str, Any]:
9092
return {'gate_type': self._gate_type, 'qubits': self._qubits}
9193

9294
@classmethod
93-
def _from_json_dict_(cls, gate_type, qubits, **kwargs) -> 'OpIdentifier':
95+
def _from_json_dict_(cls, gate_type, qubits, **kwargs) -> OpIdentifier:
9496
if isinstance(gate_type, str):
9597
gate_type = protocols.cirq_type_from_json(gate_type)
9698
return cls(gate_type, *qubits)

cirq-core/cirq/devices/superconducting_qubits_noise_properties.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
1615
"""Class for representing noise on a superconducting qubit device."""
1716

17+
from __future__ import annotations
18+
1819
import abc
1920
from dataclasses import dataclass, field
2021
from functools import cached_property
@@ -49,13 +50,13 @@ class SuperconductingQubitsNoiseProperties(devices.NoiseProperties, abc.ABC):
4950
"""
5051

5152
gate_times_ns: Dict[type, float]
52-
t1_ns: Dict['cirq.Qid', float]
53-
tphi_ns: Dict['cirq.Qid', float]
54-
readout_errors: Dict['cirq.Qid', List[float]]
53+
t1_ns: Dict[cirq.Qid, float]
54+
tphi_ns: Dict[cirq.Qid, float]
55+
readout_errors: Dict[cirq.Qid, List[float]]
5556
gate_pauli_errors: Dict[noise_utils.OpIdentifier, float]
5657

5758
validate: bool = True
58-
_qubits: List['cirq.Qid'] = field(init=False, default_factory=list)
59+
_qubits: List[cirq.Qid] = field(init=False, default_factory=list)
5960

6061
def __post_init__(self):
6162
if not self.validate:
@@ -95,7 +96,7 @@ def _validate_symmetric_errors(self, field_name: str) -> None:
9596
)
9697

9798
@property
98-
def qubits(self) -> List['cirq.Qid']:
99+
def qubits(self) -> List[cirq.Qid]:
99100
"""Qubits for which we have data"""
100101
if not self._qubits:
101102
self._qubits = sorted(self.t1_ns)
@@ -150,8 +151,8 @@ def _depolarizing_error(self) -> Dict[noise_utils.OpIdentifier, float]:
150151
depol_errors[op_id] = self._get_pauli_error(p_error, op_id)
151152
return depol_errors
152153

153-
def build_noise_models(self) -> List['cirq.NoiseModel']:
154-
noise_models: List['cirq.NoiseModel'] = []
154+
def build_noise_models(self) -> List[cirq.NoiseModel]:
155+
noise_models: List[cirq.NoiseModel] = []
155156

156157
if self.t1_ns:
157158
noise_models.append(
@@ -175,7 +176,7 @@ def build_noise_models(self) -> List['cirq.NoiseModel']:
175176

176177
# This adds per-qubit measurement error BEFORE measurement on those qubits.
177178
if self.readout_errors:
178-
added_measure_errors: Dict[noise_utils.OpIdentifier, 'cirq.Operation'] = {}
179+
added_measure_errors: Dict[noise_utils.OpIdentifier, cirq.Operation] = {}
179180
for qubit in self.readout_errors:
180181
p_00, p_11 = self.readout_errors[qubit]
181182
p = p_11 / (p_00 + p_11)

cirq-core/cirq/devices/thermal_noise_model.py

Lines changed: 12 additions & 12 deletions
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+
from __future__ import annotations
16+
1517
import dataclasses
1618
import functools
1719
from typing import Dict, List, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
@@ -129,8 +131,8 @@ def _decoherence_matrix(
129131

130132

131133
def _as_rate_dict(
132-
rate_or_dict: Optional[Union[float, Dict['cirq.Qid', float]]], qubits: Set['cirq.Qid']
133-
) -> Dict['cirq.Qid', float]:
134+
rate_or_dict: Optional[Union[float, Dict[cirq.Qid, float]]], qubits: Set[cirq.Qid]
135+
) -> Dict[cirq.Qid, float]:
134136
"""Convert float or None input into dictionary form.
135137
136138
This method also ensures that no qubits are missing from dictionary keys.
@@ -143,7 +145,7 @@ def _as_rate_dict(
143145
return {q: rate_or_dict for q in qubits}
144146

145147

146-
def _validate_rates(qubits: Set['cirq.Qid'], rates: Dict['cirq.Qid', np.ndarray]) -> None:
148+
def _validate_rates(qubits: Set[cirq.Qid], rates: Dict[cirq.Qid, np.ndarray]) -> None:
147149
"""Check all rate matrices are square and of appropriate dimension.
148150
149151
We check rates are positive in the class validator.
@@ -169,11 +171,11 @@ class ThermalNoiseModel(devices.NoiseModel):
169171

170172
def __init__(
171173
self,
172-
qubits: Set['cirq.Qid'],
174+
qubits: Set[cirq.Qid],
173175
gate_durations_ns: Dict[type, float],
174-
heat_rate_GHz: Union[float, Dict['cirq.Qid', float], None] = None,
175-
cool_rate_GHz: Union[float, Dict['cirq.Qid', float], None] = None,
176-
dephase_rate_GHz: Union[float, Dict['cirq.Qid', float], None] = None,
176+
heat_rate_GHz: Union[float, Dict[cirq.Qid, float], None] = None,
177+
cool_rate_GHz: Union[float, Dict[cirq.Qid, float], None] = None,
178+
dephase_rate_GHz: Union[float, Dict[cirq.Qid, float], None] = None,
177179
require_physical_tag: bool = True,
178180
skip_measurements: bool = True,
179181
prepend: bool = False,
@@ -225,14 +227,12 @@ def __init__(
225227

226228
_validate_rates(qubits, rate_dict)
227229
self.gate_durations_ns: Dict[type, float] = gate_durations_ns
228-
self.rate_matrix_GHz: Dict['cirq.Qid', np.ndarray] = rate_dict
230+
self.rate_matrix_GHz: Dict[cirq.Qid, np.ndarray] = rate_dict
229231
self.require_physical_tag: bool = require_physical_tag
230232
self.skip_measurements: bool = skip_measurements
231233
self._prepend = prepend
232234

233-
def noisy_moment(
234-
self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']
235-
) -> 'cirq.OP_TREE':
235+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
236236
if not moment.operations:
237237
return [moment]
238238
if self.require_physical_tag:
@@ -247,7 +247,7 @@ def noisy_moment(
247247
# Only moments with physical operations should have noise.
248248
return [moment]
249249

250-
noise_ops: List['cirq.Operation'] = []
250+
noise_ops: List[cirq.Operation] = []
251251
# Some devices (including Google hardware) require that all gates have
252252
# the same duration, but this does not. Instead, each moment is assumed
253253
# to be as long as the longest gate it contains.

cirq-core/cirq/devices/unconstrained_device.py

Lines changed: 3 additions & 1 deletion
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+
from __future__ import annotations
16+
1517
from typing import Any, Dict, TYPE_CHECKING
1618

1719
from cirq import protocols, value
@@ -26,7 +28,7 @@
2628
class _UnconstrainedDevice(device.Device):
2729
"""A device that allows everything, infinitely fast."""
2830

29-
def duration_of(self, operation: 'cirq.Operation') -> 'cirq.Duration':
31+
def duration_of(self, operation: cirq.Operation) -> cirq.Duration:
3032
return value.Duration(picos=0)
3133

3234
def validate_moment(self, moment) -> None:

cirq-core/cirq/experiments/n_qubit_tomography.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
The code is designed to be modular with regards to data collection
1818
so that occurs outside of the StateTomographyExperiment class.
1919
"""
20+
21+
from __future__ import annotations
22+
2023
from typing import List, Optional, Sequence, Tuple, TYPE_CHECKING
2124

2225
import numpy as np
@@ -49,7 +52,7 @@ class StateTomographyExperiment:
4952

5053
def __init__(
5154
self,
52-
qubits: Sequence['cirq.Qid'],
55+
qubits: Sequence[cirq.Qid],
5356
prerotations: Optional[Sequence[Tuple[float, float]]] = None,
5457
):
5558
"""Initializes the rotation protocol and matrix for system.
@@ -69,8 +72,8 @@ def __init__(
6972

7073
phase_exp_vals, exp_vals = zip(*prerotations)
7174

72-
operations: List['cirq.Operation'] = []
73-
sweeps: List['cirq.Sweep'] = []
75+
operations: List[cirq.Operation] = []
76+
sweeps: List[cirq.Sweep] = []
7477
for i, qubit in enumerate(qubits):
7578
phase_exp = sympy.Symbol(f'phase_exp_{i}')
7679
exp = sympy.Symbol(f'exp_{i}')
@@ -82,7 +85,7 @@ def __init__(
8285
self.rot_sweep = study.Product(*sweeps)
8386
self.mat = self._make_state_tomography_matrix(qubits)
8487

85-
def _make_state_tomography_matrix(self, qubits: Sequence['cirq.Qid']) -> np.ndarray:
88+
def _make_state_tomography_matrix(self, qubits: Sequence[cirq.Qid]) -> np.ndarray:
8689
"""Gets the matrix used for solving the linear system of the tomography.
8790
8891
Args:
@@ -130,9 +133,9 @@ def fit_density_matrix(self, counts: np.ndarray) -> TomographyResult:
130133

131134

132135
def state_tomography(
133-
sampler: 'cirq.Sampler',
134-
qubits: Sequence['cirq.Qid'],
135-
circuit: 'cirq.Circuit',
136+
sampler: cirq.Sampler,
137+
qubits: Sequence[cirq.Qid],
138+
circuit: cirq.Circuit,
136139
repetitions: int = 1000,
137140
prerotations: Optional[Sequence[Tuple[float, float]]] = None,
138141
) -> TomographyResult:
@@ -166,11 +169,11 @@ def state_tomography(
166169

167170

168171
def get_state_tomography_data(
169-
sampler: 'cirq.Sampler',
170-
qubits: Sequence['cirq.Qid'],
171-
circuit: 'cirq.Circuit',
172-
rot_circuit: 'cirq.Circuit',
173-
rot_sweep: 'cirq.Sweep',
172+
sampler: cirq.Sampler,
173+
qubits: Sequence[cirq.Qid],
174+
circuit: cirq.Circuit,
175+
rot_circuit: cirq.Circuit,
176+
rot_sweep: cirq.Sweep,
174177
repetitions: int = 1000,
175178
) -> np.ndarray:
176179
"""Gets the data for each rotation string added to the circuit.

0 commit comments

Comments
 (0)