diff --git a/cirq-google/cirq_google/api/v2/run_context.proto b/cirq-google/cirq_google/api/v2/run_context.proto index e0cf0a27fa3..e3722cb652a 100644 --- a/cirq-google/cirq_google/api/v2/run_context.proto +++ b/cirq-google/cirq_google/api/v2/run_context.proto @@ -90,11 +90,11 @@ message DeviceParameter { repeated string path = 1; // If the value is an array, the index of the array to change. - int64 idx = 2; + optional int64 idx = 2; // String representation of the units, if any. // Examples: "GHz", "ns", etc. - string units = 3; + optional string units = 3; // Note that the device parameter values will be populated // by the sweep values themselves. diff --git a/cirq-google/cirq_google/api/v2/run_context_pb2.py b/cirq-google/cirq_google/api/v2/run_context_pb2.py index 7d62e40f33a..ac1fbe25102 100644 --- a/cirq-google/cirq_google/api/v2/run_context_pb2.py +++ b/cirq-google/cirq_google/api/v2/run_context_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/run_context.proto\x12\x12\x63irq.google.api.v2\"J\n\nRunContext\x12<\n\x10parameter_sweeps\x18\x01 \x03(\x0b\x32\".cirq.google.api.v2.ParameterSweep\"O\n\x0eParameterSweep\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12(\n\x05sweep\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Sweep\"\x86\x01\n\x05Sweep\x12;\n\x0esweep_function\x18\x01 \x01(\x0b\x32!.cirq.google.api.v2.SweepFunctionH\x00\x12\x37\n\x0csingle_sweep\x18\x02 \x01(\x0b\x32\x1f.cirq.google.api.v2.SingleSweepH\x00\x42\x07\n\x05sweep\"\xc6\x01\n\rSweepFunction\x12\x45\n\rfunction_type\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.SweepFunction.FunctionType\x12)\n\x06sweeps\x18\x02 \x03(\x0b\x32\x19.cirq.google.api.v2.Sweep\"C\n\x0c\x46unctionType\x12\x1d\n\x19\x46UNCTION_TYPE_UNSPECIFIED\x10\x00\x12\x0b\n\x07PRODUCT\x10\x01\x12\x07\n\x03ZIP\x10\x02\";\n\x0f\x44\x65viceParameter\x12\x0c\n\x04path\x18\x01 \x03(\t\x12\x0b\n\x03idx\x18\x02 \x01(\x03\x12\r\n\x05units\x18\x03 \x01(\t\"\xc5\x01\n\x0bSingleSweep\x12\x15\n\rparameter_key\x18\x01 \x01(\t\x12,\n\x06points\x18\x02 \x01(\x0b\x32\x1a.cirq.google.api.v2.PointsH\x00\x12\x30\n\x08linspace\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.LinspaceH\x00\x12\x36\n\tparameter\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.DeviceParameterB\x07\n\x05sweep\"\x18\n\x06Points\x12\x0e\n\x06points\x18\x01 \x03(\x02\"G\n\x08Linspace\x12\x13\n\x0b\x66irst_point\x18\x01 \x01(\x02\x12\x12\n\nlast_point\x18\x02 \x01(\x02\x12\x12\n\nnum_points\x18\x03 \x01(\x03\x42\x32\n\x1d\x63om.google.cirq.google.api.v2B\x0fRunContextProtoP\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/run_context.proto\x12\x12\x63irq.google.api.v2\"J\n\nRunContext\x12<\n\x10parameter_sweeps\x18\x01 \x03(\x0b\x32\".cirq.google.api.v2.ParameterSweep\"O\n\x0eParameterSweep\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12(\n\x05sweep\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Sweep\"\x86\x01\n\x05Sweep\x12;\n\x0esweep_function\x18\x01 \x01(\x0b\x32!.cirq.google.api.v2.SweepFunctionH\x00\x12\x37\n\x0csingle_sweep\x18\x02 \x01(\x0b\x32\x1f.cirq.google.api.v2.SingleSweepH\x00\x42\x07\n\x05sweep\"\xc6\x01\n\rSweepFunction\x12\x45\n\rfunction_type\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.SweepFunction.FunctionType\x12)\n\x06sweeps\x18\x02 \x03(\x0b\x32\x19.cirq.google.api.v2.Sweep\"C\n\x0c\x46unctionType\x12\x1d\n\x19\x46UNCTION_TYPE_UNSPECIFIED\x10\x00\x12\x0b\n\x07PRODUCT\x10\x01\x12\x07\n\x03ZIP\x10\x02\"W\n\x0f\x44\x65viceParameter\x12\x0c\n\x04path\x18\x01 \x03(\t\x12\x10\n\x03idx\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x12\n\x05units\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04_idxB\x08\n\x06_units\"\xc5\x01\n\x0bSingleSweep\x12\x15\n\rparameter_key\x18\x01 \x01(\t\x12,\n\x06points\x18\x02 \x01(\x0b\x32\x1a.cirq.google.api.v2.PointsH\x00\x12\x30\n\x08linspace\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.LinspaceH\x00\x12\x36\n\tparameter\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.DeviceParameterB\x07\n\x05sweep\"\x18\n\x06Points\x12\x0e\n\x06points\x18\x01 \x03(\x02\"G\n\x08Linspace\x12\x13\n\x0b\x66irst_point\x18\x01 \x01(\x02\x12\x12\n\nlast_point\x18\x02 \x01(\x02\x12\x12\n\nnum_points\x18\x03 \x01(\x03\x42\x32\n\x1d\x63om.google.cirq.google.api.v2B\x0fRunContextProtoP\x01\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -33,11 +33,11 @@ _globals['_SWEEPFUNCTION_FUNCTIONTYPE']._serialized_start=486 _globals['_SWEEPFUNCTION_FUNCTIONTYPE']._serialized_end=553 _globals['_DEVICEPARAMETER']._serialized_start=555 - _globals['_DEVICEPARAMETER']._serialized_end=614 - _globals['_SINGLESWEEP']._serialized_start=617 - _globals['_SINGLESWEEP']._serialized_end=814 - _globals['_POINTS']._serialized_start=816 - _globals['_POINTS']._serialized_end=840 - _globals['_LINSPACE']._serialized_start=842 - _globals['_LINSPACE']._serialized_end=913 + _globals['_DEVICEPARAMETER']._serialized_end=642 + _globals['_SINGLESWEEP']._serialized_start=645 + _globals['_SINGLESWEEP']._serialized_end=842 + _globals['_POINTS']._serialized_start=844 + _globals['_POINTS']._serialized_end=868 + _globals['_LINSPACE']._serialized_start=870 + _globals['_LINSPACE']._serialized_end=941 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/run_context_pb2.pyi b/cirq-google/cirq_google/api/v2/run_context_pb2.pyi index 2c104967440..75afaa133e1 100644 --- a/cirq-google/cirq_google/api/v2/run_context_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/run_context_pb2.pyi @@ -214,10 +214,15 @@ class DeviceParameter(google.protobuf.message.Message): self, *, path: collections.abc.Iterable[builtins.str] | None = ..., - idx: builtins.int = ..., - units: builtins.str = ..., + idx: builtins.int | None = ..., + units: builtins.str | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["idx", b"idx", "path", b"path", "units", b"units"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["_idx", b"_idx", "_units", b"_units", "idx", b"idx", "units", b"units"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["_idx", b"_idx", "_units", b"_units", "idx", b"idx", "path", b"path", "units", b"units"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_idx", b"_idx"]) -> typing_extensions.Literal["idx"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_units", b"_units"]) -> typing_extensions.Literal["units"] | None: ... global___DeviceParameter = DeviceParameter diff --git a/cirq-google/cirq_google/api/v2/sweeps.py b/cirq-google/cirq_google/api/v2/sweeps.py index 0eb33e63bcf..6a6e1738424 100644 --- a/cirq-google/cirq_google/api/v2/sweeps.py +++ b/cirq-google/cirq_google/api/v2/sweeps.py @@ -105,7 +105,13 @@ def sweep_from_proto(msg: run_context_pb2.Sweep) -> cirq.Sweep: key = msg.single_sweep.parameter_key if msg.single_sweep.HasField("parameter"): metadata = DeviceParameter( - path=msg.single_sweep.parameter.path, idx=msg.single_sweep.parameter.idx + path=msg.single_sweep.parameter.path, + idx=msg.single_sweep.parameter.idx + if msg.single_sweep.parameter.HasField("idx") + else None, + units=msg.single_sweep.parameter.units + if msg.single_sweep.parameter.HasField("units") + else None, ) else: metadata = None diff --git a/cirq-google/cirq_google/api/v2/sweeps_test.py b/cirq-google/cirq_google/api/v2/sweeps_test.py index f4cc144b40b..30a44573d39 100644 --- a/cirq-google/cirq_google/api/v2/sweeps_test.py +++ b/cirq-google/cirq_google/api/v2/sweeps_test.py @@ -52,6 +52,11 @@ def _values(self) -> Iterator[float]: [1, 1.5, 2, 2.5, 3], metadata=DeviceParameter(path=['path', 'to', 'parameter'], idx=2, units='GHz'), ), + cirq.Points( + 'b', + [1, 1.5, 2, 2.5, 3], + metadata=DeviceParameter(path=['path', 'to', 'parameter'], idx=None), + ), cirq.Linspace('a', 0, 1, 5) * cirq.Linspace('b', 0, 1, 5), cirq.Points('a', [1, 2, 3]) + cirq.Linspace('b', 0, 1, 3), ( @@ -69,6 +74,8 @@ def test_sweep_to_proto_roundtrip(sweep): msg = v2.sweep_to_proto(sweep) deserialized = v2.sweep_from_proto(msg) assert deserialized == sweep + # Check that metadata is the same, if it exists. + assert getattr(deserialized, 'metadata', None) == getattr(sweep, 'metadata', None) def test_sweep_to_proto_linspace():