{ "cells": [ { "cell_type": "markdown", "id": "cell-00", "metadata": {}, "source": [ "# 17-Qubit Surface-Code Chip (Wallraff group, ETH Zurich)" ] }, { "cell_type": "markdown", "id": "cell-01", "metadata": {}, "source": [ "[](https://colab.research.google.com/github/qiskit-community/qiskit-metal/blob/main/docs/circuit-examples/F.Small-quantum-chips/53-Wallraff_17Qubit_SurfaceCode.ipynb)\n", "[](https://mybinder.org/v2/gh/qiskit-community/qiskit-metal/main?labpath=docs%2Fcircuit-examples%2FF.Small-quantum-chips%2F53-Wallraff_17Qubit_SurfaceCode.ipynb)\n", "\n", "> 💡 **Running in Colab or Binder?** Uncomment the install cell below. The notebook runs headless there — no Qt, no Ansys, about a minute end to end. On a desktop with the GUI installed, it also opens the chip in `MetalGUI` and updates it after every stage." ] }, { "cell_type": "markdown", "id": "cell-02", "metadata": {}, "source": [ "In 2022, the Quantum Device Lab at ETH Zurich ran repeated rounds of quantum error correction on a distance-three surface code — seventeen superconducting qubits on one die ([Krinner *et al.*, *Nature* 2022](https://doi.org/10.1038/s41586-022-04566-8)). In this notebook you build that chip in Quantum Metal, from the bare die to the last feedline, and check the design after every step.\n", "\n", "**What you'll learn**\n", "\n", "- how a surface-code processor is laid out: data and auxiliary qubits, couplers, control lines, readout with Purcell filters, multiplexed feedlines;\n", "- how to draw a line that follows a known path with `PolylineCPW`, and connect to it partway along with *taps*;\n", "- how to carry one line over another with an `Airbridge`;\n", "- how to run Metal's design-rule check after every stage, including the shape rules that catch hairpins, self-crossings and unterminated line ends;\n", "- how to export the chip to GDS, and how to change it and see the check respond.\n", "\n", "| | |\n", "|---|---|\n", "| Qubits | 17 transmons: 9 data, 8 auxiliary |\n", "| Die | 14.4 mm square, 48 wire-bond launchpads |\n", "| Readout | 17 quarter-wave resonators, 17 Purcell filters, 4 feedlines |\n", "| Components | 348 |\n", "| Run time | about 1 minute |" ] }, { "cell_type": "markdown", "id": "cell-03", "metadata": {}, "source": [ "## The device, and thanks\n", "\n", "The chip is the design of the [Quantum Device Lab](https://qudev.phys.ethz.ch/) of Andreas Wallraff at ETH Zurich, used in S. Krinner, N. Lacroix, A. Remm *et al.* [1] and, in a device of the same design, for lattice surgery by I. Besedin, M. Kerschbaum *et al.* [2]. It builds on the group's earlier seven-qubit surface-code work [3] and on their multiplexed readout with individual Purcell filters [4, 5].\n", "\n", "**Thank you** to Andreas Wallraff and the Quantum Device Lab for sharing this design openly — in the [lecture slides](https://polybox.ethz.ch/index.php/s/CnsHoKWW6xQKZAA) and in the talks [here](https://www.youtube.com/watch?v=floIDDd6ZXA), [here](https://www.youtube.com/watch?v=CgNz4wsD0oI), and at the Quantum Device Workshop ([lecture](https://www.youtube.com/watch?v=0r1YPMcmuFU)). Every position and path in this notebook was measured from the micrographs in those slides.\n", "\n", "> ⚠️ **A mockup, not a mask.** This is a reconstruction for learning, and it is not perfect. Dimensions the images cannot resolve are chosen; each junction is a single junction standing in for the device's SQUID; and line crossings are drawn as airbridges, where the device uses integrated crossovers. The full list is under *Known issues* at the end." ] }, { "cell_type": "markdown", "id": "cell-04", "metadata": {}, "source": [ "> 🤖 **Rebuilt by AI agents, on top of Quantum Metal**\n", ">\n", "> The layout was reconstructed by AI coding agents working through Metal's Python API, with a person reviewing every stage: measuring the die from the slide images, writing the builder, and fixing what the design-rule check found.\n", ">\n", "> Reproducing a published device is a test, not the goal: the answer is known, so every mistake shows. The goal is designing *new* chips with AI — starting from a specification (qubits, connectivity, frequencies) and laying out, checking and simulating in Metal. That workflow is written up as the [`chip-design`](https://github.com/qiskit-community/qiskit-metal/blob/main/.claude/skills/chip-design/SKILL.md) agent skill. This notebook is a small, complete run of its core loop: build in stages, check every stage, change something, check again." ] }, { "cell_type": "code", "execution_count": 1, "id": "cell-05", "metadata": { "execution": { "iopub.execute_input": "2026-09-27T06:42:01.329051Z", "iopub.status.busy": "2026-09-27T06:42:01.328849Z", "iopub.status.idle": "2026-09-27T06:42:01.332859Z", "shell.execute_reply": "2026-09-27T06:42:01.332086Z" } }, "outputs": [], "source": [ "# In Colab / Binder, uncomment to install Quantum Metal (lite, no Qt).\n", "# Locally you should already have it via `pip install quantum-metal` or\n", "# `pip install 'quantum-metal[gui]'` for the desktop GUI.\n", "# !pip install -q quantum-metal" ] }, { "cell_type": "markdown", "id": "cell-06", "metadata": {}, "source": [ "### Setup\n", "\n", "**GUI or headless.** `qm.gui(design)` opens the desktop `MetalGUI` when Qt and a display are available, and falls back to an inline headless viewer otherwise (Colab, Binder, a server). Set `HEADLESS` to choose yourself: `True` for inline figures, `False` to require the desktop GUI. In the desktop GUI each stage is drawn in the GUI window and a screenshot of it lands in the notebook; headless, Metal draws an inline figure instead. The outputs saved in this notebook, and shown in the docs, come from a headless run.\n", "\n", "The builder (`wallraff_17q.py`) and the measured geometry (`geometry.json`) live in `resources/wallraff_17q/` beside this notebook. Colab opens a notebook on its own, so the cell fetches them if they are missing." ] }, { "cell_type": "code", "execution_count": 2, "id": "cell-07", "metadata": { "execution": { "iopub.execute_input": "2026-09-27T06:42:01.340528Z", "iopub.status.busy": "2026-09-27T06:42:01.340126Z", "iopub.status.idle": "2026-09-27T06:42:04.584108Z", "shell.execute_reply": "2026-09-27T06:42:04.582933Z" } }, "outputs": [], "source": [ "import sys\n", "import tempfile\n", "import urllib.request\n", "import warnings\n", "from pathlib import Path\n", "\n", "import matplotlib.pyplot as plt\n", "from IPython.display import display\n", "\n", "import qiskit_metal as qm\n", "from qiskit_metal.validation import DEFAULT_RULES, SHAPE_RULES, validate\n", "\n", "warnings.filterwarnings(\"ignore\", category=FutureWarning)\n", "\n", "HEADLESS = None # None: desktop GUI if available; True: headless; False: desktop GUI\n", "\n", "RES = Path(\"resources/wallraff_17q\")\n", "if not RES.exists():\n", " RES.mkdir(parents=True)\n", " base = (\n", " \"https://raw.githubusercontent.com/qiskit-community/qiskit-metal/main/\"\n", " \"docs/circuit-examples/F.Small-quantum-chips/\"\n", " \"resources/wallraff_17q/\"\n", " )\n", " for f in (\"wallraff_17q.py\", \"geometry.json\", \"chip_inspect.py\"):\n", " urllib.request.urlretrieve(base + f, RES / f)\n", "sys.path.insert(0, str(RES))\n", "\n", "import wallraff_17q as chip\n", "from chip_inspect import inspect_sites" ] }, { "cell_type": "markdown", "id": "cell-08", "metadata": {}, "source": [ "## Build it one layer at a time\n", "\n", "Six stages, each a function in the builder. After every stage we draw the design and run the design-rule check, so a finding points straight at the stage that caused it.\n", "\n", "The check runs Metal's default rules -- which also look at the shape of each single line: a line crossing itself, a hairpin turn, a corner rounded less than was asked for, and a line that leaves the pin it connects to at an angle -- plus `SHAPE_RULES`, which adds one more: a line end left unconnected." ] }, { "cell_type": "code", "execution_count": 3, "id": "cell-09", "metadata": { "execution": { "iopub.execute_input": "2026-09-27T06:42:04.590759Z", "iopub.status.busy": "2026-09-27T06:42:04.590173Z", "iopub.status.idle": "2026-09-27T06:42:07.714352Z", "shell.execute_reply": "2026-09-27T06:42:07.713437Z" } }, "outputs": [ { "data": { "text/html": [ "
qm.view(design); gui.rebuild(), gui.screenshot(), gui.edit_component(...) work as in the desktop GUI.pip install 'quantum-metal[gui]' and re-import.