20
20
import cirq
21
21
from cirq .study import sweeps
22
22
from cirq_google .api .v2 import run_context_pb2
23
- from cirq_google .study .device_parameter import DeviceParameter
23
+ from cirq_google .study .device_parameter import DeviceParameter , Metadata
24
24
25
25
26
26
def _build_sweep_const (value : Any ) -> run_context_pb2 .ConstValue :
@@ -116,13 +116,17 @@ def sweep_to_proto(
116
116
out .single_sweep .linspace .first_point = sweep .start
117
117
out .single_sweep .linspace .last_point = sweep .stop
118
118
out .single_sweep .linspace .num_points = sweep .length
119
- # Use duck-typing to support google-internal Parameter objects
120
- if sweep .metadata and getattr (sweep .metadata , 'path' , None ):
121
- out .single_sweep .parameter .path .extend (sweep .metadata .path )
122
- if sweep .metadata and getattr (sweep .metadata , 'idx' , None ):
123
- out .single_sweep .parameter .idx = sweep .metadata .idx
124
- if sweep .metadata and getattr (sweep .metadata , 'units' , None ):
125
- out .single_sweep .parameter .units = sweep .metadata .units
119
+ # Encode the metadata if present
120
+ if isinstance (sweep .metadata , Metadata ):
121
+ out .single_sweep .metadata .MergeFrom (metadata_to_proto (sweep .metadata ))
122
+ else :
123
+ # Use duck-typing to support google-internal Parameter objects
124
+ if sweep .metadata and getattr (sweep .metadata , 'path' , None ):
125
+ out .single_sweep .parameter .path .extend (sweep .metadata .path )
126
+ if sweep .metadata and getattr (sweep .metadata , 'idx' , None ):
127
+ out .single_sweep .parameter .idx = sweep .metadata .idx
128
+ if sweep .metadata and getattr (sweep .metadata , 'units' , None ):
129
+ out .single_sweep .parameter .units = sweep .metadata .units
126
130
elif isinstance (sweep , cirq .Points ) and not isinstance (sweep .key , sympy .Expr ):
127
131
sweep = cast (cirq .Points , sweep_transformer (sweep ))
128
132
out .single_sweep .parameter_key = sweep .key
@@ -135,13 +139,17 @@ def sweep_to_proto(
135
139
unit .to_proto (out .single_sweep .points .unit )
136
140
else :
137
141
out .single_sweep .points .points .extend (sweep .points )
138
- # Use duck-typing to support google-internal Parameter objects
139
- if sweep .metadata and getattr (sweep .metadata , 'path' , None ):
140
- out .single_sweep .parameter .path .extend (sweep .metadata .path )
141
- if sweep .metadata and getattr (sweep .metadata , 'idx' , None ):
142
- out .single_sweep .parameter .idx = sweep .metadata .idx
143
- if sweep .metadata and getattr (sweep .metadata , 'units' , None ):
144
- out .single_sweep .parameter .units = sweep .metadata .units
142
+ # Encode the metadata if present
143
+ if isinstance (sweep .metadata , Metadata ):
144
+ out .single_sweep .metadata .MergeFrom (metadata_to_proto (sweep .metadata ))
145
+ else :
146
+ # Use duck-typing to support google-internal Parameter objects
147
+ if sweep .metadata and getattr (sweep .metadata , 'path' , None ):
148
+ out .single_sweep .parameter .path .extend (sweep .metadata .path )
149
+ if sweep .metadata and getattr (sweep .metadata , 'idx' , None ):
150
+ out .single_sweep .parameter .idx = sweep .metadata .idx
151
+ if sweep .metadata and getattr (sweep .metadata , 'units' , None ):
152
+ out .single_sweep .parameter .units = sweep .metadata .units
145
153
elif isinstance (sweep , cirq .ListSweep ):
146
154
sweep_dict : Dict [str , List [float ]] = {}
147
155
for param_resolver in sweep :
@@ -190,6 +198,7 @@ def sweep_from_proto(
190
198
raise ValueError (f'invalid sweep function type: { func_type } ' )
191
199
if which == 'single_sweep' :
192
200
key = msg .single_sweep .parameter_key
201
+ metadata : DeviceParameter | Metadata | None
193
202
if msg .single_sweep .HasField ("parameter" ):
194
203
metadata = DeviceParameter (
195
204
path = msg .single_sweep .parameter .path ,
@@ -204,6 +213,8 @@ def sweep_from_proto(
204
213
else None
205
214
),
206
215
)
216
+ elif msg .single_sweep .HasField ("metadata" ):
217
+ metadata = metadata_from_proto (msg .single_sweep .metadata )
207
218
else :
208
219
metadata = None
209
220
@@ -245,6 +256,38 @@ def sweep_from_proto(
245
256
raise ValueError (f'sweep type not set: { msg } ' ) # pragma: no cover
246
257
247
258
259
+ def metadata_to_proto (metadata : Metadata ) -> run_context_pb2 .Metadata :
260
+ """Convert the metadata dataclass to the metadata proto."""
261
+ device_parameters : list [run_context_pb2 .DeviceParameter ] = []
262
+ if params := getattr (metadata , "device_parameters" , None ):
263
+ for param in params :
264
+ path = getattr (param , "path" , None )
265
+ idx = getattr (param , "idx" , None )
266
+ device_parameters .append (run_context_pb2 .DeviceParameter (path = path , idx = idx ))
267
+
268
+ return run_context_pb2 .Metadata (
269
+ device_parameters = device_parameters or None , # If empty set this field as None.
270
+ label = metadata .label ,
271
+ is_const = metadata .is_const ,
272
+ unit = metadata .unit ,
273
+ )
274
+
275
+
276
+ def metadata_from_proto (metadata_pb : run_context_pb2 .Metadata ) -> Metadata :
277
+ """Convert the metadata proto to the metadata dataclass."""
278
+ device_parameters : list [DeviceParameter ] = []
279
+ for param in metadata_pb .device_parameters :
280
+ device_parameters .append (
281
+ DeviceParameter (path = param .path , idx = param .idx if param .HasField ("idx" ) else None )
282
+ )
283
+ return Metadata (
284
+ device_parameters = device_parameters or None ,
285
+ label = metadata_pb .label if metadata_pb .HasField ("label" ) else None ,
286
+ is_const = metadata_pb .is_const ,
287
+ unit = metadata_pb .unit if metadata_pb .HasField ("unit" ) else None ,
288
+ )
289
+
290
+
248
291
def run_context_to_proto (
249
292
sweepable : cirq .Sweepable , repetitions : int , * , out : Optional [run_context_pb2 .RunContext ] = None
250
293
) -> run_context_pb2 .RunContext :
0 commit comments