Skip to content

Make gate_sets actually optional #4850

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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