Skip to content

Commit

Permalink
Make gate_sets actually optional (#4850)
Browse files Browse the repository at this point in the history
- mypy and pycharm need a default value in the abstract interface
in order to be truly optional.
- Also, add a copy of the inherited arguments in
SimulatedLocalProcessor.
  • Loading branch information
dstrain115 authored Jan 19, 2022
1 parent 745ee1b commit 8a78e10
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
10 changes: 8 additions & 2 deletions cirq-google/cirq_google/engine/abstract_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ def run_calibration(
"""

@abc.abstractmethod
def get_sampler(self, gate_set: Optional['serializer.Serializer']) -> cirq.Sampler:
def get_sampler(
self,
gate_set: Optional['serializer.Serializer'] = None,
) -> cirq.Sampler:
"""Returns a sampler backed by the processor.
Args:
Expand Down Expand Up @@ -279,7 +282,10 @@ def get_device_specification(self) -> Optional[v2.device_pb2.DeviceSpecification
"""

@abc.abstractmethod
def get_device(self, gate_sets: Iterable['serializer.Serializer']) -> cirq.Device:
def get_device(
self,
gate_sets: Iterable['serializer.Serializer'] = (),
) -> cirq.Device:
"""Returns a `Device` created from the processor's device specification.
This method queries the processor to retrieve the device specification,
Expand Down
17 changes: 14 additions & 3 deletions cirq-google/cirq_google/engine/engine_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
engine_sampler,
)
from cirq_google.serialization import circuit_serializer, serializable_gate_set, serializer
from cirq_google.serialization import gate_sets as gs

if TYPE_CHECKING:
import cirq_google.engine.engine as engine_base
Expand Down Expand Up @@ -95,13 +96,14 @@ def engine(self) -> 'engine_base.Engine':
return engine_base.Engine(self.project_id, context=self.context)

def get_sampler(
self, gate_set: Optional[serializer.Serializer]
self,
gate_set: Optional[serializer.Serializer] = None,
) -> engine_sampler.QuantumEngineSampler:
"""Returns a sampler backed by the engine.
Args:
gate_set: A `Serializer` that determines how to serialize circuits
when requesting samples.
when requesting samples. If not specified, uses proto v2.5 serialization.
Returns:
A `cirq.Sampler` instance (specifically a `engine_sampler.QuantumEngineSampler`
Expand Down Expand Up @@ -335,7 +337,10 @@ def get_device_specification(self) -> Optional[v2.device_pb2.DeviceSpecification
else:
return None

def get_device(self, gate_sets: Iterable[serializer.Serializer]) -> cirq.Device:
def get_device(
self,
gate_sets: Iterable[serializer.Serializer] = (),
) -> cirq.Device:
"""Returns a `Device` created from the processor's device specification.
This method queries the processor to retrieve the device specification,
Expand All @@ -345,6 +350,12 @@ def get_device(self, gate_sets: Iterable[serializer.Serializer]) -> cirq.Device:
spec = self.get_device_specification()
if not spec:
raise ValueError('Processor does not have a device specification')
if not gate_sets:
# Default is to use all named gatesets in the device spec
gate_sets = []
for valid_gate_set in spec.valid_gate_sets:
if valid_gate_set.name in gs.NAMED_GATESETS:
gate_sets.append(gs.NAMED_GATESETS[valid_gate_set.name])
if not all(isinstance(gs, serializable_gate_set.SerializableGateSet) for gs in gate_sets):
raise ValueError('All gate_sets must be SerializableGateSet currently.')
return serializable_device.SerializableDevice.from_proto(
Expand Down
19 changes: 19 additions & 0 deletions cirq-google/cirq_google/engine/engine_processor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from google.protobuf.timestamp_pb2 import Timestamp
import cirq
import cirq_google as cg
import cirq_google.devices.known_devices as known_devices
from cirq_google.api import v2
from cirq_google.engine.engine import EngineContext
from cirq_google.engine.client.quantum_v1alpha1 import enums as qenums
Expand Down Expand Up @@ -334,6 +335,24 @@ def test_get_device():
processor.get_device(gate_sets=[cg.serialization.circuit_serializer.CIRCUIT_SERIALIZER])


def test_default_gate_sets():
# Sycamore should have valid gate sets with default
processor = cg.EngineProcessor(
'a',
'p',
EngineContext(),
_processor=qtypes.QuantumProcessor(device_spec=_to_any(known_devices.SYCAMORE_PROTO)),
)
device = processor.get_device()
device.validate_operation(cirq.X(cirq.GridQubit(5, 4)))
# Test that a device with no standard gatesets doesn't blow up
processor = cg.EngineProcessor(
'a', 'p', EngineContext(), _processor=qtypes.QuantumProcessor(device_spec=_DEVICE_SPEC)
)
device = processor.get_device()
assert device.qubits == [cirq.GridQubit(0, 0), cirq.GridQubit(1, 1)]


def test_get_missing_device():
processor = cg.EngineProcessor('a', 'p', EngineContext(), _processor=qtypes.QuantumProcessor())
with pytest.raises(ValueError, match='device specification'):
Expand Down
9 changes: 9 additions & 0 deletions cirq-google/cirq_google/engine/simulated_local_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ class SimulatedLocalProcessor(AbstractLocalProcessor):
based on the given serializer.
calibrations: A dictionary of calibration metrics keyed by epoch seconds
that can be returned by the processor.
processor_id: Unique string id of the processor.
engine: The parent `AbstractEngine` object, if available.
expected_down_time: Optional datetime of the next expected downtime.
For informational purpose only.
expected_recovery_time: Optional datetime when the processor is
expected to be available again. For informational purpose only.
schedule: List of time slots that the scheduling/reservation should
use. All time slots must be non-overlapping.
project_name: A project_name for resource naming.
"""

def __init__(
Expand Down

0 comments on commit 8a78e10

Please sign in to comment.