Skip to content

Commit d077532

Browse files
authored
Add a new proto DeviceParametersDiff which provides a compact way to bundle multiple DeviceParameters and their values (#6583)
The new proto `DeviceParametersDiff` is for a user to compose a RunJobRequest for invoking RunJob rpc on a Cirq server, in particular to populate the `RunJobRequest.run_context` field with device parameters overrides to customize the circuit(s) execution with some control on the device's samples data. This is based on a design reviews to add "device parameters overrides" before executing circuits sweeping. I renamed some proto type names from similar internal data structure to prevent reference to internal infrastructures.
1 parent 6709046 commit d077532

File tree

5 files changed

+405
-20
lines changed

5 files changed

+405
-20
lines changed

cirq-google/cirq_google/api/v2/run_context.proto

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
syntax = "proto3";
22

3+
import "cirq_google/api/v2/program.proto";
4+
35
package cirq.google.api.v2;
46

57
option java_package = "com.google.cirq.google.api.v2";
@@ -10,6 +12,13 @@ option java_multiple_files = true;
1012
message RunContext {
1113
// The parameters for operations in a program.
1214
repeated ParameterSweep parameter_sweeps = 1;
15+
16+
// Optional override of select device parameters before program
17+
// execution. Note it is permissible to specify the same device parameter
18+
// here and in a parameter_sweeps, as sweep.single_sweep.parameter.
19+
// If the same parameter is supplied in both places, the provision here in
20+
// device_parameters_override will have no effect.
21+
DeviceParametersDiff device_parameters_override = 2;
1322
}
1423

1524
// Specifies how to repeatedly sample a circuit, with or without sweeping over
@@ -100,6 +109,41 @@ message DeviceParameter {
100109
// by the sweep values themselves.
101110
}
102111

112+
// A bundle of multiple DeviceParameters and their values.
113+
// The main use case is to set those parameters with the
114+
// values from this bundle before executing a circuit sweep.
115+
// Note multiple device parameters may have common ancestor paths
116+
// and/or share the same parameter names. A DeviceParametersDiff
117+
// stores the resource groups hierarchy extracted from the DeviceParameters'
118+
// paths and maintains a table of strings; thereby storing ancestor resource
119+
// groups only once, and avoiding repeated storage of common parameter names.
120+
message DeviceParametersDiff {
121+
// A resource group a device parameter belongs to.
122+
// The identifier of a resource group is DeviceParameter.path without the
123+
// last component.
124+
message ResourceGroup {
125+
// parent resource group, as an index into the groups repeated field.
126+
int32 parent = 1;
127+
// as index into the strs repeated field.
128+
int32 name = 2;
129+
}
130+
message Param {
131+
// the resource group hosting this parameter key, as index into groups
132+
// repeated field.
133+
int32 resource_group = 1;
134+
// name of this param, as index into the strs repeated field.
135+
int32 name = 2;
136+
// this param's new value, as message ArgValue to allow variant types,
137+
// including bool, string, double, float and arrays.
138+
ArgValue value = 3;
139+
}
140+
repeated ResourceGroup groups = 1;
141+
repeated Param params = 2;
142+
143+
// List of all key, dir, and deletion names in these contents.
144+
// ResourceGroup.name, Param.name, and Deletion.name are indexes into this list.
145+
repeated string strs = 4;
146+
}
103147

104148
// A set of values to loop over for a particular parameter.
105149
message SingleSweep {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2024 The Cirq Developers
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import functools
16+
from typing import Sequence
17+
from cirq_google.api.v2 import program_pb2
18+
from cirq_google.api.v2 import run_context_pb2
19+
20+
21+
# The special index of an empty directory path [].
22+
_EMPTY_RESOURCE_PATH_IDX = -1
23+
24+
25+
def to_device_parameters_diff(
26+
device_params: Sequence[tuple[run_context_pb2.DeviceParameter, program_pb2.ArgValue]]
27+
) -> run_context_pb2.DeviceParametersDiff:
28+
"""Constructs a DeviceParametersDiff from multiple DeviceParameters and values.
29+
30+
Args:
31+
device_params: a list of (DeviceParameter, value) pairs.
32+
33+
Returns:
34+
a DeviceParametersDiff, which comprises the entire device_params.
35+
"""
36+
diff = run_context_pb2.DeviceParametersDiff()
37+
38+
@functools.lru_cache(maxsize=None)
39+
def token_id(s: str) -> int:
40+
"""Computes the index of s in the string table diff.strs."""
41+
idx = len(diff.strs)
42+
diff.strs.append(s)
43+
return idx
44+
45+
# Maps a resource group path to its index in diff.groups.
46+
resource_groups_index: dict[tuple[str, ...], int] = {tuple(): _EMPTY_RESOURCE_PATH_IDX}
47+
48+
def resource_path_id(path: tuple[str, ...]) -> int:
49+
"""Computes the index of a path in diff.groups."""
50+
idx = resource_groups_index.get(path, None)
51+
if idx is not None:
52+
return idx
53+
# Recursive call to get the assigned index of the parent. Note the base case
54+
# of the empty path, which returns _EMPTY_RESOURCE_PATH_IDX.
55+
parent_id = resource_path_id(path[:-1])
56+
# This path has not been seen. It will be appended to diff.groups, with idx as
57+
# the size of diff.groups before appending.
58+
idx = len(diff.groups)
59+
diff.groups.add(parent=parent_id, name=token_id(path[-1]))
60+
resource_groups_index[path] = idx
61+
return idx
62+
63+
for device_param, value in device_params:
64+
resource_path = tuple(device_param.path[:-1])
65+
param_name = device_param.path[-1]
66+
path_id = resource_path_id(resource_path)
67+
diff.params.add(name=token_id(param_name), resource_group=path_id, value=value)
68+
69+
return diff

cirq-google/cirq_google/api/v2/run_context_pb2.py

Lines changed: 27 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cirq-google/cirq_google/api/v2/run_context_pb2.pyi

Lines changed: 101 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)