{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ " Trusted Notebook\" width=\"500 px\" align=\"left\">" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Introducing the Qiskit Transpiler" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this notebook we introduce the Qiskit transpiler and walk through some examples of circuit transformations using **transpiler passes**.\n", "\n", "The transpiler is Qiskit's circuit rewriting framework. We do not call it a \"compiler\" on purpose, since we use compiler in the context of a larger translation from high level applications (potentially many circuits, with classical control flow between them) down to the level of machine pulses. The transpiler, in contrast, is responsible only for circuit-level analysis and transformations.\n", "\n", "Circuits are a fundamental and universal model of computation on quantum computers. In the Noisy Intermediate-Scale Quantum (NISQ) regime, we are always limited by the scarcity of quantum resources. The transpiler is a tool that helps us reduce the number of gates and qubits, in order to increase the fidelity of executions.\n", "\n", "Circuit optimization is a difficult task (in general QMA-complete). To make it approachable, we break it down. Each transpiler pass is thus responsible for doing one small, well-defined task. Through this \"separation of responsibilities\", we are able to chain together different passes to achieve an aggressive optimization goal.\n", "\n", "Which passes are chained together and in which order has a major effect on the final outcome. This pipeline is determined by a **pass manager**, which schedules the passes and also allows passes to communicate with each other by providing a shared space." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Transpiler API" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are two main ways to use the transpiler:\n", "1. Use the ``transpile()`` function, and specify some desired transpilation options, like ``basis_gates``, ``coupling_map``, ``initial_layout`` of qubits, or ``optimization_level``.\n", "\n", "2. Create your own custom pass manager." ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from qiskit.compiler import transpile\n", "from qiskit.transpiler import PassManager" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by a very simple transpilation task. Suppose we have a single toffoli gate which we want to unroll to a more fundamental basis." ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "q_0: |0>──■──\n", " │ \n", "q_1: |0>──■──\n", " ┌─┴─┐\n", "q_2: |0>┤ X ├\n", " └───┘" ], "text/plain": [ "