{
"cells": [
{
"cell_type": "markdown",
"id": "6c47ad18",
"metadata": {
"id": "6c47ad18"
},
"source": [
""
]
},
{
"cell_type": "markdown",
"id": "869e0a2b",
"metadata": {
"id": "869e0a2b"
},
"source": [
"# Lab 2: The Transpiler\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "GMWViIAFk0Pz",
"metadata": {
"id": "GMWViIAFk0Pz"
},
"source": [
"# Table of contents\n",
"\n",
"* [Prologue - What is the transpiler?](#prologue) \n",
"* [Transpile with Preset Pass Managers](#preset_passmanager) \n",
"* [Optimization levels](#optimization_level)\n",
" * [Optimization level = 0](#opt_lv_0)\n",
" * [Optimization level = 1](#opt_lv_1)\n",
" * [Optimization level = 2](#opt_lv_2)\n",
" * [Optimization level = 3](#opt_lv_3) \n",
"* [Transpiler Stage Details with Options](#transpiler_options)\n",
" * [Init stage](#init)\n",
" * [Layout Stage](#layout)\n",
" * [Routing Stage](#routing)\n",
" * [Translation Stage](#translation)\n",
" * [Optimization Stage](#optimization)\n",
" * [Scheduling Stage](#scheduling) \n",
"* [Build your own Pass Managers with Staged Pass Manager](#staged_pm) \n",
" * [Build `Dynamic Decoupling` Pass](#dd)\n",
"* [(Bonus) Ecosystem and Qiskit Transpiler Plugin](#plugin) "
]
},
{
"cell_type": "markdown",
"id": "dacee2d4",
"metadata": {
"id": "dacee2d4"
},
"source": [
"\n",
"\n",
"\n",
"# Setup\n",
"\n",
"To run this lab properly, we need several packages. If you haven't yet installed Qiskit and relevant packages, please run the cells below after uncommenting and restarting the kernel."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1b8150ce-b900-4adf-a2c7-f5d80a1e6d70",
"metadata": {
"id": "1b8150ce-b900-4adf-a2c7-f5d80a1e6d70"
},
"outputs": [],
"source": [
"### Install Qiskit and relevant packages, if needed\n",
"\n",
"%pip install qiskit[visualization]==1.0.2\n",
"%pip install qiskit_ibm_runtime\n",
"%pip install qiskit_aer\n",
"%pip install qiskit-transpiler-service\n",
"%pip install graphviz\n",
"%pip install git+https://github.com/qiskit-community/Quantum-Challenge-Grader.git"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "EgHX0RuznCvl",
"metadata": {
"id": "EgHX0RuznCvl"
},
"outputs": [],
"source": [
"### Save API Token, if needed\n",
"\n",
"%set_env QXToken=deleteThisAndPasteYourTokenHere\n",
"\n",
"# Make sure there is no space between the equal sign\n",
"# and the beginning of your token"
]
},
{
"cell_type": "markdown",
"id": "684bbb4a-9576-474c-83fe-31d712ceb87c",
"metadata": {
"id": "684bbb4a-9576-474c-83fe-31d712ceb87c"
},
"source": [
"Now, let's run our imports and setup the grader"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "9pEFjWUcxKm-",
"metadata": {
"id": "9pEFjWUcxKm-"
},
"outputs": [],
"source": [
"# Imports\n",
"\n",
"from qiskit.circuit.random import random_circuit\n",
"from qiskit.circuit.library import XGate, YGate\n",
"from qiskit_ibm_runtime.fake_provider import FakeTorino, FakeOsaka\n",
"from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n",
"from qiskit.transpiler import InstructionProperties, PassManager\n",
"from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
"from qiskit.transpiler.preset_passmanagers.plugin import list_stage_plugins\n",
"from qiskit.transpiler.timing_constraints import TimingConstraints\n",
"from qiskit.transpiler.passes.scheduling import ASAPScheduleAnalysis,PadDynamicalDecoupling\n",
"from qiskit.visualization.timeline import draw, IQXStandard\n",
"from qiskit.transpiler import StagedPassManager\n",
"from qiskit.visualization import plot_circuit_layout\n",
"from qiskit.quantum_info.analysis import hellinger_fidelity\n",
"from qiskit.visualization import plot_distribution\n",
"from qiskit_aer import AerSimulator\n",
"\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b59eb187",
"metadata": {
"id": "b59eb187"
},
"outputs": [],
"source": [
"# Setup the grader\n",
"from qc_grader.challenges.iqc_2024 import (\n",
" grade_lab2_ex1,\n",
" grade_lab2_ex2,\n",
" grade_lab2_ex3,\n",
" grade_lab2_ex4,\n",
" grade_lab2_ex5\n",
")"
]
},
{
"cell_type": "markdown",
"id": "g_Uy-O8nnpNR",
"metadata": {
"id": "g_Uy-O8nnpNR"
},
"source": [
"This lab must use Qiskit v1.0.2. Before we start, let's check your environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "rwT3zn80nrOL",
"metadata": {
"id": "rwT3zn80nrOL"
},
"outputs": [],
"source": [
"from util import version_check\n",
"\n",
"version_check()"
]
},
{
"cell_type": "markdown",
"id": "438aa753",
"metadata": {
"id": "438aa753"
},
"source": [
"# Prologue - What is the transpiler?"
]
},
{
"cell_type": "markdown",
"id": "0d18fa3b-416a-4de6-bae4-09dbd863ed90",
"metadata": {
"id": "0d18fa3b-416a-4de6-bae4-09dbd863ed90"
},
"source": [
"Let's start with a hypothetical question:\n",
"\n",
"When someone hands you their car keys and says \"will you fill my car up with fuel?\" - how do you know what to do?\n",
"\n",
"Sure, you have your driver's license, but what type of car do they have? Where is their gear shifter? How do you turn on the blinker to turn the corner, or open the fuel tank once your arrive? What if it's an electric car that doesn't even *have* a fuel tank??\n",
"\n",
"Luckily, the human brain is smart. It is able to take a set of instructions and adapt them to the vehicle being used.\n",
"\n",
"That, in essence, is the transpiler."
]
},
{
"cell_type": "markdown",
"id": "Xz013UUMKMxk",
"metadata": {
"id": "Xz013UUMKMxk"
},
"source": [
"Transpilation is the process of taking a given input circuit and rewriting it to an equivalent circuit for a specific quantum device, and/or to optimize the circuit for execution on a real quantum system.\n",
"\n",
"This is necessary because not all quantum devices work the same way. The instructions you send to one device might not be compatible with a different quantum backend. Transpilation operates in terms of a device's basis gate set, the topology of the quantum chips, timing constraints, and more which we will explore in this lab.\n",
"\n",
"The goal of a transpiler is to get the best performance from noisy quantum hardware. Most circuits must undergo a series of transformations that make them compatible with a given target device, and optimize them to reduce the effects of noise on the resulting outcomes.\n",
"\n",
"**For example:** the process of transpilation can take a simple looking circuit that contains your instructions:"
]
},
{
"cell_type": "markdown",
"id": "1401a733-a9bb-432b-a2e4-e3160c2ad9ce",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"id": "79697b94-47d5-4fc7-a007-5fd6df339b69",
"metadata": {},
"source": [
"And transform it to provide the circuit you want, but by only using the basis gates or instructions that a given quantum computer is able to accept. It also will optimize those instructions in order to minimize the effects of noise:"
]
},
{
"cell_type": "markdown",
"id": "edf24741-adb2-4d0f-b64f-572ab3ff7657",
"metadata": {},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"id": "c1b3564f-b96a-4cf2-9bdb-8fa63b104505",
"metadata": {
"id": "c1b3564f-b96a-4cf2-9bdb-8fa63b104505"
},
"source": [
"A central component of the Qiskit SDK, the transpiler is designed for modularity and extensibility. Its main goal is to write new circuit transformations (known as transpiler passes), and combine them with other existing passes, greatly reducing the depth and complexity of quantum circuits. Which passes are chained together and in which order has a major effect on the final outcome. This pipeline is determined by the [PassManager](https://docs.quantum.ibm.com/api/qiskit/qiskit.transpiler.PassManager) and [StagedPassManager](https://docs.quantum.ibm.com/api/qiskit/qiskit.transpiler.StagedPassManager) objects.\n",
"\n",
"The `StagedPassManager` orchestrates the execution of one or more `PassManagers` and determines the order in which they are executed, while the `PassManager` object is merely a collection of one or more passes. Think of the `StagedPassManager` as the conductor in an orchestra, the `PassManagers` as the different instrument sections, and the `Pass` objects as the individual musicians.\n",
"\n",
"In this way, you can compose hardware-efficient quantum circuits that let you execute utility-scale work while keeping noise manageable. For more details, visit the [Transpile](https://docs.quantum.ibm.com/transpile) section in the IBM Quantum Platform docs."
]
},
{
"cell_type": "markdown",
"id": "9f5929ce-0456-47a3-87e1-e24f9877dc4d",
"metadata": {
"id": "9f5929ce-0456-47a3-87e1-e24f9877dc4d"
},
"source": [
"## The six stages\n",
"\n",
"Rewriting quantum circuits to match hardware constraints and optimizing for performance can be far from trivial. Qiskit provides users the standard six stages of compilation flows with four pre-built transpilation pipelines. By default, the preset pass managers are composed of six stages, with several options in each stages:\n"
]
},
{
"cell_type": "markdown",
"id": "fc0f3d06",
"metadata": {
"id": "fc0f3d06"
},
"source": [
"\n",
"- `Init`: This pass runs any initial passes that are required before we start embedding the circuit to the system. This typically involves unrolling custom instructions and converting the circuit to all single- and two-qubit gates. (By default this will just validate the circuit instructions and translate multi-qubit gates into single- and two-qubit gates.)\n",
" \n",
"- `Layout`: This stage applies a layout, mapping the virtual qubits in the circuit to the physical qubits on a backend.\n",
"\n",
"- `Routing`: This stage runs after a layout has been applied and will inject gates (i.e. swaps) into the original circuit to make it compatible with the backend’s connectivity.\n",
" \n",
"- `Translation`: This stage translates the gates in the circuit to the target backend’s basis set.\n",
"- `Optimization`: This stage runs the main optimization loop repeatedly until a condition (such as fixed depth) is reached.\n",
"- `Scheduling`: This stage is for any hardware-aware scheduling passes.\n",
"\n",
"\n",
"Qiskit also provides four pre-defined levels of transpilation that users can choose according to their needs. You can modify these preset pass managers, and in addition, you can construct a pass manager to build an entirely custom pipeline for transforming input circuits.\n",
"\n",
"For most users who are not familiar with quantum circuit optimization by transpiling, we suggest to use one of the ready-made routines. However in this lab we will be diving deep (deeeeeeeep!) into each stage and the options within."
]
},
{
"cell_type": "markdown",
"id": "cf273e41-76a0-4986-9257-cd592373f77c",
"metadata": {
"id": "cf273e41-76a0-4986-9257-cd592373f77c"
},
"source": [
"