{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "id": "S97D7gQHMdG_" }, "outputs": [], "source": [ "##### Copyright 2021 The Cirq Developers" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "cellView": "form", "id": "Y6Wh1qtGMghL" }, "outputs": [], "source": [ "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# https://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License." ] }, { "cell_type": "markdown", "metadata": { "id": "gNBCrapEMgxB" }, "source": [ "# Circuit optimization, gate alignment, and spin echoes" ] }, { "cell_type": "markdown", "metadata": { "id": "tlnEweYsMgzj" }, "source": [ "
\n",
" ![]() | \n",
" \n",
" ![]() | \n",
" \n",
" ![]() | \n",
" \n",
" ![]() | \n",
"
(0, 0): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────────────────────────────────────────M('z')───\n", " │ │\n", "(0, 1): ───────iSwap───PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5─────────────────────────────────────────────────────────────────iSwap───PhX(0.75)^0.5──────────────────────────────────────────────────────────────iSwap───────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────PhX(0.25)^-0.5──────────────────────────────────────────────────────────────────iSwap─────────────────PhX(0.75)^-0.5──────────────────────────────────────────────────────────────────iSwap──────PhX(-0.75)^-0.5────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───iSwap^-1────────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────────────────────PhX(-0.25)^0.5─────────────────────────────────────────────iSwap────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────┼───────────────────────PhX(0)^0.5─────────────────────────────────────────────────iSwap───────────────────────────PhX(-0.5)^0.5───────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────iSwap^-1───────────────────────────────PhX(0)^-0.5────────────────────────────────────────────────────┼────────────────────────────PhX(0.25)^-0.5────────────────────────────────────────────────────iSwap───────────────────────PhX(-0.25)^-0.5─────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(1, 0): ────────────────────────────────────────────────PhX(0)^0.5────────────────────────────────┼────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────┼────────────────────────────────────PhX(0.5)^0.5──────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────PhX(0)^-0.5──────────────────────────────────────────────iSwap─────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────┼─────────────────────────────────────────────PhX(0.75)^-0.5───────────────────────────────────┼─────────────────────────────────────────────PhX(0)^-0.5───────────────────────────────────────────\n", " │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────────────────────PhX(1)^0.5───────────────────┼────────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────iSwap───────────────────────────────────────────────PhX(-0.5)^0.5──────────────────────────iSwap────────────────────────────────────────────────PhX(-0.25)^0.5────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5────────────────────────────iSwap^-1──────────────────────────────────────────────────PhX(-0.5)^-0.5───────────────────iSwap^-1───────────────────────────────────────────────────────PhX(-0.75)^-0.5─────────────────┼───────────────────────────────────────────────────────────PhX(1)^-0.5─────────────────────────────\n", " │ │\n", "(1, 2): ──────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───iSwap─────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5───iSwap^-1──────────────────────────────────────────────────────────────────PhX(0.75)^-0.5────────────" ], "text/plain": [ "(0, 0): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────────────────────────────────────────M('z')───\n", " │ │\n", "(0, 1): ───────iSwap───PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5─────────────────────────────────────────────────────────────────iSwap───PhX(0.75)^0.5──────────────────────────────────────────────────────────────iSwap───────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────PhX(0.25)^-0.5──────────────────────────────────────────────────────────────────iSwap─────────────────PhX(0.75)^-0.5──────────────────────────────────────────────────────────────────iSwap──────PhX(-0.75)^-0.5────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───iSwap^-1────────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────────────────────PhX(-0.25)^0.5─────────────────────────────────────────────iSwap────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────┼───────────────────────PhX(0)^0.5─────────────────────────────────────────────────iSwap───────────────────────────PhX(-0.5)^0.5───────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────iSwap^-1───────────────────────────────PhX(0)^-0.5────────────────────────────────────────────────────┼────────────────────────────PhX(0.25)^-0.5────────────────────────────────────────────────────iSwap───────────────────────PhX(-0.25)^-0.5─────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(1, 0): ────────────────────────────────────────────────PhX(0)^0.5────────────────────────────────┼────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────┼────────────────────────────────────PhX(0.5)^0.5──────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────PhX(0)^-0.5──────────────────────────────────────────────iSwap─────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────┼─────────────────────────────────────────────PhX(0.75)^-0.5───────────────────────────────────┼─────────────────────────────────────────────PhX(0)^-0.5───────────────────────────────────────────\n", " │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────────────────────PhX(1)^0.5───────────────────┼────────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────iSwap───────────────────────────────────────────────PhX(-0.5)^0.5──────────────────────────iSwap────────────────────────────────────────────────PhX(-0.25)^0.5────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5────────────────────────────iSwap^-1──────────────────────────────────────────────────PhX(-0.5)^-0.5───────────────────iSwap^-1───────────────────────────────────────────────────────PhX(-0.75)^-0.5─────────────────┼───────────────────────────────────────────────────────────PhX(1)^-0.5─────────────────────────────\n", " │ │\n", "(1, 2): ──────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───iSwap─────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5───iSwap^-1──────────────────────────────────────────────────────────────────PhX(0.75)^-0.5────────────" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"Create an example circuit.\"\"\"\n", "qubits = cirq.GridQubit.rect(2, 3) # [cirq.GridQubit(x, y) for (x, y) in [(3, 2), (4, 2), (4, 1), (5, 1), (6, 1), (6, 2), (5, 2)]]\n", "circuit = create_benchmark_circuit(qubits, twoq_gate=cirq.ISWAP, cycles=3, seed=1)\n", "\n", "print(\"Example benchmark circuit:\\n\")\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "ojDozjQK7cos" }, "source": [ "This circuit divides the qubits into two registers: a single ancilla (top qubit) as the first register, and the remaining qubits as the second register. First, the ancilla is excited into the $|1\\rangle$ state and coupled to the second register. Then, a [Loschmidt echo](https://quantumai.google/cirq/tutorials/google/echoes) is performed on the second register. Last, the ancilla is uncoupled from the second register and measured. Without any noise, the only measurement result should be $1$." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "nooNt8bi8NKH" }, "outputs": [ { "data": { "text/plain": [ "Counter({1: 1000})" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"Without noise, only the 1 state is measured.\"\"\"\n", "result = cirq.Simulator().run(circuit, repetitions=1000)\n", "result.histogram(key=\"z\")" ] }, { "cell_type": "markdown", "metadata": { "id": "aA5wUJa38VyO" }, "source": [ "We choose this circuit as an example for two reasons:\n", "\n", "1. Each gate in the circuit is in its own `cirq.Moment`, so this is a poor circuit structure to run on devices without any optimization / alignment.\n", "\n", "2. The ancilla qubit is idle except at the start and end of the circuit, so this is a prime example where adding spin echoes can improve performance.\n", "\n", "A similar circuit was used in [Information Scrambling in Computationally Complex Quantum Circuits](https://arxiv.org/abs/2101.08870) (see Fig. S10) to benchmark the performance of spin echoes.\n", "\n", "Starting from this circuit, we show how to optimize gates, align moments, and insert spin echoes to improve the performance on a real device." ] }, { "cell_type": "markdown", "metadata": { "id": "pQXwGBdO-iS4" }, "source": [ "### Convert to target gateset" ] }, { "cell_type": "markdown", "metadata": { "id": "szjI2vm2VbN4" }, "source": [ "To run on a device, all gates in the circuit will be converted to a gateset supported by that device. (See the [Device specifications guide](https://quantumai.google/cirq/google/specification) for information on supported gatesets.)\n", "\n", "We will use the $\\sqrt{\\text{iSWAP}}$ gateset in this tutorial. You can see this gateset and others as follows." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "id": "Hyky31J08kWK" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sycamore\n", "-------\n", "syc 12000\n", "xy 25000\n", "xy_pi 25000\n", "xy_half_pi 25000\n", "z 0\n", "xyz 25000\n", "meas 4000000\n", "wait 0\n", "\n", "sqrt_iswap\n", "-------\n", "fsim_pi_4 32000\n", "inv_fsim_pi_4 32000\n", "xy 25000\n", "z 0\n", "xyz 25000\n", "meas 4000000\n", "wait 0\n", "\n", "fsim\n", "-------\n", "fsim 0\n", "xy 25000\n", "z 0\n", "xyz 25000\n", "meas 4000000\n", "wait 0\n", "\n", "xmon\n", "-------\n", "xy 25000\n", "z 0\n", "xyz 25000\n", "cz 0\n", "meas 4000000\n", "\n" ] } ], "source": [ "# Create an Engine object to use.\n", "spec = cg.Engine(project_id).get_processor(processor_id).get_device_specification()\n", "\n", "# Iterate through each gate set valid on the device.\n", "for gateset in spec.valid_gate_sets:\n", " print(gateset.name)\n", " print('-------')\n", " # Prints each gate valid in the set with its duration\n", " for gate in gateset.valid_gates:\n", " print('%s %d' % (gate.id, gate.gate_duration_picos))\n", " print()" ] }, { "cell_type": "markdown", "metadata": { "id": "Tf5O4HxH8qBg" }, "source": [ "To convert gates to this gateset, use the `cirq.MergeInteractionsToSqrtIswap` optimizer. This optimizer merges all consecutive (one- and two-qubit) interactions on two qubits into a unitary matrix and then decomposes this unitary using $\\sqrt{\\text{iSWAP}}$ gates in an attempt to (a) convert to the target gateset and (b) reduce the circuit depth by reducing the number of operations." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "Eb4NyHFT-l4-" }, "outputs": [ { "data": { "text/html": [ "
┌─────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌────────────────────┐\n", "(0, 0): ───X───X───S───iSwap────────────iSwap────────Z──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M('z')───\n", " │ │ │ │\n", "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5────X────────────S^-1────────────────────────────────────────────────────────────────────────────────────X───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────X───Z^0.118──────────────────iSwap───────────────────────iSwap───────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼─────────────────────────────────────X─────────Z^-0.016───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼──────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75──────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n", " │ │ │ │\n", "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n", " └─────────────────────┘ └───────────────────────┘ └───────────────────────┘ └────────────────────┘" ], "text/plain": [ " ┌─────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌────────────────────┐\n", "(0, 0): ───X───X───S───iSwap────────────iSwap────────Z──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M('z')───\n", " │ │ │ │\n", "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5────X────────────S^-1────────────────────────────────────────────────────────────────────────────────────X───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────X───Z^0.118──────────────────iSwap───────────────────────iSwap───────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼─────────────────────────────────────X─────────Z^-0.016───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼──────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75──────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n", " │ │ │ │\n", "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n", " └─────────────────────┘ └───────────────────────┘ └───────────────────────┘ └────────────────────┘" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cirq.MergeInteractionsToSqrtIswap().optimize_circuit(circuit)\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "RXBNzJKXG_Oi" }, "source": [ "Note: Cirq supports decomposing to many different target gatesets via analytical decomposition functions present in `cirq.optimizers`. For example, you can compile an arbitrary two-qubit unitary (provided as a matrix) to $\\sqrt{\\text{iSWAP}}$ operations as shown below. This is useful when using custom gates in a circuit." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "cOoSlIZlEjci" }, "outputs": [ { "data": { "text/html": [ "
(0, 0): ───Z^0.07────X^0.501───Z^0.424───iSwap───────Z^(1/6)────X^0.022───Z^-0.217───iSwap───────Z^0.983────X^0.603───Z^-0.78───\n", " │ │\n", "(0, 1): ───Z^0.543───X^0.26──────────────iSwap^0.5───Z^(5/13)───X^(1/3)──────────────iSwap^0.5───Z^-0.367───X^0.114───Z^0.18────" ], "text/plain": [ "(0, 0): ───Z^0.07────X^0.501───Z^0.424───iSwap───────Z^(1/6)────X^0.022───Z^-0.217───iSwap───────Z^0.983────X^0.603───Z^-0.78───\n", " │ │\n", "(0, 1): ───Z^0.543───X^0.26──────────────iSwap^0.5───Z^(5/13)───X^(1/3)──────────────iSwap^0.5───Z^-0.367───X^0.114───Z^0.18────" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"Compile an arbitrary two-qubit operation to the sqrt_iswap gateset.\"\"\"\n", "ops = cirq.two_qubit_matrix_to_sqrt_iswap_operations(\n", " q0=qubits[0], q1=qubits[1], mat=cirq.testing.random_unitary(dim=4, random_state=1)\n", ")\n", "cirq.Circuit(ops)" ] }, { "cell_type": "markdown", "metadata": { "id": "OMRtgOHh-mDj" }, "source": [ "### Eject single-qubit operations" ] }, { "cell_type": "markdown", "metadata": { "id": "4mYaNbqxBDBp" }, "source": [ "After converting to a target gateset, you can use various circuit optimizers to attempt to reduce the number of gates as shown below." ] }, { "cell_type": "markdown", "metadata": { "id": "DiR_6NvV_mb6" }, "source": [ "The `cirq.eject_phased_paulis` optimizer pushes `cirq.X`, `cirq.Y`, and `cirq.PhasedXPowGate` gates towards the end of the circuit." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "id": "KnJXHJNe-mha" }, "outputs": [ { "data": { "text/html": [ "
┌─────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌────────────────────┐\n", "(0, 0): ───────────S───iSwap────────────iSwap────────Z───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M('z')───\n", " │ │ │ │\n", "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────S───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.0592)──────────────────iSwap───────────────────────iSwap────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼───────────────────────────────────────────────PhX(-0.00809)───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼───────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75───────────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n", " │ │ │ │\n", "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n", " └─────────────────────┘ └───────────────────────┘ └───────────────────────┘ └────────────────────┘" ], "text/plain": [ " ┌─────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌────────────────────┐\n", "(0, 0): ───────────S───iSwap────────────iSwap────────Z───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────iSwap───────────────────iSwap─────────Z───────M('z')───\n", " │ │ │ │\n", "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────S───S^-1───iSwap────────────────────iSwap────────T───X^0.5───Z^0.75───T────────X^0.5────T^-1──────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.0592)──────────────────iSwap───────────────────────iSwap────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────S────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────T───────────────X^0.75───────────S──────────────┼────────────────────────┼─────────────────────────────────X^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5┼───────────────────────────┼───────────────────────────────────────────────PhX(-0.00809)───iSwap───────────────────iSwap────────Z^-0.75───────X^0.5───Z^0.75───\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5───────────────────────────────────┼────────────PhX(0.5)^0.5┼──────────────────────────────────────────Y^-0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼───────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5──────────────────iSwap^0.5────────────────iSwap^0.5────S───Y^0.5─────────────────────Y^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────Z^-0.868───X^0.5─────────Z^-0.75───────────────────┼───────────────────────┼────────────PhX(1)^-0.5────────────────────\n", " │ │ │ │\n", "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───Z^-0.355────────X^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────PhX(0)^-0.5───────────────────────────PhX(0.5)^-0.5────────────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────iSwap^0.5───────────────iSwap^0.5────Z^0.766───────X^0.5───Z^0.75───\n", " └─────────────────────┘ └───────────────────────┘ └───────────────────────┘ └────────────────────┘" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit = cirq.eject_phased_paulis(circuit)\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "M1h-qJsb_5TG" }, "source": [ "Note that, for example, the back-to-back `cirq.X` gates on the ancilla have been removed from the start of the circuit." ] }, { "cell_type": "markdown", "metadata": { "id": "oKcnKYTE-ms3" }, "source": [ "You can also use the `cirq.eject_z` optimizer to attempt to push `cirq.Z` gates towards the end of the circuit." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "id": "eomQLGiMF9kY" }, "outputs": [ { "data": { "text/html": [ "
┌─────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌────────────────────┐\n", "(0, 0): ───────────S───iSwap────────────iSwap───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1─────────iSwap───────────────────iSwap───────────────────────────────M('z')─────\n", " │ │ │ │\n", "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────iSwap────────────PhX(-0.25)^0.5─────────────────────────PhX(0.75)^0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.941)───Z──────────────────iSwap───────────────────────iSwap──────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────────S────────────────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────────────────────PhX(-0.25)^0.75───────────────┼────────────────────────┼─────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5┼───────────────────────────┼──────────────────────────────────────PhX(-0.758)───Z^0.75───iSwap───────────────────iSwap──────────────────────────PhX(0.75)^0.5────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5─────────────────────────────────┼────────────PhX(0.5)^0.5┼───────────────────────────────────────────────────────Y^-0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼─────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5────────────────iSwap^0.5────────────────iSwap^0.5────────PhX(0)^0.5─────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────────PhX(0.868)^0.5───────────────────────────────┼───────────────────────┼────────────PhX(0.618)^-0.5───Z^0.382──────────────────────\n", " │ │ │ │\n", "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───────────────────PhX(0.355)^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^0.5───────────────────PhX(0.355)^-0.5───────────────────────────PhX(0.855)^-0.5─────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^-0.5───────Z^-0.355───────────────iSwap^0.5───────────────iSwap^0.5──────────────────────PhX(-0.766)^0.5───Z^-0.484───\n", " └─────────────────────┘ └───────────────────────┘ └───────────────────────┘ └────────────────────┘" ], "text/plain": [ " ┌─────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌────────────────────┐\n", "(0, 0): ───────────S───iSwap────────────iSwap───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1─────────iSwap───────────────────iSwap───────────────────────────────M('z')─────\n", " │ │ │ │\n", "(0, 1): ───────────────iSwap^0.5────────iSwap^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────iSwap────────────PhX(-0.25)^0.5─────────────────────────PhX(0.75)^0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.941)───Z──────────────────iSwap───────────────────────iSwap──────────────────────────────────────────────────────────────────────iSwap^0.5───────────────iSwap^0.5─────────S────────────────────────────\n", " │ │ │ │\n", "(0, 2): ───────────────PhX(-0.25)^0.5─────────────────────────────────────────────Z^-0.145───iSwap───────iSwap───────────────────────PhX(-0.25)^0.75───────────────┼────────────────────────┼─────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5┼───────────────────────────┼──────────────────────────────────────PhX(-0.758)───Z^0.75───iSwap───────────────────iSwap──────────────────────────PhX(0.75)^0.5────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ────────────────────────────────PhX(0)^0.5───────────────────────────────────────────┼───────────┼───────────PhX(0.75)^0.5─────────────────────────────────┼────────────PhX(0.5)^0.5┼───────────────────────────────────────────────────────Y^-0.5────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────PhX(0.75)^-0.5┼─────────────────────────────────────────────────────────────┼────────────PhX(0)^-0.5┼───────────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ─────────────────────────────────────────────PhX(1)^0.5──────────────────────────────┼───────────┼───────────────────────────PhX(-0.75)^0.5────────────────iSwap^0.5────────────────iSwap^0.5────────PhX(0)^0.5─────────────────────────────PhX(0)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S────────────────────────────────iSwap^0.5───────────────────iSwap^0.5────────PhX(0.868)^0.5───────────────────────────────┼───────────────────────┼────────────PhX(0.618)^-0.5───Z^0.382──────────────────────\n", " │ │ │ │\n", "(1, 2): ──────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────iSwap^0.5───iSwap^0.5───────────────────PhX(0.355)^0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^0.5───────────────────PhX(0.355)^-0.5───────────────────────────PhX(0.855)^-0.5─────────────────────────────────────────────────────────────────────────────────────PhX(0.355)^-0.5───────Z^-0.355───────────────iSwap^0.5───────────────iSwap^0.5──────────────────────PhX(-0.766)^0.5───Z^-0.484───\n", " └─────────────────────┘ └───────────────────────┘ └───────────────────────┘ └────────────────────┘" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit = cirq.eject_z(circuit)\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "ydUlul4NE_Eu" }, "source": [ "Note that, for example, the `cirq.Z` gate immediately before the ancilla measurement has been removed." ] }, { "cell_type": "markdown", "metadata": { "id": "824RLaxrVbnH" }, "source": [ "### Align gates in moments" ] }, { "cell_type": "markdown", "metadata": { "id": "2o8l3r1NGT_T" }, "source": [ "After optimizing, gates should be aligned into `cirq.Moment`s to satisfy the following criteria:\n", "\n", "- The fewer moments the better (generally speaking).\n", " - Each moment is a discrete time slice, so fewer moments means shorter circuit execution time.\n", "\n", "- Moments should consist of gates with similar durations.\n", " - Otherwise some qubits will be idle for part of the moment.\n", " - It's best to align one-qubit gates in their own moment and two-qubit gates in their own moment if possible.\n", "\n", "- All measurements should be terminal and in a single moment.\n", " - Intermediate measurements are not currently supported, and measurement operation times are roughly two orders of magnitude longer than other gate times (see the above cell which prints out gatesets and gate times).\n" ] }, { "cell_type": "markdown", "metadata": { "id": "q66K76iTG23G" }, "source": [ "To align gates into moments and push them as far left as possible, use `cirq.align_left`." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "id": "MhFYbG0WGUML" }, "outputs": [ { "data": { "text/html": [ "
┌─────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐ ┌──────────────────┐ ┌───────────────────────┐\n", "(0, 0): ───S────────────────iSwap─────────────iSwap─────────────────────S^-1─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────iSwap─────────────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5─────────iSwap^0.5──────────────────────────iSwap──────────────────────────────iSwap────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────iSwap──────────────────iSwap^0.5──────────────────iSwap^0.5─────────S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145──────────iSwap─────────────────────iSwap────┼───────────────────PhX(-0.25)^0.75┼────────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────┼────────iSwap───────────────────────iSwap────────PhX(0.75)^0.5────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────PhX(0.75)^0.5─────┼────────PhX(0.5)^0.5─────┼────────┼────────Y^-0.5─────PhX(0.75)^-0.5─┼────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────┼────────────┼────────┼───────────────────────────┼─────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────PhX(-0.75)^0.5────┼─────────────────────────┼────────iSwap^0.5──────────────────────────iSwap^0.5────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────iSwap^0.5┼─────────────PhX(0.868)^0.5┼────────────PhX(0.618)^-0.5───Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5──────────────────────iSwap^0.5─────────────────iSwap^0.5────────────────────PhX(0.355)^0.5──────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───Z^-0.355──────────────iSwap^0.5───────────────────iSwap^0.5────PhX(-0.766)^0.5───Z^-0.484───\n", " └─────────────────────┘ └────────────────────────┘ └────────────────────────┘ └──────────────────┘ └───────────────────────┘" ], "text/plain": [ " ┌─────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐ ┌──────────────────┐ ┌───────────────────────┐\n", "(0, 0): ───S────────────────iSwap─────────────iSwap─────────────────────S^-1─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap──────────────────────iSwap─────────────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5─────────iSwap^0.5──────────────────────────iSwap──────────────────────────────iSwap────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────iSwap──────────────────iSwap^0.5──────────────────iSwap^0.5─────────S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145──────────iSwap─────────────────────iSwap────┼───────────────────PhX(-0.25)^0.75┼────────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────┼────────iSwap───────────────────────iSwap────────PhX(0.75)^0.5────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────PhX(0.75)^0.5─────┼────────PhX(0.5)^0.5─────┼────────┼────────Y^-0.5─────PhX(0.75)^-0.5─┼────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────┼────────────┼────────┼───────────────────────────┼─────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────PhX(-0.75)^0.5────┼─────────────────────────┼────────iSwap^0.5──────────────────────────iSwap^0.5────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────iSwap^0.5┼─────────────PhX(0.868)^0.5┼────────────PhX(0.618)^-0.5───Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5──────────────────────iSwap^0.5─────────────────iSwap^0.5────────────────────PhX(0.355)^0.5──────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───Z^-0.355──────────────iSwap^0.5───────────────────iSwap^0.5────PhX(-0.766)^0.5───Z^-0.484───\n", " └─────────────────────┘ └────────────────────────┘ └────────────────────────┘ └──────────────────┘ └───────────────────────┘" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "left_aligned_circuit = cirq.align_left(circuit)\n", "left_aligned_circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "J537zBXPHny4" }, "source": [ "Note: Optimizers can cause terminal measurements to become misaligned, but this can be fixed with `cirq.synchronize_terminal_measurements` as discussed below." ] }, { "cell_type": "markdown", "metadata": { "id": "dectZpWqHMFL" }, "source": [ "Note how many fewer moments this aligned circuit has." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "id": "o-MDeT-wHa97" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original circuit has 54 moments.\n", "Aligned circuit has 14 moments.\n" ] } ], "source": [ "print(f\"Original circuit has {len(circuit)} moments.\")\n", "print(f\"Aligned circuit has {len(left_aligned_circuit)} moments.\")" ] }, { "cell_type": "markdown", "metadata": { "id": "v7VhDhlOHQuQ" }, "source": [ "You can also align gates and push them to the right with `cirq.align_right`." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "id": "NOcRIJacGihn" }, "outputs": [ { "data": { "text/html": [ "
┌───────────────────────┐ ┌──────────────────┐ ┌──────────────────────┐ ┌──────────────────────────────┐ ┌───────────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────iSwap──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1───────────────────────────────iSwap──────────────────────iSwap─────────────M('z')──────────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────iSwap^0.5───────────────────iSwap─────────────────iSwap────────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z───────────────────────────────iSwap──────────────────iSwap─────────────────────iSwap^0.5──────────────────iSwap^0.5─────────S───────────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145───────────────────────iSwap─────────┼────────iSwap────────┼────────────────PhX(-0.25)^0.75───PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)────────Z^0.75───────┼─────────────iSwap────┼─────────────────────────iSwap────────────────────────────────────────PhX(0.75)^0.5───\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───────────────────────────────────────────────────┼─────────────┼────────┼────────────┼──────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────PhX(0.75)^0.5┼─────────────┼────────┼────────PhX(0.5)^0.5─────┼────────Y^-0.5────────────PhX(0.75)^-0.5────PhX(0)^-0.5─────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ────────────────────PhX(1)^0.5───────PhX(-0.75)^0.5┼─────────────iSwap^0.5┼────────────iSwap^0.5──────────────────────────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────iSwap^0.5─────┼────────iSwap^0.5─────────────────┼────────PhX(0.868)^0.5────PhX(0.618)^-0.5───Z^0.382─────────\n", " │ │ │ │\n", "(1, 2): ────────────────────PhX(0.75)^0.5──────────────────iSwap^0.5──────────────iSwap^0.5────PhX(0.355)^0.5───PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5────Z^-0.355───────────────────iSwap^0.5──────────────────────────iSwap^0.5──────────────────PhX(-0.766)^0.5───Z^-0.484────────\n", " └───────────────────────┘ └──────────────────┘ └──────────────────────┘ └──────────────────────────────┘ └───────────────────────┘" ], "text/plain": [ " ┌───────────────────────┐ ┌──────────────────┐ ┌──────────────────────┐ ┌──────────────────────────────┐ ┌───────────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────iSwap──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────S^-1───────────────────────────────iSwap──────────────────────iSwap─────────────M('z')──────────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────iSwap^0.5───────────────────iSwap─────────────────iSwap────────────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z───────────────────────────────iSwap──────────────────iSwap─────────────────────iSwap^0.5──────────────────iSwap^0.5─────────S───────────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───Z^-0.145───────────────────────iSwap─────────┼────────iSwap────────┼────────────────PhX(-0.25)^0.75───PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)────────Z^0.75───────┼─────────────iSwap────┼─────────────────────────iSwap────────────────────────────────────────PhX(0.75)^0.5───\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───────────────────────────────────────────────────┼─────────────┼────────┼────────────┼──────────────────────────────────────────────────────────────────────PhX(0)^0.5─────────PhX(0.75)^0.5┼─────────────┼────────┼────────PhX(0.5)^0.5─────┼────────Y^-0.5────────────PhX(0.75)^-0.5────PhX(0)^-0.5─────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ────────────────────PhX(1)^0.5───────PhX(-0.75)^0.5┼─────────────iSwap^0.5┼────────────iSwap^0.5──────────────────────────PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────iSwap^0.5─────┼────────iSwap^0.5─────────────────┼────────PhX(0.868)^0.5────PhX(0.618)^-0.5───Z^0.382─────────\n", " │ │ │ │\n", "(1, 2): ────────────────────PhX(0.75)^0.5──────────────────iSwap^0.5──────────────iSwap^0.5────PhX(0.355)^0.5───PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5────Z^-0.355───────────────────iSwap^0.5──────────────────────────iSwap^0.5──────────────────PhX(-0.766)^0.5───Z^-0.484────────\n", " └───────────────────────┘ └──────────────────┘ └──────────────────────┘ └──────────────────────────────┘ └───────────────────────┘" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "right_aligned_circuit = cirq.align_right(circuit)\n", "right_aligned_circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "R9SbfOfPVdMv" }, "source": [ "Also, you can use `cirq.stratified_circuit` to align operations into similar categories. For example, you can align single-qubit and two-qubit operations in separate moments as follows." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "id": "7LRQ3WooVd1Z" }, "outputs": [ { "data": { "text/html": [ "
┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n", " └──────────────────┘ └──────────────────┘" ], "text/plain": [ " ┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n", " └──────────────────┘ └──────────────────┘" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit = cirq.stratified_circuit(\n", " circuit, categories=[lambda op : len(op.qubits) == 1, lambda op : len(op.qubits) == 2]\n", ")\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "Z7U3Bu37Q0Hz" }, "source": [ "Note that each moment now only contains single-qubit gates or two-qubit gates." ] }, { "cell_type": "markdown", "metadata": { "id": "V1dZEX6uHIhD" }, "source": [ "#### Drop moments" ] }, { "cell_type": "markdown", "metadata": { "id": "yFRC4G8hI8W-" }, "source": [ "To drop moments that have a tiny effect or moments that are empty, you can use the following optimizers." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "id": "lUoGe6sAHItP" }, "outputs": [ { "data": { "text/html": [ "
┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n", " └──────────────────┘ └──────────────────┘" ], "text/plain": [ " ┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n", " └──────────────────┘ └──────────────────┘" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit = cirq.drop_negligible_operations(circuit)\n", "circuit = cirq.drop_empty_moments(circuit)\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "YdXaElSeIk3K" }, "source": [ "#### Synchronize terminal measurements" ] }, { "cell_type": "markdown", "metadata": { "id": "q0J0zRqjKKhP" }, "source": [ "You can use the `cirq.synchronize_terminal_measurements` to move all measurements to the final moment if it can accommodate them (without overlapping with other operations)." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "id": "0ZrpvUJyHzNh" }, "outputs": [ { "data": { "text/html": [ "
┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap──────────────────M('z')───\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S───────────────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5─────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼─────────────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382─────────────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484────────────\n", " └──────────────────┘ └──────────────────┘" ], "text/plain": [ " ┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────────iSwap──────────────────M('z')───\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap───────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S───────────────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼───────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5─────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼───────────────────────┼────────┼─────────────────────────────┼─────────────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5───────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382─────────────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355─────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484────────────\n", " └──────────────────┘ └──────────────────┘" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit = cirq.synchronize_terminal_measurements(circuit)\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "b5i41UXNfree" }, "source": [ "## Adding spin echoes" ] }, { "cell_type": "markdown", "metadata": { "id": "1VoTQNIzfupZ" }, "source": [ "[Dynamical decoupling](https://arxiv.org/abs/quant-ph/9803057) applies a series of spin echoes to otherwise idle qubits to reduce decoherent effects. As mentioned above, spin echoes were used as an effective error mitigation technique in [Information Scrambling in Computationally Complex Quantum Circuits](https://arxiv.org/abs/2101.08870), and the performance of any circuit with idle qubits can potentially be improved by adding spin echoes." ] }, { "cell_type": "markdown", "metadata": { "id": "rvo9HcLoKw4w" }, "source": [ "The following codeblock shows how to insert spin echoes on the ancilla qubit." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "id": "gyKYbFtt8Dvd" }, "outputs": [ { "data": { "text/html": [ "
┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1──────────────────────────────────PhX(0)────────────────────────PhX(0)────────────PhX(1)────────────PhX(1)────────────PhX(-0.5)─────────────────────PhX(-0.5)───────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼────────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355──────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n", " └──────────────────┘ └──────────────────┘" ], "text/plain": [ " ┌──────────────────┐ ┌──────────────────┐\n", "(0, 0): ───S────────────────iSwap────────────────────────iSwap───────S^-1──────────────────────────────────PhX(0)────────────────────────PhX(0)────────────PhX(1)────────────PhX(1)────────────PhX(-0.5)─────────────────────PhX(-0.5)───────────────────────────────────────────iSwap─────────────────────────iSwap───────M('z')─────\n", " │ │ │ │\n", "(0, 1): ────────────────────iSwap^0.5────────────────────iSwap^0.5────────────────────────────iSwap──────────────────────────iSwap───────PhX(-0.25)^0.5────PhX(0.75)^0.5─────PhX(-0.941)───────Z─────────────────iSwap────────────────────iSwap──────────────────────────────────iSwap^0.5─────────────────────iSwap^0.5───S──────────\n", " │ │ │ │\n", "(0, 2): ───PhX(-0.25)^0.5───────────────Z^-0.145─────────iSwap───────────────────────iSwap────┼────────────PhX(-0.25)^0.75───┼───────────PhX(-0.75)^-0.5───PhX(-0.5)^-0.5────PhX(-0.758)───────Z^0.75────────────┼────────────────────────┼────────iSwap─────────────────────────iSwap───────PhX(0.75)^0.5────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 0): ───PhX(0)^0.5───────────────────PhX(0.75)^0.5────┼───────────PhX(0.5)^0.5────┼────────┼────────────Y^-0.5────────────┼───────────PhX(0.75)^-0.5────PhX(0)^-0.5───────────────────────────────────────────┼────────────────────────┼────────┼─────────────────────────────┼────────────────────────────────────────────────────\n", " │ │ │ │ │ │ │ │\n", "(1, 1): ───PhX(1)^0.5───────────────────PhX(-0.75)^0.5───┼───────────────────────────┼────────iSwap^0.5──────────────────────iSwap^0.5───PhX(0)^0.5────────PhX(0)^0.5────────S───────────────────────────────────iSwap^0.5────────────────iSwap^0.5┼────────────PhX(0.868)^0.5───┼───────────PhX(0.618)^-0.5───────────────Z^0.382────\n", " │ │ │ │\n", "(1, 2): ───PhX(0.75)^0.5─────────────────────────────────iSwap^0.5───────────────────iSwap^0.5─────────────PhX(0.355)^0.5────────────────PhX(0.355)^0.5────PhX(0.355)^-0.5───PhX(0.855)^-0.5───PhX(0.355)^-0.5───────────────Z^-0.355──────────────iSwap^0.5─────────────────────iSwap^0.5───PhX(-0.766)^0.5───────────────Z^-0.484───\n", " └──────────────────┘ └──────────────────┘" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Gates for spin echoes. Note that these gates are self-inverse.\n", "pi_pulses = [\n", " cirq.PhasedXPowGate(phase_exponent=p, exponent=1.0) for p in (-0.5, 0.0, 0.5, 1.0)\n", "]\n", "\n", "# Generate spin echoes on ancilla.\n", "num_echoes = 3\n", "random_state = np.random.RandomState(1)\n", "\n", "spin_echo = []\n", "for _ in range(num_echoes):\n", " op = random_state.choice(pi_pulses).on(qubits[0])\n", " spin_echo += [op, cirq.inverse(op)]\n", "\n", "# Insert spin echo operations to circuit.\n", "optimized_circuit_with_spin_echoes = circuit.copy()\n", "optimized_circuit_with_spin_echoes.insert(5, spin_echo)\n", "\n", "# Align single-qubit spin echo gates into other moments of single-qubit gates.\n", "optimized_circuit_with_spin_echoes = cirq.stratified_circuit(\n", " optimized_circuit_with_spin_echoes, \n", " categories=[lambda op : len(op.qubits) == 1, lambda op : len(op.qubits) == 2]\n", ")\n", "optimized_circuit_with_spin_echoes" ] }, { "cell_type": "markdown", "metadata": { "id": "fshsOLq_05zV" }, "source": [ "The ancilla now has spin echoes between the two-qubit gates at the start/end of the circuit instead of remaining idle." ] }, { "cell_type": "markdown", "metadata": { "id": "nDOcuX94054O" }, "source": [ "## Benchmark" ] }, { "cell_type": "markdown", "metadata": { "id": "pclRv5YIMRM2" }, "source": [ "Now that we have discussed how to remove uncessary gates, align gates, and insert spin echoes, we run an experiment to benchmark the results. First we get a line of qubits, list of cycle values (one circuit per cycle value), and set other experimental parameters." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "id": "FGFb2YN43g9D" }, "outputs": [], "source": [ "\"\"\"Set experiment parameters.\"\"\"\n", "qubits = cg.line_on_device(device_sampler.device, length=7)\n", "cycle_values = range(0, 100 + 1, 4)\n", "nreps = 20_000\n", "seed = 1" ] }, { "cell_type": "markdown", "metadata": { "id": "B4Pbu2F9MTFg" }, "source": [ "The `create_benchmark_circuit` defined at the start of this tutorial has options to optimize the circuit and insert spin echoes on the ancilla as we have discussed above. Without any optimization or spin echoes, an example circuit looks like this:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "id": "qP8CWEPj_QkS" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Unoptimized circuit (47 moments):\n", "\n" ] }, { "data": { "text/html": [ "
┌─────────────────────────┐\n", "(3, 2): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────────────────────────────────────────────────────────M('z')───\n", " │ │\n", "(4, 1): ───────┼───────────────────────────PhX(-0.25)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5──────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────iSwap───────────────────────────────────────PhX(0.25)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5┼─────────────────────────────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(4, 2): ───────iSwap^0.5───PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────iSwap───────────────────PhX(-0.25)^0.5─────────────────────────────────────────────────────────────────────────────────┼───────────────────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───────────────────────────────────────────────────────────────────────────────────┼─────────────────────────PhX(-0.25)^-0.5──────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────PhX(0.25)^-0.5───────────────────iSwap^-0.5────────────────────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(5, 1): ────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────┼───────────iSwap────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────────────────────────iSwap^-0.5───────────────────────────────────────────────────PhX(0.75)^-0.5────────────────────────────────────────────────────┼────────────iSwap───────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(5, 2): ──────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5───iSwap^0.5───┼──────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───────────────iSwap──────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5────────────────iSwap────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5───iSwap^-0.5───┼────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n", " │ │ │ │\n", "(6, 1): ─────────────────────────────────────────────────────────────────PhX(1)^0.5────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────────────────────────────────┼───────────────────────────────────────────────────────PhX(-0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────iSwap^-0.5────────────────────────────────────────────────────────────────PhX(1)^-0.5───────────────────────────────────────────────\n", " │ │\n", "(6, 2): ──────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────iSwap^0.5───────────────────────────────────────────────────────────────PhX(0.5)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────iSwap^-0.5─────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5──────────────────────────────\n", " └─────────────────────────┘" ], "text/plain": [ " ┌─────────────────────────┐\n", "(3, 2): ───X───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────iSwap────────────────────────────────────────────────────────────────────────M('z')───\n", " │ │\n", "(4, 1): ───────┼───────────────────────────PhX(-0.25)^0.5───────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5─────────────────────────────────────────────────────────────────iSwap───────────────────────────────────PhX(0)^0.5──────────────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────iSwap───────────────────────────────────────PhX(0.25)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^-0.5┼─────────────────────────────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(4, 2): ───────iSwap^0.5───PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────iSwap───────────────────PhX(-0.25)^0.5─────────────────────────────────────────────────────────────────────────────────┼───────────────────────PhX(0.25)^0.5──────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5───────────────────────────────────────────────────────────────────────────────────┼─────────────────────────PhX(-0.25)^-0.5──────────────────────────────────────────────────────────────────────────────────────iSwap─────────────────────PhX(0.25)^-0.5───────────────────iSwap^-0.5────────────────────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(5, 1): ────────────────────────────────────────────────────PhX(0)^0.5─────────────────────────────────────────────────┼───────────iSwap────────────────────────────────────────PhX(0.75)^0.5─────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────PhX(0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────────────────────────iSwap^-0.5───────────────────────────────────────────────────PhX(0.75)^-0.5────────────────────────────────────────────────────┼────────────iSwap───────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────\n", " │ │ │ │\n", "(5, 2): ──────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^0.5───iSwap^0.5───┼──────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5───────────────iSwap──────────────────────────────────────────────────────────────────────────────────PhX(0.25)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.25)^-0.5────────────────iSwap────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5───iSwap^-0.5───┼────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n", " │ │ │ │\n", "(6, 1): ─────────────────────────────────────────────────────────────────PhX(1)^0.5────────────────────────────────────────────────iSwap^0.5────────────────────────────────────────────────────PhX(-0.75)^0.5────────────────────────────────────────────┼───────────────────────────────────────────────────────PhX(-0.5)^0.5─────────────────────────────────────────────────────────────────────────────────PhX(-0.5)^-0.5─────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────PhX(-0.75)^-0.5───────────────────────────────────────────────iSwap^-0.5────────────────────────────────────────────────────────────────PhX(1)^-0.5───────────────────────────────────────────────\n", " │ │\n", "(6, 2): ──────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5──────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0)^0.5───────────────────────────────iSwap^0.5───────────────────────────────────────────────────────────────PhX(0.5)^0.5───────────────────────────────────────────────────────────────────────────────────PhX(0.5)^-0.5─────────────────────────────────iSwap^-0.5─────────────────────────────────────────────────────────────────────────PhX(0)^-0.5─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^-0.5──────────────────────────────\n", " └─────────────────────────┘" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit = create_benchmark_circuit(qubits, cycles=2, seed=1)\n", "print(f\"Unoptimized circuit ({len(circuit)} moments):\\n\")\n", "circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "omR0mlzl_kGN" }, "source": [ "After removing unnecessary gates (optimization) and aligning gates, the same circuit looks like this:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "id": "f6sj5umf_W4J" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Circuit with optimization + alignment (15 moments):\n", "\n" ] }, { "data": { "text/html": [ "
┌────────────────────────────┐ ┌─────────────────────────┐\n", "(3, 2): ───PhX(0)───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Z────────────────iSwap──────────────────────────────────────────M('z')───\n", " │ │\n", "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n", " │ │\n", "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n", " │ │\n", "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n", " │ │ │ │\n", "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n", " │ │\n", "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n", "\n", "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n", " └────────────────────────────┘ └─────────────────────────┘" ], "text/plain": [ " ┌────────────────────────────┐ ┌─────────────────────────┐\n", "(3, 2): ───PhX(0)───iSwap────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────Z────────────────iSwap──────────────────────────────────────────M('z')───\n", " │ │\n", "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n", " │ │\n", "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n", " │ │\n", "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n", " │ │ │ │\n", "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n", " │ │\n", "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n", "\n", "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n", " └────────────────────────────┘ └─────────────────────────┘" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimized_circuit = create_benchmark_circuit(qubits, cycles=2, seed=1, with_optimization=True, with_alignment=True)\n", "print(f\"Circuit with optimization + alignment ({len(optimized_circuit)} moments):\\n\")\n", "optimized_circuit" ] }, { "cell_type": "markdown", "metadata": { "id": "9G4KFlAO_k5d" }, "source": [ "And with optimization + alginment + spin echoes on the ancilla, the same circuit looks like this:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "id": "g52V6Y4b0A7f" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Circuit with optimization + alignment + spin echoes (15 moments):\n", "\n" ] }, { "data": { "text/html": [ "
┌────────────────────────────┐ ┌─────────────────────────┐\n", "(3, 2): ───PhX(0)───iSwap────────────────────────PhX(0)──────PhX(0)───────────PhX(1)──────────PhX(1)───────────PhX(-0.5)─────────PhX(-0.5)─────────PhX(-0.5)───────────────────────PhX(-0.5)─────────Z────────────────iSwap──────────────────────────────────────────M('z')───\n", " │ │\n", "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n", " │ │\n", "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n", " │ │\n", "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n", " │ │ │ │\n", "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n", " │ │\n", "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n", "\n", "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n", " └────────────────────────────┘ └─────────────────────────┘" ], "text/plain": [ " ┌────────────────────────────┐ ┌─────────────────────────┐\n", "(3, 2): ───PhX(0)───iSwap────────────────────────PhX(0)──────PhX(0)───────────PhX(1)──────────PhX(1)───────────PhX(-0.5)─────────PhX(-0.5)─────────PhX(-0.5)───────────────────────PhX(-0.5)─────────Z────────────────iSwap──────────────────────────────────────────M('z')───\n", " │ │\n", "(4, 1): ────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(-0.25)^0.5────PhX(0.25)^0.5────┼──────────PhX(-0.75)^0.5────PhX(-0.25)^-0.5────────────\n", " │ │\n", "(4, 2): ────────────iSwap^0.5───PhX(0.25)^0.5────iSwap───────PhX(-0.25)^0.5───PhX(0.25)^0.5───PhX(0.25)^-0.5───PhX(-0.25)^-0.5───Z─────────────────iSwap───────────────────────────PhX(0.25)^0.5─────Z────────────────iSwap^0.5───────────────────────────────────────────────\n", " │ │\n", "(5, 1): ─────────────────────────────────────────┼────────────────────────────PhX(0)^0.5──────iSwap──────────────────────────────PhX(0.75)^0.5─────┼─────────────PhX(-0.25)^0.5────Z─────────────────iSwap────────────PhX(1)^-0.5──────────────────Z──────────────────────────\n", " │ │ │ │\n", "(5, 2): ────────────────────────PhX(-0.75)^0.5───iSwap^0.5────────────────────────────────────┼────────────────PhX(0.75)^0.5─────PhX(-0.25)^0.5────iSwap^0.5─────────────────────────────────────────┼─────────────────────────────────────────────PhX(-0.75)^-0.5────────────\n", " │ │\n", "(6, 1): ──────────────────────────────────────────────────────────────────────PhX(1)^0.5──────iSwap^0.5────────PhX(-0.75)^0.5────PhX(-0.5)^0.5─────PhX(-0.5)^-0.5──────────────────PhX(-0.75)^-0.5───iSwap^0.5─────────────────────────────────────X^0.5──────────────────────\n", "\n", "(6, 2): ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────PhX(0.75)^0.5─────PhX(0)^0.5───────X^-0.5───────────────────────PhX(0.75)^-0.5─────────────\n", " └────────────────────────────┘ └─────────────────────────┘" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimized_circuit_with_spin_echoes = create_benchmark_circuit(qubits, cycles=2, seed=1, with_optimization=True, with_alignment=True, with_spin_echoes=True)\n", "print(f\"Circuit with optimization + alignment + spin echoes ({len(optimized_circuit_with_spin_echoes)} moments):\\n\")\n", "optimized_circuit_with_spin_echoes" ] }, { "cell_type": "markdown", "metadata": { "id": "-ZldoKJBNVkj" }, "source": [ "Now we create circuits for all cycle values without optimization, with optimization + alignment, and with optimization + alignment + spin echoes." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "id": "GYmT7C5w2OxO" }, "outputs": [], "source": [ "\"\"\"Create all circuits.\"\"\"\n", "batch = [\n", " create_benchmark_circuit(qubits, cycles=c, seed=seed)\n", " for c in cycle_values\n", "]\n", "batch_with_optimization = [\n", " create_benchmark_circuit(qubits, cycles=c, seed=seed, with_optimization=True, with_alignment=True)\n", " for c in cycle_values\n", "]\n", "batch_with_optimization_and_spin_echoes = [\n", " create_benchmark_circuit(qubits, cycles=c, seed=seed, with_optimization=True, with_alignment=True, with_spin_echoes=True)\n", " for c in cycle_values\n", "]" ] }, { "cell_type": "markdown", "metadata": { "id": "LE3Af6DvNenw" }, "source": [ "The next cell runs them on the device." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "id": "p-vEk4p12tF3" }, "outputs": [], "source": [ "\"\"\"Run all circuits.\"\"\"\n", "all_probs = []\n", "for b in (batch, batch_with_optimization, batch_with_optimization_and_spin_echoes):\n", " results = device_sampler.sampler.run_batch(b, repetitions=nreps)\n", " all_probs.append([to_survival_prob(*res) for res in results])" ] }, { "cell_type": "markdown", "metadata": { "id": "wwAV401nNhGI" }, "source": [ "And the next cell plots the results." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "id": "m3DFhHXk3DC9" }, "outputs": [ { "data": { "image/png": "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smW88sordOvWjeuvv56XXnqJtm3bWuz/yCOPYDQaiYiI4LbbbmPp0qVFb/G9e/dmwoQJREZGMmHCBKKiomjSpAn9+/enS5cuzJw5s0qyfvvtt5w+fZoHHnigyGkM2kN+yZIldO3alc6dO/Ptt98CsGDBAhYuXEhERASJiXUjykpRfxF17UEYFRUlq1yYxpDDqv90J8bbiYVDF/KPkH9Uj3D1hL///puOHTs6WoxqY+nSpcTGxvLBBx84WhSFokYw939YCLFLShllrn/DmxEAOLsxtvtDBBvy+XDHPDUrUCgUDZqGqQgA51738+DVfA5knGJrwlZHi6OwI5MnT1azAYXCCg1WEeDiyZjI+wkxGPgw9m01K1AoFA2WhqsIAOc+DzI108DB9JP8cvYXR4ujUCgUDqFBKwLc/bix8520MBhYtOsdNStQKBQNkgahCKwlRXPqN40H07P5O/0km89udqCUCoVC4RjqvSIoNymapz/RHW6jlSGfRbsWYJRVS42gqB4SEhK46aabCA8Pp23btsyYMYO8vDyr5zgyrfSaNWs4ePBglcepDpKSknB2dmbx4sUl2lu3bk1SUhIA/fr1c4RoVtmzZw/r1693tBgNknqvCOb9dJhsQ8mU09mGAub9dLho36n/DB5My+Rw+kk2n1Gzggqz7yt4pwvE+Gmf+76q0nBSSsaPH8+4ceM4evQoR44cITMzk+eff97qeY5MK11aEdgjPXVMTAxLly4tt9/XX3/Nddddx/Llyy322b59ezVKVj0oReA46r0iOGcmD06Zdt9gRoXdRGtDPh/ufk/NCirCvq/gu+mQdhaQ2ud306ukDDZv3oybmxv33nsvoOUTeuedd/jkk0+4evWqQ9NK//e//6VXr1507dqVCRMmcPXqVbZv387atWuZOXMm3bp14/jx40XjAGzatInu3bsTERHBlClTyM3NBbQ39JdeeokePXoQERFRlKK6qixfvpy3336bxMREEhISzPYpLIRjNBp55JFH6NChA8OGDWP06NFFcluSLyYmhnvuuYeBAwfSqlUrVq9ezTPPPENERAQjR47EYNAqAu7atYtBgwbRs2dPRowYUZRwz1wa8by8PGbPns2KFSvo1q0bK1asqJZ7obCNeq8Imvu529TuNOAJHkxN42j6STaedsyUvlbywyz4NNry9u1jYCilbA3ZWrulc36Y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\n", "text/plain": [ "