|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
15 | 15 | import abc
|
16 |
| -from typing import TYPE_CHECKING, Optional, AbstractSet, cast, FrozenSet, Iterator |
| 16 | +from typing import TYPE_CHECKING, Optional, AbstractSet, cast, FrozenSet, Iterator, Iterable |
17 | 17 |
|
| 18 | +import networkx as nx |
18 | 19 | from cirq import value
|
19 | 20 | from cirq.devices.grid_qubit import _BaseGridQid
|
20 | 21 | from cirq.devices.line_qubit import _BaseLineQid
|
@@ -178,3 +179,77 @@ def __iter__(self) -> Iterator['cirq.Qid']:
|
178 | 179 |
|
179 | 180 | def __contains__(self, item: 'cirq.Qid') -> bool:
|
180 | 181 | return item in self.qids
|
| 182 | + |
| 183 | + |
| 184 | +@value.value_equality |
| 185 | +class DeviceMetadata: |
| 186 | + """Parent type for all device specific metadata classes.""" |
| 187 | + |
| 188 | + def __init__( |
| 189 | + self, |
| 190 | + qubits: Optional[Iterable['cirq.Qid']] = None, |
| 191 | + nx_graph: Optional['nx.graph'] = None, |
| 192 | + ): |
| 193 | + """Construct a DeviceMetadata object. |
| 194 | +
|
| 195 | + Args: |
| 196 | + qubits: Optional iterable of `cirq.Qid`s that exist on the device. |
| 197 | + nx_graph: Optional `nx.Graph` describing qubit connectivity |
| 198 | + on a device. Nodes represent qubits, directed edges indicate |
| 199 | + directional coupling, undirected edges indicate bi-directional |
| 200 | + coupling. |
| 201 | + """ |
| 202 | + if qubits is not None: |
| 203 | + qubits = frozenset(qubits) |
| 204 | + self._qubits_set: Optional[FrozenSet['cirq.Qid']] = ( |
| 205 | + None if qubits is None else frozenset(qubits) |
| 206 | + ) |
| 207 | + |
| 208 | + self._nx_graph = nx_graph |
| 209 | + |
| 210 | + def qubit_set(self) -> Optional[FrozenSet['cirq.Qid']]: |
| 211 | + """Returns a set of qubits on the device, if possible. |
| 212 | +
|
| 213 | + Returns: |
| 214 | + Frozenset of qubits on device if specified, otherwise None. |
| 215 | + """ |
| 216 | + return self._qubits_set |
| 217 | + |
| 218 | + def nx_graph(self) -> Optional['nx.Graph']: |
| 219 | + """Returns a nx.Graph where nodes are qubits and edges are couple-able qubits. |
| 220 | +
|
| 221 | + Returns: |
| 222 | + `nx.Graph` of device connectivity if specified, otherwise None. |
| 223 | + """ |
| 224 | + return self._nx_graph |
| 225 | + |
| 226 | + def _value_equality_values_(self): |
| 227 | + graph_equality = None |
| 228 | + if self._nx_graph is not None: |
| 229 | + graph_equality = (sorted(self._nx_graph.nodes()), sorted(self._nx_graph.edges())) |
| 230 | + |
| 231 | + qubit_equality = None |
| 232 | + if self._qubits_set is not None: |
| 233 | + qubit_equality = sorted(list(self._qubits_set)) |
| 234 | + |
| 235 | + return qubit_equality, graph_equality |
| 236 | + |
| 237 | + def _json_dict_(self): |
| 238 | + graph_payload = '' |
| 239 | + if self._nx_graph is not None: |
| 240 | + graph_payload = nx.readwrite.json_graph.node_link_data(self._nx_graph) |
| 241 | + |
| 242 | + qubits_payload = '' |
| 243 | + if self._qubits_set is not None: |
| 244 | + qubits_payload = sorted(list(self._qubits_set)) |
| 245 | + |
| 246 | + return {'qubits': qubits_payload, 'nx_graph': graph_payload} |
| 247 | + |
| 248 | + @classmethod |
| 249 | + def _from_json_dict_(cls, qubits, nx_graph, **kwargs): |
| 250 | + if qubits == '': |
| 251 | + qubits = None |
| 252 | + graph_obj = None |
| 253 | + if nx_graph != '': |
| 254 | + graph_obj = nx.readwrite.json_graph.node_link_graph(nx_graph) |
| 255 | + return cls(qubits, graph_obj) |
0 commit comments