-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add qubit_attributes to GridDeviceMetadata and corresponding proto #8155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -17,7 +17,7 @@ | |||||
| from __future__ import annotations | ||||||
|
|
||||||
| from collections.abc import Iterable, Mapping | ||||||
| from typing import cast, TYPE_CHECKING | ||||||
| from typing import Any, cast, TYPE_CHECKING | ||||||
|
|
||||||
| import networkx as nx | ||||||
|
|
||||||
|
|
@@ -39,6 +39,7 @@ def __init__( | |||||
| 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, | ||||||
| ): | ||||||
| """Create a GridDeviceMetadata object. | ||||||
|
|
||||||
|
|
@@ -117,6 +118,11 @@ def __init__( | |||||
| ) | ||||||
|
|
||||||
| self._gate_durations = gate_durations | ||||||
| self._qubit_attributes = ( | ||||||
| {q: dict(attrs) for q, attrs in qubit_attributes.items()} | ||||||
| if qubit_attributes is not None | ||||||
| else {} | ||||||
| ) | ||||||
|
|
||||||
| @property | ||||||
| def qubit_set(self) -> frozenset[cirq.GridQubit]: | ||||||
|
|
@@ -175,25 +181,37 @@ def gate_durations(self) -> Mapping[cirq.GateFamily, cirq.Duration] | None: | |||||
|
|
||||||
| return self._gate_durations | ||||||
|
|
||||||
| @property | ||||||
| def qubit_attributes(self) -> Mapping[cirq.GridQubit, Mapping[str, Any]]: | ||||||
| """Returns a mapping from qubit to its attributes (if applicable).""" | ||||||
| return self._qubit_attributes | ||||||
|
|
||||||
| def _value_equality_values_(self): | ||||||
| duration_equality = '' | ||||||
| if self._gate_durations is not None: | ||||||
| duration_equality = sorted(self._gate_durations.items(), key=lambda x: repr(x[0])) | ||||||
|
|
||||||
| attributes_equality = sorted( | ||||||
| [(q, tuple(sorted(attrs.items()))) for q, attrs in self._qubit_attributes.items()], | ||||||
| key=lambda x: x[0], | ||||||
| ) | ||||||
|
|
||||||
| return ( | ||||||
| self._qubit_pairs, | ||||||
| self._gateset, | ||||||
| tuple(duration_equality), | ||||||
| tuple(sorted(self.qubit_set)), | ||||||
| frozenset(self._compilation_target_gatesets), | ||||||
| tuple(attributes_equality), | ||||||
| ) | ||||||
|
|
||||||
| def __repr__(self) -> str: | ||||||
| qubit_pair_tuples = frozenset({tuple(sorted(p)) for p in self._qubit_pairs}) | ||||||
| return ( | ||||||
| f'cirq.GridDeviceMetadata({repr(qubit_pair_tuples)},' | ||||||
| f' {repr(self._gateset)}, {repr(self._gate_durations)},' | ||||||
| f' {repr(self.qubit_set)}, {repr(self._compilation_target_gatesets)})' | ||||||
| f' {repr(self.qubit_set)}, {repr(self._compilation_target_gatesets)},' | ||||||
| f' {repr(self._qubit_attributes)})' | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we turn |
||||||
| ) | ||||||
|
|
||||||
| def _json_dict_(self): | ||||||
|
|
@@ -207,6 +225,10 @@ def _json_dict_(self): | |||||
| 'gate_durations': duration_payload, | ||||||
| '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()], | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider making the Nit - no need for throw-away list (same on line 195):
Suggested change
|
||||||
| key=lambda x: x[0], | ||||||
| ), | ||||||
| } | ||||||
|
|
||||||
| @classmethod | ||||||
|
|
@@ -217,6 +239,7 @@ def _from_json_dict_( | |||||
| gate_durations, | ||||||
| all_qubits, | ||||||
| compilation_target_gatesets=(), | ||||||
| qubit_attributes=None, | ||||||
| **kwargs, | ||||||
| ): | ||||||
| return cls( | ||||||
|
|
@@ -225,4 +248,5 @@ def _from_json_dict_( | |||||
| 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, | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ) | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,8 @@ | |||||
|
|
||||||
| from __future__ import annotations | ||||||
|
|
||||||
| from typing import Any | ||||||
|
|
||||||
| import networkx as nx | ||||||
| import pytest | ||||||
|
|
||||||
|
|
@@ -202,3 +204,43 @@ def test_repr() -> None: | |||||
| compilation_target_gatesets=target_gatesets, | ||||||
| ) | ||||||
| cirq.testing.assert_equivalent_repr(metadata) | ||||||
|
|
||||||
|
|
||||||
| def test_griddevice_metadata_qubit_attributes() -> None: | ||||||
| qubits = cirq.GridQubit.rect(1, 2) | ||||||
| gateset = cirq.Gateset(cirq.XPowGate) | ||||||
| qubit_attributes: dict[cirq.GridQubit, dict[str, Any]] = { | ||||||
| cirq.GridQubit(0, 0): {"type": "transmon", "frequency": 5.1}, | ||||||
| cirq.GridQubit(0, 1): {"index": 42}, | ||||||
| } | ||||||
|
|
||||||
| metadata = cirq.GridDeviceMetadata( | ||||||
| qubit_pairs=[], gateset=gateset, all_qubits=qubits, qubit_attributes=qubit_attributes | ||||||
| ) | ||||||
|
|
||||||
| assert metadata.qubit_attributes == qubit_attributes | ||||||
|
|
||||||
| # test JSON serialization | ||||||
| rep_str = cirq.to_json(metadata) | ||||||
| assert metadata == cirq.read_json(json_text=rep_str) | ||||||
|
Comment on lines
+223
to
+225
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this to |
||||||
|
|
||||||
| # test repr | ||||||
| cirq.testing.assert_equivalent_repr(metadata) | ||||||
|
Comment on lines
+227
to
+228
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move to |
||||||
|
|
||||||
| # test equality | ||||||
| qubit_attributes2: dict[cirq.GridQubit, dict[str, Any]] = { | ||||||
|
Comment on lines
+230
to
+231
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please move equality tests to |
||||||
| cirq.GridQubit(0, 0): {"type": "transmon", "frequency": 5.1}, | ||||||
| cirq.GridQubit(0, 1): {"index": 43}, # different index | ||||||
| } | ||||||
| metadata2 = cirq.GridDeviceMetadata( | ||||||
| qubit_pairs=[], gateset=gateset, all_qubits=qubits, qubit_attributes=qubit_attributes2 | ||||||
| ) | ||||||
|
|
||||||
| metadata3 = cirq.GridDeviceMetadata( | ||||||
| qubit_pairs=[], gateset=gateset, all_qubits=qubits, qubit_attributes=None | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is better to leave out
Suggested change
|
||||||
| ) | ||||||
|
|
||||||
| eq = cirq.testing.EqualsTester() | ||||||
| eq.add_equality_group(metadata) | ||||||
| eq.add_equality_group(metadata2) | ||||||
| eq.add_equality_group(metadata3) | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -265,5 +265,6 @@ | |
| "required_sqrt_iswap_count": null, | ||
| "use_sqrt_iswap_inv": false | ||
| } | ||
| ] | ||
| ], | ||
| "qubit_attributes": [] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please fill with some actual data. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| cirq.GridDeviceMetadata(frozenset({(cirq.GridQubit(1, 1), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), (cirq.GridQubit(0, 2), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 1), cirq.GridQubit(0, 2))}), cirq.Gateset(cirq.ops.common_gates.XPowGate, cirq.ops.common_gates.YPowGate, cirq.ops.common_gates.ZPowGate, cirq.CZ, (cirq.ISWAP**0.5), unroll_circuit_op = True), {cirq.GateFamily(gate=cirq.ops.common_gates.XPowGate, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(nanos=1), cirq.GateFamily(gate=cirq.ops.common_gates.YPowGate, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=1), cirq.GateFamily(gate=cirq.ops.common_gates.ZPowGate, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=1), cirq.GateFamily(gate=cirq.CZ, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=500), cirq.GateFamily(gate=(cirq.ISWAP**0.5), ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=600)}, frozenset({cirq.GridQubit(1, 0), cirq.GridQubit(0, 2), cirq.GridQubit(9, 9), cirq.GridQubit(10, 10), cirq.GridQubit(0, 1), cirq.GridQubit(1, 1), cirq.GridQubit(0, 0), cirq.GridQubit(1, 2)}), (cirq.CZTargetGateset(atol=1e-08, allow_partial_czs=False), cirq.SqrtIswapTargetGateset(atol=1e-08, required_sqrt_iswap_count=None, use_sqrt_iswap_inv=False))) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please convert to a 2-item list in a similar fashion as suggested for GridDeviceMetadata.json above, ie, the first element is the original repr (without the qubit_attributes argument), and the second one a GDM with qubit_attributes set. Also, please format with |
||
| cirq.GridDeviceMetadata(frozenset({(cirq.GridQubit(1, 1), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), (cirq.GridQubit(0, 2), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 1), cirq.GridQubit(0, 2))}), cirq.Gateset(cirq.ops.common_gates.XPowGate, cirq.ops.common_gates.YPowGate, cirq.ops.common_gates.ZPowGate, cirq.CZ, (cirq.ISWAP**0.5), unroll_circuit_op = True), {cirq.GateFamily(gate=cirq.ops.common_gates.XPowGate, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(nanos=1), cirq.GateFamily(gate=cirq.ops.common_gates.YPowGate, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=1), cirq.GateFamily(gate=cirq.ops.common_gates.ZPowGate, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=1), cirq.GateFamily(gate=cirq.CZ, ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=500), cirq.GateFamily(gate=(cirq.ISWAP**0.5), ignore_global_phase=True, tags_to_accept=frozenset(), tags_to_ignore=frozenset()): cirq.Duration(picos=600)}, frozenset({cirq.GridQubit(1, 0), cirq.GridQubit(0, 2), cirq.GridQubit(9, 9), cirq.GridQubit(10, 10), cirq.GridQubit(0, 1), cirq.GridQubit(1, 1), cirq.GridQubit(0, 0), cirq.GridQubit(1, 2)}), (cirq.CZTargetGateset(atol=1e-08, allow_partial_czs=False), cirq.SqrtIswapTargetGateset(atol=1e-08, required_sqrt_iswap_count=None, use_sqrt_iswap_inv=False)), {}) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,9 @@ message DeviceSpecification { | |
| // are advice to users of the device, specified in English text | ||
| // For instance, "All Z gates are converted to VirtualZ gates". | ||
| string developer_recommendations = 4; | ||
|
|
||
| // Qubit attributes for the device. | ||
| repeated QubitAttributes qubit_attributes = 6; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be a |
||
| } | ||
|
|
||
| // This contains information about a single device gate. | ||
|
|
@@ -199,3 +202,25 @@ message Target { | |
| // A list of qubit ids that form a valid gate target. | ||
| repeated string ids = 1; | ||
| } | ||
|
|
||
| // Qubit attributes for a specific qubit. | ||
| message QubitAttributes { | ||
| string qubit = 1; | ||
| repeated QubitAttributeEntry attributes = 2; | ||
|
Comment on lines
+208
to
+209
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar as above, this could just have one field of |
||
| } | ||
|
|
||
| // A key-value entry representing a single qubit attribute. | ||
| message QubitAttributeEntry { | ||
| string name = 1; | ||
| QubitAttributeValue value = 2; | ||
| } | ||
|
|
||
| // A generic value for a qubit attribute. | ||
| message QubitAttributeValue { | ||
| oneof val { | ||
| string string_value = 1; | ||
| int64 int_value = 2; | ||
| double double_value = 3; | ||
| bool bool_value = 4; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
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,