Skip to content

Commit

Permalink
Named topologies: support manual placement (quantumlib#4628)
Browse files Browse the repository at this point in the history
- Helper method to get mappings to gridqubits
- Document how to manually place TiltedSquareLattice and LineTopology graphs onto a sample device
- Let `draw_placements` accept `tilted` boolean like the other draw methods
- added some missing docstrings and type annotations

![image](https://user-images.githubusercontent.com/4967059/140413234-d21fe08b-ec9e-4b5c-81d9-3600b4884799.png)
  • Loading branch information
mpharrigan authored and rht committed May 1, 2023
1 parent 68b4263 commit c79c3d5
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 11 deletions.
34 changes: 30 additions & 4 deletions cirq-core/cirq/devices/named_topologies.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,15 @@ def nodes_as_gridqubits(self) -> List['cirq.GridQubit']:
"""Get the graph nodes as cirq.GridQubit"""
return [GridQubit(r, c) for r, c in sorted(self.graph.nodes)]

def nodes_to_gridqubits(self, offset=(0, 0)) -> Dict[Tuple[int, int], 'cirq.GridQubit']:
"""Return a mapping from graph nodes to `cirq.GridQubit`
Args:
offset: Offest row and column indices of the resultant GridQubits by this amount.
The offest positions the top-left node in the `draw(tilted=False)` frame.
"""
return {(r, c): GridQubit(r, c) + offset for r, c in self.graph.nodes}

def _json_dict_(self) -> Dict[str, Any]:
return dataclass_json_dict(self)

Expand Down Expand Up @@ -281,14 +290,25 @@ def get_placements(
def draw_placements(
big_graph: nx.Graph,
small_graph: nx.Graph,
small_to_big_mappings,
max_plots=20,
small_to_big_mappings: Sequence[Dict],
max_plots: int = 20,
axes: Sequence[plt.Axes] = None,
tilted=True,
):
"""Draw a visualization of placements from small_graph onto big_graph using Matplotlib.
The entire `big_graph` will be drawn with default blue colored nodes. `small_graph` nodes
and edges will be highlighted with a red color.
Args:
big_graph: A larger graph to draw with blue colored nodes.
small_graph: A smaller, sub-graph to highlight with red nodes and edges.
small_to_big_mappings: A sequence of mappings from `small_graph` nodes to `big_graph`
nodes.
max_plots: To prevent an explosion of open Matplotlib figures, we only show the first
`max_plots` plots.
axes: Optional list of matplotlib Axes to contain the drawings.
tilted: Whether to draw gridlike graphs in the ordinary cartesian or tilted plane.
"""
if len(small_to_big_mappings) > max_plots:
# coverage: ignore
Expand All @@ -308,9 +328,15 @@ def draw_placements(
ax = plt.gca()

small_mapped = nx.relabel_nodes(small_graph, small_to_big_map)
draw_gridlike(big_graph, ax=ax)
draw_gridlike(big_graph, ax=ax, tilted=tilted)
draw_gridlike(
small_mapped, node_color='red', edge_color='red', width=2, with_labels=False, ax=ax
small_mapped,
node_color='red',
edge_color='red',
width=2,
with_labels=False,
ax=ax,
tilted=tilted,
)
ax.axis('equal')
if call_show:
Expand Down
5 changes: 5 additions & 0 deletions cirq-core/cirq/devices/named_topologies_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ def test_tilted_square_methods():
qubits = topo.nodes_as_gridqubits()
assert all(isinstance(q, cirq.GridQubit) for q in qubits)

mapping = topo.nodes_to_gridqubits(offset=(3, 5))
assert all(
isinstance(q, cirq.GridQubit) and q >= cirq.GridQubit(0, 0) for q in mapping.values()
)


def test_tilted_square_lattice_n_nodes():
for width, height in itertools.product(list(range(1, 4 + 1)), repeat=2):
Expand Down
1 change: 1 addition & 0 deletions dev_tools/notebooks/isolated_notebook_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
'docs/tutorials/google/start.ipynb',
'docs/tutorials/google/visualizing_calibration_metrics.ipynb',
'docs/tutorials/google/xeb_calibration_example.ipynb',
'docs/named_topologies.ipynb',
]

# By default all notebooks should be tested, however, this list contains exceptions to the rule
Expand Down
95 changes: 88 additions & 7 deletions docs/named_topologies.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ea381f53cf89"
},
"source": [
"Note: this notebook relies on unreleased Cirq features. If you want to try these features, make sure you install cirq via `pip install cirq --pre`."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -76,8 +85,10 @@
" import cirq\n",
"except ImportError:\n",
" print(\"installing cirq...\")\n",
" !pip install --quiet cirq\n",
" print(\"installed cirq.\")"
" !pip install --quiet cirq --pre\n",
" print(\"installed cirq.\")\n",
" \n",
"import cirq"
]
},
{
Expand Down Expand Up @@ -192,6 +203,40 @@
"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ca39fc2f6773"
},
"source": [
"You can manually generate mappings between `NamedTopology` nodes and device qubits using helper functions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0f6a1e57db87"
},
"outputs": [],
"source": [
"topo = TiltedSquareLattice(4, 2)\n",
"\n",
"cirq.draw_placements(SYC23_GRAPH, topo.graph, [\n",
" topo.nodes_to_gridqubits(offset=(3,2)),\n",
" topo.nodes_to_gridqubits(offset=(5,3)),\n",
"], tilted=False)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "898879ebaf69"
},
"source": [
"Or you can automatically generate placements using a subgraph monomorphism algorithm in NetworkX."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -200,10 +245,9 @@
},
"outputs": [],
"source": [
"from cirq import get_placements, draw_placements\n",
"topo = TiltedSquareLattice(4, 2)\n",
"placements = get_placements(SYC23_GRAPH, topo.graph)\n",
"draw_placements(SYC23_GRAPH, topo.graph, placements[::3])\n",
"placements = cirq.get_placements(SYC23_GRAPH, topo.graph)\n",
"cirq.draw_placements(SYC23_GRAPH, topo.graph, placements[::3])\n",
"print('...\\n')\n",
"print(f'{len(placements)} total placements')"
]
Expand Down Expand Up @@ -243,6 +287,43 @@
"fig.tight_layout()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ffbdece786d1"
},
"source": [
"### Manual placement"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "fb0f5289d6f5"
},
"outputs": [],
"source": [
"topo = LineTopology(9)\n",
"\n",
"cirq.draw_placements(SYC23_GRAPH, topo.graph, [\n",
" {i: q for i, q in enumerate([\n",
" cirq.GridQubit(4, 1), cirq.GridQubit(4, 2), cirq.GridQubit(5, 2), \n",
" cirq.GridQubit(5, 3), cirq.GridQubit(6, 3), cirq.GridQubit(6, 4), \n",
" cirq.GridQubit(7, 4), cirq.GridQubit(7, 5), cirq.GridQubit(8, 5), \n",
" ])}\n",
"], tilted=False)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d3085236f6b7"
},
"source": [
"### Automatic placement"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -252,8 +333,8 @@
"outputs": [],
"source": [
"topo = LineTopology(9)\n",
"placements = get_placements(SYC23_GRAPH, topo.graph)\n",
"draw_placements(SYC23_GRAPH, topo.graph, placements[::300])\n",
"placements = cirq.get_placements(SYC23_GRAPH, topo.graph)\n",
"cirq.draw_placements(SYC23_GRAPH, topo.graph, placements[::300])\n",
"print('...\\n')\n",
"print(f'{len(placements)} total placements')"
]
Expand Down

0 comments on commit c79c3d5

Please sign in to comment.