From bcd35333ebe2c85dca5b655d4710d7848b922056 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Fri, 22 Mar 2024 22:38:20 +0000 Subject: [PATCH 01/17] add default device config key to grid device metadata --- cirq-core/cirq/devices/grid_device_metadata.py | 15 +++++++++++++++ cirq-google/cirq_google/devices/grid_device.py | 9 ++++++++- .../cirq_google/engine/engine_processor.py | 13 ++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/cirq-core/cirq/devices/grid_device_metadata.py b/cirq-core/cirq/devices/grid_device_metadata.py index 58b49df7f7f..0bf56e836e9 100644 --- a/cirq-core/cirq/devices/grid_device_metadata.py +++ b/cirq-core/cirq/devices/grid_device_metadata.py @@ -18,6 +18,7 @@ import networkx as nx from cirq import value from cirq.devices import device +from cirq_google.cloud import quantum if TYPE_CHECKING: import cirq @@ -31,6 +32,7 @@ def __init__( self, qubit_pairs: Iterable[Tuple['cirq.GridQubit', 'cirq.GridQubit']], gateset: 'cirq.Gateset', + device_config_key: Optional[quantum.DeviceConfigKey] = None, gate_durations: Optional[Mapping['cirq.GateFamily', 'cirq.Duration']] = None, all_qubits: Optional[Iterable['cirq.GridQubit']] = None, compilation_target_gatesets: Iterable['cirq.CompilationTargetGateset'] = (), @@ -47,6 +49,8 @@ def __init__( bi-directional couplings. gateset: `cirq.Gateset` indicating gates supported everywhere on the device. + device_config_key: quantum.DeviceConfigKey representing + the name of the device configuration. gate_durations: Optional dictionary of `cirq.GateFamily` instances mapping to `cirq.Duration` instances for gate timing metadata information. If provided, @@ -99,6 +103,7 @@ def __init__( self._qubit_pairs = frozenset({frozenset(pair) for pair in edge_set}) self._gateset = gateset + self._device_config_key = device_config_key self._isolated_qubits = all_qubits.difference(node_set) self._compilation_target_gatesets = tuple(compilation_target_gatesets) @@ -141,6 +146,11 @@ def gateset(self) -> 'cirq.Gateset': """Returns the `cirq.Gateset` of supported gates on this device.""" return self._gateset + @property + def device_config_key(self) -> quantum.DeviceConfigKey | None: + """Returns the key of the device configuration.""" + return self._device_config_key + @property def compilation_target_gatesets(self) -> Tuple['cirq.CompilationTargetGateset', ...]: """Returns a sequence of valid `cirq.CompilationTargetGateset`s for this device.""" @@ -178,6 +188,7 @@ def _value_equality_values_(self): return ( self._qubit_pairs, self._gateset, + self._device_config_key, tuple(duration_equality), tuple(sorted(self.qubit_set)), frozenset(self._compilation_target_gatesets), @@ -186,6 +197,7 @@ def _value_equality_values_(self): def __repr__(self) -> str: qubit_pair_tuples = frozenset({tuple(sorted(p)) for p in self._qubit_pairs}) return ( + f'device_config_key={self._device_config_key},' f'cirq.GridDeviceMetadata({repr(qubit_pair_tuples)},' f' {repr(self._gateset)}, {repr(self._gate_durations)},' f' {repr(self.qubit_set)}, {repr(self._compilation_target_gatesets)})' @@ -199,6 +211,7 @@ def _json_dict_(self): return { 'qubit_pairs': sorted([sorted(pair) for pair in self._qubit_pairs]), 'gateset': self._gateset, + 'device_config_key': self._device_config_key, 'gate_durations': duration_payload, 'all_qubits': sorted(list(self.qubit_set)), 'compilation_target_gatesets': list(self._compilation_target_gatesets), @@ -209,6 +222,7 @@ def _from_json_dict_( cls, qubit_pairs, gateset, + device_config_key, gate_durations, all_qubits, compilation_target_gatesets=(), @@ -217,6 +231,7 @@ def _from_json_dict_( return cls( qubit_pairs, gateset, + device_config_key, dict(gate_durations) if gate_durations is not None else None, all_qubits, compilation_target_gatesets, diff --git a/cirq-google/cirq_google/devices/grid_device.py b/cirq-google/cirq_google/devices/grid_device.py index 6dc8ddad169..a7637fcb0bb 100644 --- a/cirq-google/cirq_google/devices/grid_device.py +++ b/cirq-google/cirq_google/devices/grid_device.py @@ -36,6 +36,7 @@ from cirq_google import ops from cirq_google import transformers from cirq_google.api import v2 +from cirq_google.cloud.quantum import DeviceConfigKey from cirq_google.devices import known_devices from cirq_google.experimental import ops as experimental_ops @@ -428,11 +429,16 @@ def __init__(self, metadata: cirq.GridDeviceMetadata): self._metadata = metadata @classmethod - def from_proto(cls, proto: v2.device_pb2.DeviceSpecification) -> 'GridDevice': + def from_proto( + cls, + proto: v2.device_pb2.DeviceSpecification, + device_config_key: DeviceConfigKey = DeviceConfigKey(), + ) -> 'GridDevice': """Deserializes the `DeviceSpecification` to a `GridDevice`. Args: proto: The `DeviceSpecification` proto describing a Google device. + device_config_key: The default device config key for a Google device. Raises: ValueError: If the given `DeviceSpecification` is invalid. It is invalid if: @@ -463,6 +469,7 @@ def from_proto(cls, proto: v2.device_pb2.DeviceSpecification) -> 'GridDevice': metadata = cirq.GridDeviceMetadata( qubit_pairs=qubit_pairs, gateset=gateset, + device_config_key=device_config_key, gate_durations=gate_durations if len(gate_durations) > 0 else None, all_qubits=all_qubits, compilation_target_gatesets=_build_compilation_target_gatesets(gateset), diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 19b21d78901..935f5d6a363 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -19,8 +19,8 @@ from google.protobuf import any_pb2 import cirq -from cirq_google.cloud import quantum from cirq_google.api import v2 +from cirq_google.cloud import quantum from cirq_google.devices import grid_device from cirq_google.engine import abstract_processor, calibration, processor_sampler, util @@ -220,6 +220,17 @@ def get_device_specification(self) -> Optional[v2.device_pb2.DeviceSpecification else: return None + def get_default_device_configuration(self) -> quantum.DeviceConfigKey: + """Returns the default device configuration key for the processor. + Returns: + Device configuration proto if present. + Raises: + ValueError: If the processor does not have a default device configuration key. + """ + if not self._inner_processor().default_device_config_key: + raise ValueError('Processor does not have a default device configuration key') + return self._inner_processor().default_device_config_key + def get_device(self) -> cirq.Device: """Returns a `Device` created from the processor's device specification. From 69ed5532fb6004d99f222a42ab13523422194788 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Fri, 22 Mar 2024 23:22:25 +0000 Subject: [PATCH 02/17] Revert "add default device config key to grid device metadata" This reverts commit bcd35333ebe2c85dca5b655d4710d7848b922056. --- cirq-core/cirq/devices/grid_device_metadata.py | 15 --------------- cirq-google/cirq_google/devices/grid_device.py | 9 +-------- .../cirq_google/engine/engine_processor.py | 13 +------------ 3 files changed, 2 insertions(+), 35 deletions(-) diff --git a/cirq-core/cirq/devices/grid_device_metadata.py b/cirq-core/cirq/devices/grid_device_metadata.py index 0bf56e836e9..58b49df7f7f 100644 --- a/cirq-core/cirq/devices/grid_device_metadata.py +++ b/cirq-core/cirq/devices/grid_device_metadata.py @@ -18,7 +18,6 @@ import networkx as nx from cirq import value from cirq.devices import device -from cirq_google.cloud import quantum if TYPE_CHECKING: import cirq @@ -32,7 +31,6 @@ def __init__( self, qubit_pairs: Iterable[Tuple['cirq.GridQubit', 'cirq.GridQubit']], gateset: 'cirq.Gateset', - device_config_key: Optional[quantum.DeviceConfigKey] = None, gate_durations: Optional[Mapping['cirq.GateFamily', 'cirq.Duration']] = None, all_qubits: Optional[Iterable['cirq.GridQubit']] = None, compilation_target_gatesets: Iterable['cirq.CompilationTargetGateset'] = (), @@ -49,8 +47,6 @@ def __init__( bi-directional couplings. gateset: `cirq.Gateset` indicating gates supported everywhere on the device. - device_config_key: quantum.DeviceConfigKey representing - the name of the device configuration. gate_durations: Optional dictionary of `cirq.GateFamily` instances mapping to `cirq.Duration` instances for gate timing metadata information. If provided, @@ -103,7 +99,6 @@ def __init__( self._qubit_pairs = frozenset({frozenset(pair) for pair in edge_set}) self._gateset = gateset - self._device_config_key = device_config_key self._isolated_qubits = all_qubits.difference(node_set) self._compilation_target_gatesets = tuple(compilation_target_gatesets) @@ -146,11 +141,6 @@ def gateset(self) -> 'cirq.Gateset': """Returns the `cirq.Gateset` of supported gates on this device.""" return self._gateset - @property - def device_config_key(self) -> quantum.DeviceConfigKey | None: - """Returns the key of the device configuration.""" - return self._device_config_key - @property def compilation_target_gatesets(self) -> Tuple['cirq.CompilationTargetGateset', ...]: """Returns a sequence of valid `cirq.CompilationTargetGateset`s for this device.""" @@ -188,7 +178,6 @@ def _value_equality_values_(self): return ( self._qubit_pairs, self._gateset, - self._device_config_key, tuple(duration_equality), tuple(sorted(self.qubit_set)), frozenset(self._compilation_target_gatesets), @@ -197,7 +186,6 @@ def _value_equality_values_(self): def __repr__(self) -> str: qubit_pair_tuples = frozenset({tuple(sorted(p)) for p in self._qubit_pairs}) return ( - f'device_config_key={self._device_config_key},' f'cirq.GridDeviceMetadata({repr(qubit_pair_tuples)},' f' {repr(self._gateset)}, {repr(self._gate_durations)},' f' {repr(self.qubit_set)}, {repr(self._compilation_target_gatesets)})' @@ -211,7 +199,6 @@ def _json_dict_(self): return { 'qubit_pairs': sorted([sorted(pair) for pair in self._qubit_pairs]), 'gateset': self._gateset, - 'device_config_key': self._device_config_key, 'gate_durations': duration_payload, 'all_qubits': sorted(list(self.qubit_set)), 'compilation_target_gatesets': list(self._compilation_target_gatesets), @@ -222,7 +209,6 @@ def _from_json_dict_( cls, qubit_pairs, gateset, - device_config_key, gate_durations, all_qubits, compilation_target_gatesets=(), @@ -231,7 +217,6 @@ def _from_json_dict_( return cls( qubit_pairs, gateset, - device_config_key, dict(gate_durations) if gate_durations is not None else None, all_qubits, compilation_target_gatesets, diff --git a/cirq-google/cirq_google/devices/grid_device.py b/cirq-google/cirq_google/devices/grid_device.py index a7637fcb0bb..6dc8ddad169 100644 --- a/cirq-google/cirq_google/devices/grid_device.py +++ b/cirq-google/cirq_google/devices/grid_device.py @@ -36,7 +36,6 @@ from cirq_google import ops from cirq_google import transformers from cirq_google.api import v2 -from cirq_google.cloud.quantum import DeviceConfigKey from cirq_google.devices import known_devices from cirq_google.experimental import ops as experimental_ops @@ -429,16 +428,11 @@ def __init__(self, metadata: cirq.GridDeviceMetadata): self._metadata = metadata @classmethod - def from_proto( - cls, - proto: v2.device_pb2.DeviceSpecification, - device_config_key: DeviceConfigKey = DeviceConfigKey(), - ) -> 'GridDevice': + def from_proto(cls, proto: v2.device_pb2.DeviceSpecification) -> 'GridDevice': """Deserializes the `DeviceSpecification` to a `GridDevice`. Args: proto: The `DeviceSpecification` proto describing a Google device. - device_config_key: The default device config key for a Google device. Raises: ValueError: If the given `DeviceSpecification` is invalid. It is invalid if: @@ -469,7 +463,6 @@ def from_proto( metadata = cirq.GridDeviceMetadata( qubit_pairs=qubit_pairs, gateset=gateset, - device_config_key=device_config_key, gate_durations=gate_durations if len(gate_durations) > 0 else None, all_qubits=all_qubits, compilation_target_gatesets=_build_compilation_target_gatesets(gateset), diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 935f5d6a363..19b21d78901 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -19,8 +19,8 @@ from google.protobuf import any_pb2 import cirq -from cirq_google.api import v2 from cirq_google.cloud import quantum +from cirq_google.api import v2 from cirq_google.devices import grid_device from cirq_google.engine import abstract_processor, calibration, processor_sampler, util @@ -220,17 +220,6 @@ def get_device_specification(self) -> Optional[v2.device_pb2.DeviceSpecification else: return None - def get_default_device_configuration(self) -> quantum.DeviceConfigKey: - """Returns the default device configuration key for the processor. - Returns: - Device configuration proto if present. - Raises: - ValueError: If the processor does not have a default device configuration key. - """ - if not self._inner_processor().default_device_config_key: - raise ValueError('Processor does not have a default device configuration key') - return self._inner_processor().default_device_config_key - def get_device(self) -> cirq.Device: """Returns a `Device` created from the processor's device specification. From bc55c9d6b6c1237c18099a4103756baa2b4b0bd3 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Sat, 23 Mar 2024 00:16:08 +0000 Subject: [PATCH 03/17] initialize sampler with default device config key and add tests --- .../cirq_google/engine/engine_processor.py | 18 ++++++++-- .../engine/engine_processor_test.py | 34 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 19b21d78901..4ad70f1759a 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -19,8 +19,8 @@ from google.protobuf import any_pb2 import cirq -from cirq_google.cloud import quantum from cirq_google.api import v2 +from cirq_google.cloud import quantum from cirq_google.devices import grid_device from cirq_google.engine import abstract_processor, calibration, processor_sampler, util @@ -110,8 +110,11 @@ def get_sampler( Returns: A `cirq.Sampler` instance (specifically a `engine_sampler.ProcessorSampler` that will send circuits to the Quantum Computing Service - when sampled.1 + when sampled. """ + if self._processor is not None: + run_name = self._processor.default_device_config_key.run + device_config_name = self._processor.default_device_config_key.config_alias return processor_sampler.ProcessorSampler( processor=self, run_name=run_name, device_config_name=device_config_name ) @@ -220,6 +223,17 @@ def get_device_specification(self) -> Optional[v2.device_pb2.DeviceSpecification else: return None + def get_default_device_config_key(self) -> quantum.DeviceConfigKey: + """Returns the default device configuration key for the processor. + Returns: + Device configuration proto if present. + Raises: + ValueError: If the processor does not have a default device configuration key. + """ + if not self._inner_processor().default_device_config_key: + raise ValueError('Processor does not have a default device configuration key') + return self._inner_processor().default_device_config_key + def get_device(self) -> cirq.Device: """Returns a `Device` created from the processor's device specification. diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 2277cace49f..7c416c8cb7b 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -301,6 +301,40 @@ def test_get_missing_device(): _ = processor.get_device() +def test_get_default_device_config_key() -> None: + processor = cg.EngineProcessor( + 'a', + 'p', + EngineContext(), + _processor=quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey( + run="run", config_alias="conflig_alias" + ) + ), + ) + + inner_default_device_config_key = processor.get_default_device_config_key() + assert inner_default_device_config_key.run == "run" + assert inner_default_device_config_key.config_alias == "conflig_alias" + + +def test_get_sampler_initializes_default_device_configuration() -> None: + processor = cg.EngineProcessor( + 'a', + 'p', + EngineContext(), + _processor=quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey( + run="run", config_alias="conflig_alias" + ) + ), + ) + sampler = processor.get_sampler() + + assert sampler.run_name == "run" + assert sampler.device_config_name == "config_alias" + + @mock.patch('cirq_google.engine.engine_client.EngineClient.list_calibrations_async') def test_list_calibrations(list_calibrations): list_calibrations.return_value = [_CALIBRATION] From 9b1309b5092b9c1e0abd4650c835ff6c9f2a1586 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 04:01:07 +0000 Subject: [PATCH 04/17] add properties to sampler --- cirq-google/cirq_google/engine/processor_sampler.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cirq-google/cirq_google/engine/processor_sampler.py b/cirq-google/cirq_google/engine/processor_sampler.py index ecf18230d56..14a09ca48f0 100644 --- a/cirq-google/cirq_google/engine/processor_sampler.py +++ b/cirq-google/cirq_google/engine/processor_sampler.py @@ -86,3 +86,11 @@ async def run_batch_async( @property def processor(self) -> 'cg.engine.AbstractProcessor': return self._processor + + @property + def run_name(self) -> str: + return self._run_name + + @property + def device_config_name(self) -> str: + return self._device_config_name From 7845b3c50f4bdebda3e4f0e0fa5f4d8eee0d615b Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 04:37:50 +0000 Subject: [PATCH 05/17] dedupe DeviceConfigK, onewas renamed to DeviceConfigSelector --- .../cirq_google/cloud/quantum/__init__.py | 6 ++-- .../cloud/quantum_v1alpha1/__init__.py | 6 ++-- .../cloud/quantum_v1alpha1/types/__init__.py | 4 ++- .../cloud/quantum_v1alpha1/types/quantum.py | 26 ++++++++++++-- .../cirq_google/engine/engine_client.py | 4 +-- .../cirq_google/engine/engine_client_test.py | 34 ++++++++++++------- 6 files changed, 58 insertions(+), 22 deletions(-) diff --git a/cirq-google/cirq_google/cloud/quantum/__init__.py b/cirq-google/cirq_google/cloud/quantum/__init__.py index da13d072acf..df76298594d 100644 --- a/cirq-google/cirq_google/cloud/quantum/__init__.py +++ b/cirq-google/cirq_google/cloud/quantum/__init__.py @@ -61,7 +61,7 @@ from cirq_google.cloud.quantum_v1alpha1.types.engine import UpdateQuantumJobRequest from cirq_google.cloud.quantum_v1alpha1.types.engine import UpdateQuantumProgramRequest from cirq_google.cloud.quantum_v1alpha1.types.engine import UpdateQuantumReservationRequest -from cirq_google.cloud.quantum_v1alpha1.types.quantum import DeviceConfigKey +from cirq_google.cloud.quantum_v1alpha1.types.quantum import DeviceConfigSelector from cirq_google.cloud.quantum_v1alpha1.types.quantum import ExecutionStatus from cirq_google.cloud.quantum_v1alpha1.types.quantum import GcsLocation from cirq_google.cloud.quantum_v1alpha1.types.quantum import InlineData @@ -77,6 +77,7 @@ from cirq_google.cloud.quantum_v1alpha1.types.quantum import QuantumResult from cirq_google.cloud.quantum_v1alpha1.types.quantum import QuantumTimeSlot from cirq_google.cloud.quantum_v1alpha1.types.quantum import SchedulingConfig +from cirq_google.cloud.quantum_v1alpha1.types.quantum import DeviceConfigKey __all__ = ( 'QuantumEngineServiceClient', @@ -121,7 +122,7 @@ 'UpdateQuantumJobRequest', 'UpdateQuantumProgramRequest', 'UpdateQuantumReservationRequest', - 'DeviceConfigKey', + 'DeviceConfigSelector', 'ExecutionStatus', 'GcsLocation', 'InlineData', @@ -137,4 +138,5 @@ 'QuantumResult', 'QuantumTimeSlot', 'SchedulingConfig', + 'DeviceConfigKey', ) diff --git a/cirq-google/cirq_google/cloud/quantum_v1alpha1/__init__.py b/cirq-google/cirq_google/cloud/quantum_v1alpha1/__init__.py index fa5dd1140e9..8d2c1d80b27 100644 --- a/cirq-google/cirq_google/cloud/quantum_v1alpha1/__init__.py +++ b/cirq-google/cirq_google/cloud/quantum_v1alpha1/__init__.py @@ -57,7 +57,7 @@ from .types.engine import UpdateQuantumJobRequest from .types.engine import UpdateQuantumProgramRequest from .types.engine import UpdateQuantumReservationRequest -from .types.quantum import DeviceConfigKey +from .types.quantum import DeviceConfigSelector from .types.quantum import ExecutionStatus from .types.quantum import GcsLocation from .types.quantum import InlineData @@ -73,6 +73,7 @@ from .types.quantum import QuantumResult from .types.quantum import QuantumTimeSlot from .types.quantum import SchedulingConfig +from .types.quantum import DeviceConfigKey __all__ = ( 'QuantumEngineServiceAsyncClient', @@ -85,7 +86,7 @@ 'DeleteQuantumJobRequest', 'DeleteQuantumProgramRequest', 'DeleteQuantumReservationRequest', - 'DeviceConfigKey', + 'DeviceConfigSelector', 'ExecutionStatus', 'GcsLocation', 'GetQuantumCalibrationRequest', @@ -133,4 +134,5 @@ 'UpdateQuantumJobRequest', 'UpdateQuantumProgramRequest', 'UpdateQuantumReservationRequest', + 'DeviceConfigKey', ) diff --git a/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/__init__.py b/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/__init__.py index fc9a36199ba..d298e09478b 100644 --- a/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/__init__.py +++ b/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/__init__.py @@ -57,6 +57,7 @@ ) from .quantum import ( DeviceConfigKey, + DeviceConfigSelector, ExecutionStatus, GcsLocation, InlineData, @@ -115,7 +116,7 @@ 'UpdateQuantumJobRequest', 'UpdateQuantumProgramRequest', 'UpdateQuantumReservationRequest', - 'DeviceConfigKey', + 'DeviceConfigSelector', 'ExecutionStatus', 'GcsLocation', 'InlineData', @@ -131,4 +132,5 @@ 'QuantumResult', 'QuantumTimeSlot', 'SchedulingConfig', + 'DeviceConfigKey', ) diff --git a/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/quantum.py b/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/quantum.py index 9a7962c206a..517e07e9f4f 100644 --- a/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/quantum.py +++ b/cirq-google/cirq_google/cloud/quantum_v1alpha1/types/quantum.py @@ -39,6 +39,8 @@ 'QuantumReservationBudget', 'QuantumTimeSlot', 'QuantumReservation', + 'DeviceConfigSelector', + 'DeviceConfigKey', }, ) @@ -152,7 +154,7 @@ class QuantumJob(proto.Message): run_context = proto.Field(proto.MESSAGE, number=11, message=any_pb2.Any) -class DeviceConfigKey(proto.Message): +class DeviceConfigSelector(proto.Message): r"""- Attributes: run_name (str): @@ -185,13 +187,13 @@ class ProcessorSelector(proto.Message): - processor (str): - - device_config_key ((google.cloud.quantum_v1alpha1.types.DeviceConfigKey): + device_config_selector ((google.cloud.quantum_v1alpha1.types.DeviceConfigSelector): - """ processor_names = proto.RepeatedField(proto.STRING, number=1) processor = proto.Field(proto.STRING, number=2) - device_config_key = proto.Field(proto.MESSAGE, number=3, message=DeviceConfigKey) + device_config_selector = proto.Field(proto.MESSAGE, number=3, message=DeviceConfigSelector) target_route = proto.Field(proto.STRING, number=1) processor_selector = proto.Field(proto.MESSAGE, number=3, message=ProcessorSelector) @@ -378,6 +380,9 @@ class QuantumProcessor(proto.Message): Output only. - activity_stats (google.cloud.quantum_v1alpha1.types.QuantumProcessor.ActivityStats): - + default_device_config_key (google.cloud.quantum_v1alpha1.types.DeviceConfigKey): + - + """ class Health(proto.Enum): @@ -413,6 +418,7 @@ class ActivityStats(proto.Message): current_calibration = proto.Field(proto.STRING, number=10) active_time_slot = proto.Field(proto.MESSAGE, number=11, message='QuantumTimeSlot') activity_stats = proto.Field(proto.MESSAGE, number=12, message=ActivityStats) + default_device_config_key = proto.Field(proto.MESSAGE, number=13, message='DeviceConfigKey') class QuantumCalibration(proto.Message): @@ -605,4 +611,18 @@ class QuantumReservation(proto.Message): whitelisted_users = proto.RepeatedField(proto.STRING, number=5) +class DeviceConfigKey(proto.Message): + r"""- + + Attributes: + run (str): + - + config_alias (str): + - + """ + + run = proto.Field(proto.STRING, number=1) + config_alias = proto.Field(proto.STRING, number=2) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/cirq-google/cirq_google/engine/engine_client.py b/cirq-google/cirq_google/engine/engine_client.py index f73e2b3c26a..00d7c751b1a 100644 --- a/cirq-google/cirq_google/engine/engine_client.py +++ b/cirq-google/cirq_google/engine/engine_client.py @@ -455,7 +455,7 @@ async def create_job_async( scheduling_config=quantum.SchedulingConfig( processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor=_processor_name_from_ids(project_id, processor_id), - device_config_key=quantum.DeviceConfigKey( + device_config_selector=quantum.DeviceConfigSelector( run_name=run_name, config_alias=device_config_name ), ) @@ -816,7 +816,7 @@ def run_job_over_stream( scheduling_config=quantum.SchedulingConfig( processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor=_processor_name_from_ids(project_id, processor_id), - device_config_key=quantum.DeviceConfigKey( + device_config_selector=quantum.DeviceConfigSelector( run_name=run_name, config_alias=device_config_name ), ) diff --git a/cirq-google/cirq_google/engine/engine_client_test.py b/cirq-google/cirq_google/engine/engine_client_test.py index 82273d9f29d..eae40635d31 100644 --- a/cirq-google/cirq_google/engine/engine_client_test.py +++ b/cirq-google/cirq_google/engine/engine_client_test.py @@ -373,7 +373,9 @@ def test_create_job(client_constructor): priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(run_name="", config_alias=""), + device_config_selector=quantum.DeviceConfigSelector( + run_name="", config_alias="" + ), ), ), description='A job', @@ -396,7 +398,9 @@ def test_create_job(client_constructor): priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(run_name="", config_alias=""), + device_config_selector=quantum.DeviceConfigSelector( + run_name="", config_alias="" + ), ), ), description='A job', @@ -417,7 +421,9 @@ def test_create_job(client_constructor): priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(run_name="", config_alias=""), + device_config_selector=quantum.DeviceConfigSelector( + run_name="", config_alias="" + ), ), ), labels=labels, @@ -439,7 +445,9 @@ def test_create_job(client_constructor): priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(run_name="", config_alias=""), + device_config_selector=quantum.DeviceConfigSelector( + run_name="", config_alias="" + ), ), ), ), @@ -463,7 +471,9 @@ def test_create_job(client_constructor): priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(run_name="", config_alias=""), + device_config_selector=quantum.DeviceConfigSelector( + run_name="", config_alias="" + ), ), ), ), @@ -573,7 +583,7 @@ def test_create_job_with_run_name_and_device_config_name( priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey( + device_config_selector=quantum.DeviceConfigSelector( run_name=run_name, config_alias=device_config_name ), ), @@ -615,7 +625,7 @@ def test_create_job_with_run_name_and_device_config_name( priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(), + device_config_selector=quantum.DeviceConfigSelector(), ), ), description='A job', @@ -649,7 +659,7 @@ def test_create_job_with_run_name_and_device_config_name( priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(), + device_config_selector=quantum.DeviceConfigSelector(), ), ), description='A job', @@ -680,7 +690,7 @@ def test_create_job_with_run_name_and_device_config_name( priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(), + device_config_selector=quantum.DeviceConfigSelector(), ), ), description='A job', @@ -717,7 +727,7 @@ def test_create_job_with_run_name_and_device_config_name( priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(), + device_config_selector=quantum.DeviceConfigSelector(), ), ), description='A job', @@ -752,7 +762,7 @@ def test_create_job_with_run_name_and_device_config_name( priority=10, processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(), + device_config_selector=quantum.DeviceConfigSelector(), ), ), ), @@ -784,7 +794,7 @@ def test_create_job_with_run_name_and_device_config_name( scheduling_config=quantum.SchedulingConfig( processor_selector=quantum.SchedulingConfig.ProcessorSelector( processor='projects/proj/processors/processor0', - device_config_key=quantum.DeviceConfigKey(), + device_config_selector=quantum.DeviceConfigSelector(), ) ), ), From 73a493d9d7eeff73b5c18ed340adeb4519d184ee Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 04:46:02 +0000 Subject: [PATCH 06/17] spelling --- cirq-google/cirq_google/engine/engine_processor_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 7c416c8cb7b..4595f0e52ba 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -308,14 +308,14 @@ def test_get_default_device_config_key() -> None: EngineContext(), _processor=quantum.QuantumProcessor( default_device_config_key=quantum.DeviceConfigKey( - run="run", config_alias="conflig_alias" + run="run", config_alias="config_alias" ) ), ) inner_default_device_config_key = processor.get_default_device_config_key() assert inner_default_device_config_key.run == "run" - assert inner_default_device_config_key.config_alias == "conflig_alias" + assert inner_default_device_config_key.config_alias == "config_alias" def test_get_sampler_initializes_default_device_configuration() -> None: @@ -325,7 +325,7 @@ def test_get_sampler_initializes_default_device_configuration() -> None: EngineContext(), _processor=quantum.QuantumProcessor( default_device_config_key=quantum.DeviceConfigKey( - run="run", config_alias="conflig_alias" + run="run", config_alias="config_alias" ) ), ) From e2cf3696845ed7a426210967adacefee73489452 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 05:11:16 +0000 Subject: [PATCH 07/17] coverage --- cirq-google/cirq_google/engine/engine_processor.py | 2 +- cirq-google/cirq_google/engine/engine_processor_test.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 4ad70f1759a..514d556ed31 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -231,7 +231,7 @@ def get_default_device_config_key(self) -> quantum.DeviceConfigKey: ValueError: If the processor does not have a default device configuration key. """ if not self._inner_processor().default_device_config_key: - raise ValueError('Processor does not have a default device configuration key') + raise ValueError('Processor does not have a default device configuration key.') return self._inner_processor().default_device_config_key def get_device(self) -> cirq.Device: diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 4595f0e52ba..389c686ba4d 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -318,6 +318,15 @@ def test_get_default_device_config_key() -> None: assert inner_default_device_config_key.config_alias == "config_alias" +def test_get_default_device_config_key_on_empty_raises_exception() -> None: + processor = cg.EngineProcessor('a', 'p', EngineContext(), _processor=quantum.QuantumProcessor()) + + with pytest.raises( + ValueError, match='Processor does not have a default device configuration key' + ): + processor.get_default_device_config_key() + + def test_get_sampler_initializes_default_device_configuration() -> None: processor = cg.EngineProcessor( 'a', From 42c49393b50dc6a76f502fbbba19e7d04602288a Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 19:35:03 +0000 Subject: [PATCH 08/17] address comments --- .../cirq_google/engine/engine_processor.py | 17 +++--------- .../engine/engine_processor_test.py | 26 ------------------- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 514d556ed31..aaa9c9c2b85 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -112,9 +112,9 @@ def get_sampler( that will send circuits to the Quantum Computing Service when sampled. """ - if self._processor is not None: - run_name = self._processor.default_device_config_key.run - device_config_name = self._processor.default_device_config_key.config_alias + if processor := self._inner_processor(): + run_name = processor.default_device_config_key.run + device_config_name = processor.default_device_config_key.config_alias return processor_sampler.ProcessorSampler( processor=self, run_name=run_name, device_config_name=device_config_name ) @@ -223,17 +223,6 @@ def get_device_specification(self) -> Optional[v2.device_pb2.DeviceSpecification else: return None - def get_default_device_config_key(self) -> quantum.DeviceConfigKey: - """Returns the default device configuration key for the processor. - Returns: - Device configuration proto if present. - Raises: - ValueError: If the processor does not have a default device configuration key. - """ - if not self._inner_processor().default_device_config_key: - raise ValueError('Processor does not have a default device configuration key.') - return self._inner_processor().default_device_config_key - def get_device(self) -> cirq.Device: """Returns a `Device` created from the processor's device specification. diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 389c686ba4d..d1c85e0d46b 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -301,32 +301,6 @@ def test_get_missing_device(): _ = processor.get_device() -def test_get_default_device_config_key() -> None: - processor = cg.EngineProcessor( - 'a', - 'p', - EngineContext(), - _processor=quantum.QuantumProcessor( - default_device_config_key=quantum.DeviceConfigKey( - run="run", config_alias="config_alias" - ) - ), - ) - - inner_default_device_config_key = processor.get_default_device_config_key() - assert inner_default_device_config_key.run == "run" - assert inner_default_device_config_key.config_alias == "config_alias" - - -def test_get_default_device_config_key_on_empty_raises_exception() -> None: - processor = cg.EngineProcessor('a', 'p', EngineContext(), _processor=quantum.QuantumProcessor()) - - with pytest.raises( - ValueError, match='Processor does not have a default device configuration key' - ): - processor.get_default_device_config_key() - - def test_get_sampler_initializes_default_device_configuration() -> None: processor = cg.EngineProcessor( 'a', From 47a7e3f468b86cfe9275819fe953b1903e4711b5 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 21:28:46 +0000 Subject: [PATCH 09/17] add fake engine context and client for testing --- .../cirq_google/engine/engine_processor.py | 3 +- .../engine/engine_processor_test.py | 35 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index aaa9c9c2b85..7552172b00f 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -112,7 +112,8 @@ def get_sampler( that will send circuits to the Quantum Computing Service when sampled. """ - if processor := self._inner_processor(): + processor = self._inner_processor() + if processor is not None: run_name = processor.default_device_config_key.run device_config_name = processor.default_device_config_key.config_alias return processor_sampler.ProcessorSampler( diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index d1c85e0d46b..f0b24cc4745 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -26,7 +26,7 @@ import cirq import cirq_google as cg from cirq_google.api import v2 -from cirq_google.engine import util +from cirq_google.engine import engine_client, util from cirq_google.engine.engine import EngineContext from cirq_google.cloud import quantum @@ -179,6 +179,27 @@ def _to_timestamp(json_string): ) +class FakeEngineClient(engine_client.EngineClient): + """Fake engine client for testing.""" + + @duet.sync + async def get_processor_async( + self, project_id: str = "", processor_id: str = "" + ) -> quantum.QuantumProcessor: + return quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey( + run="run", config_alias="config_alias" + ) + ) + + +class FakeEngineContext(EngineContext): + """Fake engine context for testing.""" + + def __init__(self): + self.client = FakeEngineClient() + + @pytest.fixture(scope='module', autouse=True) def mock_grpc_client(): with mock.patch( @@ -318,6 +339,18 @@ def test_get_sampler_initializes_default_device_configuration() -> None: assert sampler.device_config_name == "config_alias" +@mock.patch('cirq_google.engine.engine_client.EngineClient.get_processor_async') +def test_get_sampler_loads_processor_with_default_device_configuration(get_processor) -> None: + get_processor.return_value = quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey(run="run", config_alias="config_alias") + ) + processor = cg.EngineProcessor('a', 'p', EngineContext()) + sampler = processor.get_sampler() + + assert sampler.run_name == "run" + assert sampler.device_config_name == "config_alias" + + @mock.patch('cirq_google.engine.engine_client.EngineClient.list_calibrations_async') def test_list_calibrations(list_calibrations): list_calibrations.return_value = [_CALIBRATION] From 02e54c70e908f4546ec0c278ac5fdb822d7efd48 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 22:37:49 +0000 Subject: [PATCH 10/17] lint --- .../engine/engine_processor_test.py | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index f0b24cc4745..b14dc105ca5 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -182,22 +182,26 @@ def _to_timestamp(json_string): class FakeEngineClient(engine_client.EngineClient): """Fake engine client for testing.""" + def __init__(self): + super().__init__() + self._processor = quantum.QuantumProcessor() + @duet.sync async def get_processor_async( self, project_id: str = "", processor_id: str = "" ) -> quantum.QuantumProcessor: - return quantum.QuantumProcessor( - default_device_config_key=quantum.DeviceConfigKey( - run="run", config_alias="config_alias" - ) - ) + return self._processor + + def set_processor(self, processor: quantum.QuantumProcessor): + self._processor = processor class FakeEngineContext(EngineContext): """Fake engine context for testing.""" - def __init__(self): - self.client = FakeEngineClient() + def __init__(self, client: FakeEngineClient = FakeEngineClient()): + super().__init__() + self.client = client @pytest.fixture(scope='module', autouse=True) @@ -339,12 +343,16 @@ def test_get_sampler_initializes_default_device_configuration() -> None: assert sampler.device_config_name == "config_alias" -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_processor_async') -def test_get_sampler_loads_processor_with_default_device_configuration(get_processor) -> None: - get_processor.return_value = quantum.QuantumProcessor( - default_device_config_key=quantum.DeviceConfigKey(run="run", config_alias="config_alias") +def test_get_sampler_loads_processor_with_default_device_configuration() -> None: + client = FakeEngineClient() + client.set_processor( + quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey( + run="run", config_alias="config_alias" + ) + ) ) - processor = cg.EngineProcessor('a', 'p', EngineContext()) + processor = cg.EngineProcessor('a', 'p', EngineContext(client=client)) sampler = processor.get_sampler() assert sampler.run_name == "run" From eaf153c8bf2a7b5e694b66449d7679af9509b7fb Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 22:46:40 +0000 Subject: [PATCH 11/17] use new FakeEngineContext --- cirq-google/cirq_google/engine/engine_processor_test.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index b14dc105ca5..32657de659d 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -186,9 +186,8 @@ def __init__(self): super().__init__() self._processor = quantum.QuantumProcessor() - @duet.sync - async def get_processor_async( - self, project_id: str = "", processor_id: str = "" + def get_processor( + self, unused_project_id: str = "", unused_processor_id: str = "" ) -> quantum.QuantumProcessor: return self._processor @@ -352,7 +351,7 @@ def test_get_sampler_loads_processor_with_default_device_configuration() -> None ) ) ) - processor = cg.EngineProcessor('a', 'p', EngineContext(client=client)) + processor = cg.EngineProcessor('a', 'p', FakeEngineContext(client=client)) sampler = processor.get_sampler() assert sampler.run_name == "run" From 0e1726e5048954f97ba4b16054925e73f2252f6a Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 22:56:19 +0000 Subject: [PATCH 12/17] typecheck --- cirq-google/cirq_google/engine/engine_processor_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 32657de659d..69e2dcfa3c2 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -187,7 +187,7 @@ def __init__(self): self._processor = quantum.QuantumProcessor() def get_processor( - self, unused_project_id: str = "", unused_processor_id: str = "" + self, project_id: str = "", processor_id: str = "" ) -> quantum.QuantumProcessor: return self._processor From 53a66a59d17ca4ccf0d6faa7c5055603d0288eef Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 25 Mar 2024 23:03:14 +0000 Subject: [PATCH 13/17] lint , local env not catching CI errors --- cirq-google/cirq_google/engine/engine_processor_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 69e2dcfa3c2..2c3d1ead127 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -186,7 +186,8 @@ def __init__(self): super().__init__() self._processor = quantum.QuantumProcessor() - def get_processor( + @duet.sync + async def get_processor_async( self, project_id: str = "", processor_id: str = "" ) -> quantum.QuantumProcessor: return self._processor From 10d42bba3473765e44a22ddad8d6fc86c1ba6ff9 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Tue, 26 Mar 2024 00:03:47 +0000 Subject: [PATCH 14/17] signature of fakes match real impls --- cirq-google/cirq_google/engine/engine_processor_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 2c3d1ead127..d58f6a72864 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -186,12 +186,13 @@ def __init__(self): super().__init__() self._processor = quantum.QuantumProcessor() - @duet.sync async def get_processor_async( self, project_id: str = "", processor_id: str = "" ) -> quantum.QuantumProcessor: return self._processor + get_processor = duet.sync(get_processor_async) + def set_processor(self, processor: quantum.QuantumProcessor): self._processor = processor From 85c28c418eec4d8a17b84b47e92223322de6dc58 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Tue, 26 Mar 2024 18:44:00 +0000 Subject: [PATCH 15/17] add logic to initialize default values instead of throwing value error --- .../cirq_google/engine/engine_processor.py | 13 +++- .../engine/engine_processor_test.py | 65 ++++++++++++------- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 7552172b00f..a15c51fb529 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -14,6 +14,7 @@ import datetime +import logging from typing import Dict, List, Optional, TYPE_CHECKING, Union from google.protobuf import any_pb2 @@ -113,7 +114,17 @@ def get_sampler( when sampled. """ processor = self._inner_processor() - if processor is not None: + # If a run_name or config_alias is not provided, initialize them + # to the Processor's default values. + if not run_name or not device_config_name: + logging.basicConfig(level=logging.INFO) + logging.info( + "Cannot specify only one of `run_name` and `device_config_name`. Defaulting to the default values.\n" + "Default run_name: `%s`\n" + "Default device_config_name: `%s`\n", + processor.default_device_config_key.run, + processor.default_device_config_key.config_alias, + ) run_name = processor.default_device_config_key.run device_config_name = processor.default_device_config_key.config_alias return processor_sampler.ProcessorSampler( diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index d58f6a72864..7aea6220e05 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -179,28 +179,10 @@ def _to_timestamp(json_string): ) -class FakeEngineClient(engine_client.EngineClient): - """Fake engine client for testing.""" - - def __init__(self): - super().__init__() - self._processor = quantum.QuantumProcessor() - - async def get_processor_async( - self, project_id: str = "", processor_id: str = "" - ) -> quantum.QuantumProcessor: - return self._processor - - get_processor = duet.sync(get_processor_async) - - def set_processor(self, processor: quantum.QuantumProcessor): - self._processor = processor - - class FakeEngineContext(EngineContext): """Fake engine context for testing.""" - def __init__(self, client: FakeEngineClient = FakeEngineClient()): + def __init__(self, client: engine_client.EngineClient): super().__init__() self.client = client @@ -344,15 +326,48 @@ def test_get_sampler_initializes_default_device_configuration() -> None: assert sampler.device_config_name == "config_alias" -def test_get_sampler_loads_processor_with_default_device_configuration() -> None: - client = FakeEngineClient() - client.set_processor( - quantum.QuantumProcessor( +def test_get_sampler_uses_custom_default_device_configuration_key() -> None: + processor = cg.EngineProcessor( + 'a', + 'p', + EngineContext(), + _processor=quantum.QuantumProcessor( default_device_config_key=quantum.DeviceConfigKey( - run="run", config_alias="config_alias" + run="default_run", config_alias="default_config_alias" ) - ) + ), ) + sampler = processor.get_sampler(run_name="run1", device_config_name="config_alias1") + + assert sampler.run_name == "run1" + assert sampler.device_config_name == "config_alias1" + + +@pytest.mark.parametrize('run, config_alias', [('run', ''), ('', 'config')]) +def test_get_sampler_with_incomplete_device_configuration_uses_defaults(run, config_alias) -> None: + processor = cg.EngineProcessor( + 'a', + 'p', + EngineContext(), + _processor=quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey( + run="default_run", config_alias="default_config_alias" + ) + ), + ) + + sampler = processor.get_sampler(run_name=run, device_config_name=config_alias) + + assert sampler.run_name == "default_run" + assert sampler.device_config_name == "default_config_alias" + + +def test_get_sampler_loads_processor_with_default_device_configuration() -> None: + client = mock.Mock(engine_client.EngineClient) + client.get_processor.return_value = quantum.QuantumProcessor( + default_device_config_key=quantum.DeviceConfigKey(run="run", config_alias="config_alias") + ) + processor = cg.EngineProcessor('a', 'p', FakeEngineContext(client=client)) sampler = processor.get_sampler() From 4848cb039b95e5bd3fc4432bff37bb40c161ca4e Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Tue, 26 Mar 2024 18:45:50 +0000 Subject: [PATCH 16/17] lint --- cirq-google/cirq_google/engine/engine_processor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index a15c51fb529..d2cf9aeefff 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -81,6 +81,8 @@ def __init__( self.context = context self._processor = _processor + logging.basicConfig(level=logging.INFO) + def __repr__(self) -> str: return ( f' Date: Tue, 26 Mar 2024 16:47:51 -0700 Subject: [PATCH 17/17] rm logging and prefer to throw value error --- cirq-google/cirq_google/engine/engine_processor.py | 13 +------------ .../cirq_google/engine/engine_processor_test.py | 8 ++++---- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index d2cf9aeefff..df5e498a4d6 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -14,7 +14,6 @@ import datetime -import logging from typing import Dict, List, Optional, TYPE_CHECKING, Union from google.protobuf import any_pb2 @@ -81,8 +80,6 @@ def __init__( self.context = context self._processor = _processor - logging.basicConfig(level=logging.INFO) - def __repr__(self) -> str: return ( f' None: