Skip to content

Commit

Permalink
DeviceMetadata docs update. (#4963)
Browse files Browse the repository at this point in the history
Closes #4962
  • Loading branch information
MichaelBroughton authored Feb 8, 2022
1 parent c20c99b commit 5eae221
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 87 deletions.
14 changes: 7 additions & 7 deletions cirq-core/cirq/devices/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,13 @@ class DeviceMetadata:
def __init__(
self,
qubits: Iterable['cirq.Qid'],
nx_graph: 'nx.graph',
nx_graph: 'nx.Graph',
):
"""Construct a DeviceMetadata object.
Args:
qubits: Optional iterable of `cirq.Qid`s that exist on the device.
nx_graph: Optional `nx.Graph` describing qubit connectivity
qubits: Iterable of `cirq.Qid`s that exist on the device.
nx_graph: `nx.Graph` describing qubit connectivity
on a device. Nodes represent qubits, directed edges indicate
directional coupling, undirected edges indicate bi-directional
coupling.
Expand All @@ -238,10 +238,10 @@ def __init__(

@property
def qubit_set(self) -> FrozenSet['cirq.Qid']:
"""Returns a set of qubits on the device, if possible.
"""Returns the set of qubits on the device.
Returns:
Frozenset of qubits on device if specified, otherwise None.
Frozenset of qubits on device.
"""
return self._qubits_set

Expand All @@ -250,7 +250,7 @@ def nx_graph(self) -> 'nx.Graph':
"""Returns a nx.Graph where nodes are qubits and edges are couple-able qubits.
Returns:
`nx.Graph` of device connectivity if specified, otherwise None.
`nx.Graph` of device connectivity.
"""
return self._nx_graph

Expand All @@ -269,6 +269,6 @@ def _json_dict_(self):
return {'qubits': qubits_payload, 'nx_graph': graph_payload}

@classmethod
def _from_json_dict_(cls, qubits, nx_graph, **kwargs):
def _from_json_dict_(cls, qubits: Iterable['cirq.Qid'], nx_graph: 'nx.Graph', **kwargs):
graph_obj = nx.readwrite.json_graph.node_link_graph(nx_graph)
return cls(qubits, graph_obj)
45 changes: 22 additions & 23 deletions cirq-core/cirq/devices/grid_device_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class GridDeviceMetadata(device.DeviceMetadata):
def __init__(
self,
qubit_pairs: Iterable[Tuple['cirq.Qid', 'cirq.Qid']],
supported_gates: 'cirq.Gateset',
gate_durations: Optional[Dict['cirq.Gateset', 'cirq.Duration']] = None,
gateset: 'cirq.Gateset',
gate_durations: Optional[Dict['cirq.GateFamily', 'cirq.Duration']] = None,
):
"""Create a GridDeviceMetadata object.
Expand All @@ -49,16 +49,16 @@ def __init__(
Args:
qubit_pairs: Iterable of pairs of `cirq.Qid`s representing
bi-directional couplings.
supported_gates: `cirq.Gateset` indicating gates supported
gateset: `cirq.Gateset` indicating gates supported
everywhere on the device.
gate_durations: Optional dictionary of `cirq.Gateset`
gate_durations: Optional dictionary of `cirq.GateFamily`
instances mapping to `cirq.Duration` instances for
gate timing metadata information. If provided,
must match all entries in supported_gates.
must match all entries in gateset.
Raises:
ValueError: if the union of gateset keys in gate_durations,
do not represent an identical gateset to supported_gates.
ValueError: if the union of GateFamily keys in gate_durations
is not identical to set of gate families in gateset.
"""
qubit_pairs = list(qubit_pairs)
flat_pairs = [q for pair in qubit_pairs for q in pair]
Expand All @@ -73,18 +73,17 @@ def __init__(
connectivity.add_edges_from(sorted(pair_set), directed=False)
super().__init__(flat_pairs, connectivity)
self._qubit_pairs = frozenset(pair_set)
self._supported_gates = supported_gates
self._gateset = gateset

if gate_durations is not None:
working_gatefamilies = frozenset(
g for gset in gate_durations.keys() for g in gset.gates
)
if working_gatefamilies != supported_gates.gates:
missing_items = working_gatefamilies.difference(supported_gates.gates)
working_gatefamilies = frozenset(gate_durations.keys())
if working_gatefamilies != gateset.gates:
raise ValueError(
"Supplied gate_durations contains gates not present"
f" in supported_gates. {missing_items} in supported_gates"
" is False."
"set of gate_durations keys are not equal to the "
"GateFamily instances found in gateset. Some gates "
"will be missing duration information."
f" gate_durations={gate_durations}"
f" gateset.gates={gateset.gates}"
)

self._gate_durations = gate_durations
Expand All @@ -97,10 +96,10 @@ def qubit_pairs(self) -> FrozenSet[Tuple['cirq.Qid', 'cirq.Qid']]:
@property
def gateset(self) -> 'cirq.Gateset':
"""Returns the `cirq.Gateset` of supported gates on this device."""
return self._supported_gates
return self._gateset

@property
def gate_durations(self) -> Optional[Dict['cirq.Gateset', 'cirq.Duration']]:
def gate_durations(self) -> Optional[Dict['cirq.GateFamily', 'cirq.Duration']]:
"""Get a dictionary mapping from gateset to duration for gates."""
return self._gate_durations

Expand All @@ -111,14 +110,14 @@ def _value_equality_values_(self):

return (
tuple(sorted(self._qubit_pairs)),
self._supported_gates,
self._gateset,
tuple(duration_equality),
)

def __repr__(self) -> str:
return (
f'cirq.GridDeviceMetadata({repr(self._qubit_pairs)},'
f' {repr(self._supported_gates)}, {repr(self._gate_durations)})'
f' {repr(self._gateset)}, {repr(self._gate_durations)})'
)

def _json_dict_(self):
Expand All @@ -128,10 +127,10 @@ def _json_dict_(self):

return {
'qubit_pairs': sorted(list(self._qubit_pairs)),
'supported_gates': self._supported_gates,
'gateset': self._gateset,
'gate_durations': duration_payload,
}

@classmethod
def _from_json_dict_(cls, qubit_pairs, supported_gates, gate_durations, **kwargs):
return cls(qubit_pairs, supported_gates, dict(gate_durations))
def _from_json_dict_(cls, qubit_pairs, gateset, gate_durations, **kwargs):
return cls(qubit_pairs, gateset, dict(gate_durations))
28 changes: 14 additions & 14 deletions cirq-core/cirq/devices/grid_device_metadata_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def test_griddevice_metadata_bad_durations():

gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate)
invalid_duration = {
cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=1),
cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=1),
}
with pytest.raises(ValueError, match="ZPowGate"):
cirq.GridDeviceMetadata([qubits], gateset, gate_durations=invalid_duration)
Expand All @@ -63,9 +63,9 @@ def test_griddevice_json_load():
qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)]
gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate)
duration = {
cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.Gateset(cirq.YPowGate): cirq.Duration(picos=2),
cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=3),
cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=2),
cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=3),
}
metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration)
rep_str = cirq.to_json(metadata)
Expand All @@ -77,14 +77,14 @@ def test_griddevice_metadata_equality():
qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)]
gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate)
duration = {
cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.Gateset(cirq.YPowGate): cirq.Duration(picos=3),
cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=2),
cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=3),
cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=2),
}
duration2 = {
cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=10),
cirq.Gateset(cirq.YPowGate): cirq.Duration(picos=13),
cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=12),
cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=10),
cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=13),
cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=12),
}
metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration)
metadata2 = cirq.GridDeviceMetadata(qubit_pairs[:2], gateset, gate_durations=duration)
Expand All @@ -106,9 +106,9 @@ def test_repr():
qubit_pairs = [(a, b) for a in qubits for b in qubits if a != b and a.is_adjacent(b)]
gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate)
duration = {
cirq.Gateset(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.Gateset(cirq.YPowGate): cirq.Duration(picos=3),
cirq.Gateset(cirq.ZPowGate): cirq.Duration(picos=2),
cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1),
cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=3),
cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=2),
}
metadata = cirq.GridDeviceMetadata(qubit_pairs, gateset, gate_durations=duration)
cirq.testing.assert_equivalent_repr(metadata)
58 changes: 17 additions & 41 deletions cirq-core/cirq/protocols/json_test_data/GridDeviceMetadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
}
]
],
"supported_gates": {
"gateset": {
"cirq_type": "Gateset",
"gates": [
{
Expand Down Expand Up @@ -118,19 +118,11 @@
"gate_durations": [
[
{
"cirq_type": "Gateset",
"gates": [
{
"cirq_type": "GateFamily",
"gate": "XPowGate",
"name": "Type GateFamily: cirq.ops.common_gates.XPowGate",
"description": "Accepts `cirq.Gate` instances `g` s.t. `isinstance(g, cirq.ops.common_gates.XPowGate)`",
"ignore_global_phase": true
}
],
"name": null,
"unroll_circuit_op": true,
"accept_global_phase_op": true
"cirq_type": "GateFamily",
"gate": "XPowGate",
"name": "Type GateFamily: cirq.ops.common_gates.XPowGate",
"description": "Accepts `cirq.Gate` instances `g` s.t. `isinstance(g, cirq.ops.common_gates.XPowGate)`",
"ignore_global_phase": true
},
{
"cirq_type": "Duration",
Expand All @@ -139,19 +131,11 @@
],
[
{
"cirq_type": "Gateset",
"gates": [
{
"cirq_type": "GateFamily",
"gate": "YPowGate",
"name": "Type GateFamily: cirq.ops.common_gates.YPowGate",
"description": "Accepts `cirq.Gate` instances `g` s.t. `isinstance(g, cirq.ops.common_gates.YPowGate)`",
"ignore_global_phase": true
}
],
"name": null,
"unroll_circuit_op": true,
"accept_global_phase_op": true
"cirq_type": "GateFamily",
"gate": "YPowGate",
"name": "Type GateFamily: cirq.ops.common_gates.YPowGate",
"description": "Accepts `cirq.Gate` instances `g` s.t. `isinstance(g, cirq.ops.common_gates.YPowGate)`",
"ignore_global_phase": true
},
{
"cirq_type": "Duration",
Expand All @@ -160,24 +144,16 @@
],
[
{
"cirq_type": "Gateset",
"gates": [
{
"cirq_type": "GateFamily",
"gate": "ZPowGate",
"name": "Type GateFamily: cirq.ops.common_gates.ZPowGate",
"description": "Accepts `cirq.Gate` instances `g` s.t. `isinstance(g, cirq.ops.common_gates.ZPowGate)`",
"ignore_global_phase": true
}
],
"name": null,
"unroll_circuit_op": true,
"accept_global_phase_op": true
"cirq_type": "GateFamily",
"gate": "ZPowGate",
"name": "Type GateFamily: cirq.ops.common_gates.ZPowGate",
"description": "Accepts `cirq.Gate` instances `g` s.t. `isinstance(g, cirq.ops.common_gates.ZPowGate)`",
"ignore_global_phase": true
},
{
"cirq_type": "Duration",
"picos": 1
}
]
]
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cirq.GridDeviceMetadata(frozenset({(cirq.GridQubit(0, 2), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), (cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), (cirq.GridQubit(0, 1), cirq.GridQubit(0, 2)), (cirq.GridQubit(1, 1), cirq.GridQubit(1, 2)), (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))}), cirq.Gateset(cirq.ops.common_gates.XPowGate, cirq.ops.common_gates.YPowGate, cirq.ops.common_gates.ZPowGate, unroll_circuit_op = True,accept_global_phase_op = True), {cirq.Gateset(cirq.ops.common_gates.XPowGate, unroll_circuit_op = True,accept_global_phase_op = True): cirq.Duration(nanos=1), cirq.Gateset(cirq.ops.common_gates.YPowGate, unroll_circuit_op = True,accept_global_phase_op = True): cirq.Duration(picos=1), cirq.Gateset(cirq.ops.common_gates.ZPowGate, unroll_circuit_op = True,accept_global_phase_op = True): cirq.Duration(picos=1)})
cirq.GridDeviceMetadata(frozenset({(cirq.GridQubit(0, 2), cirq.GridQubit(1, 2)), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), (cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)), (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), (cirq.GridQubit(0, 1), cirq.GridQubit(0, 2)), (cirq.GridQubit(1, 1), cirq.GridQubit(1, 2)), (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))}), cirq.Gateset(cirq.ops.common_gates.XPowGate, cirq.ops.common_gates.YPowGate, cirq.ops.common_gates.ZPowGate), {cirq.GateFamily(cirq.ops.common_gates.XPowGate): cirq.Duration(nanos=1), cirq.GateFamily(cirq.ops.common_gates.YPowGate): cirq.Duration(picos=1), cirq.GateFamily(cirq.ops.common_gates.ZPowGate): cirq.Duration(picos=1)})
2 changes: 1 addition & 1 deletion cirq-google/cirq_google/devices/serializable_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def __init__(
for pair in gate_def.target_set
if len(pair) == 2 and pair[0] < pair[1]
],
supported_gates=cirq.Gateset(
gateset=cirq.Gateset(
*[g for g in gate_definitions.keys() if isinstance(g, (cirq.Gate, type(cirq.Gate)))]
),
gate_durations=None,
Expand Down

0 comments on commit 5eae221

Please sign in to comment.