Skip to content

Add qubit_attributes to GridDeviceMetadata and corresponding proto#8155

Open
BichengYing wants to merge 3 commits into
quantumlib:mainfrom
BichengYing:u/ybc/qubit_attributes
Open

Add qubit_attributes to GridDeviceMetadata and corresponding proto#8155
BichengYing wants to merge 3 commits into
quantumlib:mainfrom
BichengYing:u/ybc/qubit_attributes

Conversation

@BichengYing

Copy link
Copy Markdown
Collaborator

This will allow us to have more room to add custom qubit corresponding information to the external users in the future. This change should be backward and forward compatible

…roto message definition

This will allow use to have more room to add custom qubit corresponding information to the external users in the future. This change should be backward and forwar compatible
@BichengYing BichengYing requested review from a team, hoisinberg, verult and wcourtney as code owners June 18, 2026 18:59
@github-actions github-actions Bot added the size: L 250< lines changed <1000 label Jun 18, 2026
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.60%. Comparing base (8cb539e) to head (690dddc).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8155   +/-   ##
=======================================
  Coverage   99.60%   99.60%           
=======================================
  Files        1118     1118           
  Lines      101048   101145   +97     
=======================================
+ Hits       100647   100745   +98     
+ Misses        401      400    -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pavoljuhas pavoljuhas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should include some example attributes in GridDeviceMetadata.json and GridDeviceMetadata.repr, as well as their initial form to verify legacy json and repr data.

Also it might be better to use a mapping instead of repeated message to express the attributes in a proto.

Unless strongly justified, it should be better to disallow attributes (i.e., fail proto validation) for unknown qubits in GridDevice.

Otherwise LGTM in general.

'all_qubits': sorted(self.qubit_set),
'compilation_target_gatesets': list(self._compilation_target_gatesets),
'qubit_attributes': sorted(
[(q, sorted(attrs.items())) for q, attrs in self._qubit_attributes.items()],

@pavoljuhas pavoljuhas Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making the qubit_attributes item optional only when set. That way it might be possible to leave GridDevice.json and GridDevice.repr unchanged.

Nit - no need for throw-away list (same on line 195):

Suggested change
[(q, sorted(attrs.items())) for q, attrs in self._qubit_attributes.items()],
((q, sorted(attrs.items())) for q, attrs in self._qubit_attributes.items()),

dict(gate_durations) if gate_durations is not None else None,
all_qubits,
compilation_target_gatesets,
dict(qubit_attributes) if qubit_attributes is not None else None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qubit_attributes is already copied in __init__, just pass it as is:

Suggested change
dict(qubit_attributes) if qubit_attributes is not None else None,
qubit_attributes,

gate_durations: Mapping[cirq.GateFamily, cirq.Duration] | None = None,
all_qubits: Iterable[cirq.GridQubit] | None = None,
compilation_target_gatesets: Iterable[cirq.CompilationTargetGateset] = (),
qubit_attributes: Mapping[cirq.GridQubit, Mapping[str, Any]] | None = None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide typing consistent with the QubitAttributeValue proto instead of Any?
This could be done with a TypeVar, for example,

TQubitAttributeValue = TypeVar("TQubitAttributeValue", bound=bool | int | float | str)

Comment on lines +223 to +225
# test JSON serialization
rep_str = cirq.to_json(metadata)
assert metadata == cirq.read_json(json_text=rep_str)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to test_griddevice_json_load above.

Comment on lines +227 to +228
# test repr
cirq.testing.assert_equivalent_repr(metadata)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to test_repr above.

self._metadata = metadata

@property
def qubit_attributes(self) -> Mapping[cirq.GridQubit, Mapping[str, Any]]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reuse the TQubitAttributeValue type annotation suggested above.

Comment on lines +512 to +520
val_proto = entry.value
which_val = val_proto.WhichOneof("val")
if which_val == "bool_value":
attrs[entry.name] = val_proto.bool_value
elif which_val == "int_value":
attrs[entry.name] = val_proto.int_value
elif which_val == "double_value":
attrs[entry.name] = val_proto.double_value
elif which_val == "string_value":

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(i) Please move this conversion to a local helper function.
(ii) also, please rewrite as a match-case statement like here

string developer_recommendations = 4;

// Qubit attributes for the device.
repeated QubitAttributes qubit_attributes = 6;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a map<string, QubitAttributes> instead? That way there could be no duplicate entries for some qubit.

Comment on lines +208 to +209
string qubit = 1;
repeated QubitAttributeEntry attributes = 2;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar as above, this could just have one field of map<string, QubitAttributeValue> attributes which would prevent duplicate specification of some attribute.

Comment on lines +872 to +874
# Add attributes for an unlisted qubit
qa = spec.qubit_attributes.add()
qa.qubit = "10_10" # Not in valid_qubits

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this behavior required?

On a first look the qubit_attributes keys should be consistent with the qubits present in the device, so this should raise an error in _validate_device_specification.

If unsure, I'd suggest to leave out this test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: L 250< lines changed <1000

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants