Add a new proto DeviceParametersDiff which provides a compact way to bundle multiple DeviceParameters and their values#6583
Conversation
…ay to bundle multiple DeviceParameters and their values
|
cc @dstrain115 |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6583 +/- ##
=======================================
Coverage 97.81% 97.81%
=======================================
Files 1061 1063 +2
Lines 91455 91501 +46
=======================================
+ Hits 89454 89500 +46
Misses 2001 2001 ☔ View full report in Codecov by Sentry. |
| // DeviceParametersDiff from a list of (DeviceParameter, ArgValue) pairs. | ||
| message DeviceParametersDiff { | ||
| message Dir { | ||
| int32 parent = 1; |
There was a problem hiding this comment.
This should explain that this is an index into the strs array.
Also should clarify that -1 means root.
There was a problem hiding this comment.
comments added to indicate the various int32 fields as indices into which arrays, among groups and strs.
| dirs_seen: set[tuple[int, int]] = set() | ||
|
|
||
| for device_param, value in device_params: | ||
| parent = -1 # no parent for the 1st path component |
There was a problem hiding this comment.
I think "-1" should be a constant, as we will likely need it for decoding the diff too.
There was a problem hiding this comment.
added a constant of -1, with comment.
senecameeks
left a comment
There was a problem hiding this comment.
How will users interact with this new proto? IIUC, the internal diff proto has an abstraction layer that clients can easily interact with for creating a Diff which can then be easily packaged into its proto form. Can a similar well defined abstraction layer e.g class DeviceParameterDiff exist for this proto as well? It doesn't have to include all the APIs as the one linked, but a clear abstraction layer will help me see how this proto will later get integrated into a Job's run context. WDYT?
thanks for the comment. the PR includes a helper function to construct a DeviceParametersDiff proto out of a list of DeviceParameter and their values. please see the module run_context.py in this PR. Suppose you want to override some readout parameters on 2 qubits, and build a RunContext proto with such overrides, you may use the following code |
| // See run_context.py for utility function to construct a | ||
| // DeviceParametersDiff from a list of (DeviceParameter, ArgValue) pairs. | ||
| message DeviceParametersDiff { | ||
| message Dir { |
There was a problem hiding this comment.
Avoid abbreviation, here and below: go/pystyle#naming
There was a problem hiding this comment.
rename from "Dir" to "ResourceGroup"
| // The parameters for operations in a program. | ||
| repeated ParameterSweep parameter_sweeps = 1; | ||
|
|
||
| // optional override of select device parameters before program |
There was a problem hiding this comment.
Is it valid for both the parameter_sweeps and device_parameter_override to specify the same parameter(s)? The ordering of these two is ambiguous, which only makes sense if they're disjoint, but either way it should be documented.
There was a problem hiding this comment.
good catch. yes the proto definition allows such overlap. however the override will have no effect since it is applied before the circuit sweep is executed.
I have put in proto field comment to document such case.
| """ | ||
| diff = run_context_pb2.DeviceParametersDiff() | ||
|
|
||
| # Maps a string to its token id. A string is a component of a device parameter's path |
| } | ||
| message Key { | ||
| // directory hosting this key, as index into dirs array. | ||
| int32 dir = 1; |
There was a problem hiding this comment.
Why does Key reference the dir index rather than just being a sub-message?
| int32 name = 2; | ||
| ArgValue value = 3; | ||
| } | ||
| message Del { |
There was a problem hiding this comment.
Could deletions be incorporated into the Dir as a list of strings indicating keys that should be deleted?
| import google.protobuf.text_format as text_format | ||
|
|
||
|
|
||
| def test_to_device_parameters_diff() -> None: |
There was a problem hiding this comment.
Test names should summarize the behavior being tested and its expected outcome.
go/unit-testing-practices#naming
There was a problem hiding this comment.
renamed the test to call out the behavior to be tested.
| strs: "phase_i_rad" | ||
| strs: "q5_6" | ||
| """ | ||
| assert text_format.Parse(expected_diff_pb_text, run_context_pb2.DeviceParametersDiff()) == diff |
There was a problem hiding this comment.
Test behaviors, not methods.
Behaviors should be tested independently.
go/unit-testing-practices#behavior-testing-examples
|
friendly ping @senecameeks and @dstrain115 |
dstrain115
left a comment
There was a problem hiding this comment.
Some final comments, then LGTM
| // Optional override of select device parameters before program | ||
| // execution. Note it is permissible to specify the same device parameter | ||
| // here and in a parameter_sweeps, as sweep.single_sweep.parameter. | ||
| // However the override will have no effect since it is applied before |
There was a problem hiding this comment.
This wording is confusing. Can we clarify it? Maybe something like "If the same parameter is supplied in both places, then XYZ will happen"
There was a problem hiding this comment.
reworded the docstring here.
senecameeks
left a comment
There was a problem hiding this comment.
A few nits but overall LGTM
Thanks, Kim-Ming!
| // The main use case is to set those parameters with the | ||
| // values from this bundle before executing a circuit sweep. | ||
| // Note multiple device parameters may have common ancestor paths | ||
| // and/or share the same parameter names. A DeviceParamaetersDiff |
| // Note multiple device parameters may have common ancestor paths | ||
| // and/or share the same parameter names. A DeviceParamaetersDiff | ||
| // stores the resource groups hierarchy extracted from the DeviceParameters' | ||
| // paths and maintains a string tables; thereby storing ancestor resource |
There was a problem hiding this comment.
Nit: should this be maintains a table of strings
There was a problem hiding this comment.
updated per suggested.
| def to_device_parameters_diff( | ||
| device_params: Sequence[tuple[run_context_pb2.DeviceParameter, program_pb2.ArgValue]] | ||
| ) -> run_context_pb2.DeviceParametersDiff: | ||
| """Constructs a DeviceParametersDiff from multiple DeviceParameters and values |
|
|
||
| def resource_path_id(path: tuple[str, ...]) -> int: | ||
| """Computes the index of a path in diff.groups.""" | ||
| idx = resource_groups_index.get(path) |
There was a problem hiding this comment.
Nit: prefer explicitly setting a default resource_groups_index.get(path, None)
…bundle multiple DeviceParameters and their values (quantumlib#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.
The new proto
DeviceParametersDiffis for a user to compose a RunJobRequest for invoking RunJob rpc on a Cirq server, in particular to populate theRunJobRequest.run_contextfield 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.