---
title: transpiler (latest version)
description: API reference for qiskit.transpiler in the latest version of qiskit
source: https://eu-de.quantum.cloud.ibm.com/docs/en/api/qiskit/transpiler
---

# Transpiler

`qiskit.transpiler`

## Overview

> **Note**
>
> If you are already familiar with the concepts of circuit transpilation / compilation, you may want to skip ahead to:
>
> - [Descriptions of the preconfigured pass managers](#transpiler-preset). This includes descriptions of the stages, and of all the available built-in plugins.
> - [Documentation on building a custom transpiler pass](#transpiler-custom-passes).

Transpilation is the process of rewriting a given input circuit to match the topology of a specific quantum device, and/or to optimize the circuit for execution on quantum systems.

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. Rewriting quantum circuits to match hardware constraints and optimizing for performance can be far from trivial. The flow of logic in the rewriting tool chain need not be linear, and can often have iterative sub-loops, conditional branches, and other complex behaviors. That being said, the standard compilation flow follows the structure given below:

![The transpilation process takes the input circuit, applies the transpilation       passes, then produces the output circuit.](https://eu-de.quantum.cloud.ibm.com/docs/images/api/qiskit/transpiling_core_steps.avif)

Qiskit uses the graph-based [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") intermediate representation (IR) of a circuit throughout the transpiler stack, rather than the tree-based [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). A transpiler pipeline is a [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") object, whose [`PassManager.run()`](/docs/api/qiskit/qiskit.transpiler.PassManager#run "qiskit.transpiler.PassManager.run") method takes in a [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") and converts it to a [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit"), then subjects the IR to a sequence of *passes*, finally returning a [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") back. A pass is either an [`AnalysisPass`](/docs/api/qiskit/qiskit.transpiler.AnalysisPass "qiskit.transpiler.AnalysisPass"), which calculates and stores properties about the circuit in the stateful [`PropertySet`](/docs/api/qiskit/qiskit.passmanager.PropertySet "qiskit.passmanager.PropertySet"), or a [`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.TransformationPass"), which modifies the IR to achieve a particular singular goal. You can think of a pipeline as being split into “stages”, where each stage is responsible for one high-level transformation.

Qiskit exposes a default transpilation pipeline builder using the function [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager"). This returns a properly configured pipeline for complete transpilation, at a chosen `optimization_level` (between 0 and 3, inclusive). Unless you are looking for something highly specialized, this is almost certainly the entry point you want. A sample transpilation looks like:

```python
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService

# Any abstract circuit you want:
abstract = QuantumCircuit(2)
abstract.h(0)
abstract.cx(0, 1)

# Any method you like to retrieve the backend you want to run on:
backend = QiskitRuntimeService().backend("some-backend")

# Create the pass manager for the transpilation ...
pm = generate_preset_pass_manager(backend=backend)
# ... and use it (as many times as you like).
physical = pm.run(abstract)
```

For early experiments towards fault tolerance, the functions [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") and [`transpile()`](/docs/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") invoke a specialized transpilation pipeline when the target basis consists of Clifford+T gates, see [`generate_preset_clifford_t_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_clifford_t_pass_manager "qiskit.transpiler.generate_preset_clifford_t_pass_manager") for documentation. It is recommended to use the latter for a detailed configuration of Clifford+T pipelines. For example, the $R_Z$ synthesis accuracy cannot be set via `"unitary_synthesis_method"` in [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") but can only be globally set via the `"approximation_degree"`. However, [`generate_preset_clifford_t_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_clifford_t_pass_manager "qiskit.transpiler.generate_preset_clifford_t_pass_manager") exposes `"rz_synthesis_config"` for this matter.

For example:

```python
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import QFTGate
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import get_clifford_gate_names

# Any abstract circuit you want:
abstract = QuantumCircuit(4)
abstract.append(QFTGate(4), [0, 1, 2, 3])

# Use all Clifford+T basis gates
basis_gates = get_clifford_gate_names() + ["t", "tdg"]

# Create and run the pass manager
pm = generate_preset_pass_manager(basis_gates=basis_gates)
transpiled = pm.run(abstract)
```

For most use cases, this is all you need. All of Qiskit’s transpiler infrastructure is highly extensible and configurable, however. The rest of this page details how to harness the low-level capabilities of the transpiler stack.

## Preset pass managers

The function [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") creates the “preset pass managers”. These are all instances of [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager"), so are used by passing a [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") to the [`PassManager.run()`](/docs/api/qiskit/qiskit.transpiler.PassManager#run "qiskit.transpiler.PassManager.run") method. More specifically, the preset pass managers are instances of [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager"), which allows greater configuration of the individual stages of a transpilation, including pre- and post-stage hooks.

A preset pass manager has up to six named stages. These are summarized, in order of execution, below, with more in-depth information in the following subsections.

**`init`**

Abstract-circuit optimizations, and reduction of multi-qubit operations to one- and two-qubit operations. See [Initialization stage](#transpiler-preset-stage-init) for more details.

**`layout`**

Choose an initial mapping of virtual qubits to physical qubits, including expansion of the circuit to contain explicit ancillas. This stage sometimes subsumes `routing`. See [Layout stage](#transpiler-preset-stage-layout) for more details.

**`routing`**

Insert gates into the circuit to ensure it matches the connectivity constraints of the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target"). The inserted gates need not match the target ISA yet, so are often just `swap` instructions. This stage is sometimes omitted, when the `layout` stage handles its job. See [Routing stage](#transpiler-preset-stage-routing) for more details.

**`translation`**

Convert all gates in the circuit to ones matching the ISA of the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target"). See [Translation stage](#transpiler-preset-stage-translation) for more details.

**`optimization`**

Low-level, hardware-aware optimizations. Unlike the abstract optimizations of the `init` stage, this stage acts on a physical circuit. See [Optimization stage](#transpiler-preset-stage-optimization) for more details.

**`scheduling`**

Insert [`Delay`](/docs/api/qiskit/circuit#qiskit.circuit.Delay "qiskit.circuit.Delay") instructions to make the wall-clock timing of a circuit explicit. This may also include hardware-aware online error reduction techniques such as dynamical decoupling, which are dependent on knowing wall-clock timings. See [Scheduling stage](#transpiler-preset-stage-scheduling) for more details.

The preset transpiler pipelines can also be configured at a high level by setting an `optimization_level`. This is an integer from 0 to 3, inclusive, indicating the relative effort to exert in attempting to optimize the circuit for the hardware. Level 0 disables all unnecessary optimizations; only transformations needed to make the circuit runnable are used. On the other end, level 3 enables a full range of optimization techniques, some of which can be very expensive in compilation time. Similar to classical compilers, optimization level 3 is not always guaranteed to produce the best results. Qiskit defaults to optimization level 2, as a trade-off between compilation time and the expected amount of optimization.

The optimization level affects which implementations are used for a given stage by default, though this can be overridden by passing explicit `<stage>_method="<choice>"` arguments to [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager").

### Reproducibility of the preset pipelines

Quantum compilation often involves solving problems that are known to be non-polynomial in complexity, and so are intractable to globally optimize. In these cases, stochastic and heuristic algorithms are often more appropriate. This leads to problems of reproducibility, however.

The preset pass managers almost always include stochastic, heuristic-based passes. If you need to ensure reproducibility of a compilation, pass a known integer to the `seed_transpiler` argument of the generator functions.

All built-in plugins to Qiskit are required to produce their analyses and modify the [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") in deterministic ways if their randomization (if any) is seeded, so that a compilation can be repeated later. There are limits on this:

- All built-in passes with stochastic components must provide a way to seed the randomization, and if seeded, they must respect the rules of deterministic output.
- All built-in passes without stochastic components must respect the rules of deterministic output for identical input. It is permissible to keep a cache for efficiency, but given the same set of inputs, the pass’s returns must be the same if the pass is called multiple times, unless something outside the pass’s control mutates one of its inputs in-place (for example, the [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator "qiskit.transpiler.passes.BasisTranslator") uses the [`SessionEquivalenceLibrary`](/docs/api/qiskit/circuit#qiskit.circuit.SessionEquivalenceLibrary "qiskit.circuit.SessionEquivalenceLibrary") by default in the preset pass managers, and it is not a bug to get different results if new entries are added to the equivalence library). An “output” is anything the pass writes out for further consumption; this can be the explicit `return` value from the pass, but also includes properties intended for later consumption in the [`PropertySet`](/docs/api/qiskit/qiskit.passmanager.PropertySet "qiskit.passmanager.PropertySet").
- The output of a pass should be deterministic on a given machine for a given version of Qiskit and a frozen environment, no matter how many threads are available for the pass. Many built-in Qiskit passes use threaded concurrency, and they are not permitted to have different behavior based on the number of threads.
- The output of a pass for a fixed seed is not required to be equal if some part of the underlying Python environment changes (such as a dependent package updating), or if the system mathematical libraries change (such as a different implementation of BLAS is available).
- The output of a pass for a fixed seed is not required to be equal between operating systems (although typically, it is the implementation of the system mathematical library that is the root cause of operating-system-related differences).
- The output of a pass for a fixed seed is not required to be the same between two machines that have different CPU instructions available; it is expected that different implementations of core mathematical kernels may produce different behavior if different CPU instructions are available, such as fused multiply-add instructions having different rounding characteristics to two separate floating-point multiply and add instructions.
- The output of a pass for a fixed seed must be the same, regardless of the number of threads it is allowed to use, unless the user specifically opts out of this behavior. For example in the preset passmanagers, the Sabre layout and routing methods need to run the same number of trials by default, no matter if there is a single thread allowed or even more threads than trials, though this behavior can be explicitly overridden by setting the `QISKIT_SABRE_ALL_THREADS` environment variable to opt in to becoming sensitive to the thread count.
- All the above rules apply even between separate Python interpreter sessions, even when `PYTHONHASHSEED` has not been explicitly set.

In general, a consumer of the [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") should be able to assume, after any combination of built-in, seeded if appropriate, Qiskit passes have run with fixed inputs, that the exact output of all `DAGCircuit()` methods is deterministic. This includes the order of output even of methods that do not make any promise about the order; while the semantics and precise order cannot be relied on, the determinism of it for fixed inputs can.

Transpiler-pass authors should consult [Randomness and determinism](#transpiler-custom-passes-determinism) for a discussion of how to make a transpiler pass deterministic.

### Choosing preset stage implementations

Qiskit includes several implementations of the above stages, and more can be installed as separate “plugins”. To control which implementation of a stage is used, pass its name to the `<stage>_method` keyword argument of the two functions, such as `translation_method="translator"`. To read more about implementing such external plugins for a stage, see [`qiskit.transpiler.preset_passmanagers.plugin`](/docs/api/qiskit/transpiler_plugins#module-qiskit.transpiler.preset_passmanagers.plugin "qiskit.transpiler.preset_passmanagers.plugin").

For example, to generate a preset pass manager at optimization level 1 that explicitly uses the `trivial` method for layout with the `sabre` method for routing, we would do:

```python
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.providers.fake_provider import GenericBackendV2

# Whatever backend you like:
backend = GenericBackendV2(num_qubits=5)

pass_manager = generate_preset_pass_manager(
    optimization_level=1,
    backend=backend,
    layout_method="trivial",
    routing_method="sabre",
)
```

> **Note**
>
> The built-in set of available plugins for each stage is part of Qiskit’s public API, and subject to all the stability guarantees. This includes the high-level logical effects of that method (for example, `routing_method="sabre"` will always use a Sabre-derived algorithm). The exact internal construction of the [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") representing the stage is not, however; the order of passes might change between minor versions, or new passes might be introduced.
>
> For any stage that has one, the method named `"default"` is the most subject to change. Qiskit typically only makes complete algorithmic changes in the default method across a major-version boundary, but it might rebalance heuristics and add new passes to default methods between minor versions.

Since the output of [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") is a [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager"), you can also modify the pass manager after its creation to provide an entirely custom stage implementation. For example, if you wanted to run a custom scheduling stage using dynamical decoupling (using the [`PadDynamicalDecoupling`](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling "qiskit.transpiler.passes.PadDynamicalDecoupling") pass) and also add initial logical optimization prior to routing, you would do something like the following (building off the previous example):

```python
import numpy as np
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit.circuit import library as lib
from qiskit.transpiler import PassManager, generate_preset_pass_manager
from qiskit.transpiler.passes import (
    ALAPScheduleAnalysis,
    InverseCancellation,
    PadDynamicalDecoupling,
)

backend = GenericBackendV2(num_qubits=5)
dd_sequence = [lib.XGate(), lib.XGate()]
scheduling_pm = PassManager(
    [
        ALAPScheduleAnalysis(target=backend.target),
        PadDynamicalDecoupling(target=backend.target, dd_sequence=dd_sequence),
    ]
)
inverse_gate_list = [
    lib.CXGate(),
    lib.HGate(),
    (lib.RXGate(np.pi / 4), lib.RXGate(-np.pi / 4)),
    (lib.PhaseGate(np.pi / 4), lib.PhaseGate(-np.pi / 4)),
    (lib.TGate(), lib.TdgGate()),
]
logical_opt = PassManager([InverseCancellation(inverse_gate_list)])

pass_manager = generate_preset_pass_manager(optimization_level=0)
# Add pre-layout stage to run extra logical optimization
pass_manager.pre_layout = logical_opt
# Set scheduling stage to custom pass manager
pass_manager.scheduling = scheduling_pm
```

Now, when the staged pass manager is run via the [`run()`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager#run "qiskit.transpiler.StagedPassManager.run") method, the `logical_opt` pass manager will be called before the `layout` stage, and the `scheduling_pm` pass manager will be used for the `scheduling` stage instead of the default.

If you are constructing custom stages for the preset pass managers, you may find some of the low-level helper functions in [`qiskit.transpiler.preset_passmanagers`](/docs/api/qiskit/transpiler_preset#module-qiskit.transpiler.preset_passmanagers "qiskit.transpiler.preset_passmanagers") useful.

### Initialization stage

> **See also**
>
> **[Init stage explanation](/docs/guides/transpiler-stages#init-stage)**
>
> Higher-level user-facing explanation of the init stage in the IBM Quantum guide.

The `init` stage is responsible for high-level, logical optimizations on abstract circuits, and for lowering multi-qubit (3+) operations down to a series of one- and two-qubit operations. As this is the first stage run, its input is a fully abstract circuit. The `init` stage must be able to handle custom user-defined gates, and all the high-level abstract circuit-description objects, such as [`AnnotatedOperation`](/docs/api/qiskit/qiskit.circuit.AnnotatedOperation "qiskit.circuit.AnnotatedOperation").

The output of the `init` stage is an abstract circuit that contains only one- and two-qubit operations.

When writing [stage plugins](/docs/api/qiskit/transpiler_plugins#transpiler-preset-stage-plugins), the entry point for `init` is `qiskit.transpiler.init`. The built-in plugins are:

| Method                                           | Summary                                                                  |
| ------------------------------------------------ | ------------------------------------------------------------------------ |
| [default](#transpiler-preset-stage-init-default) | Built-in unrolling of multi-qubit operations and abstract optimizations. |

#### Built-in `default` plugin

At optimization level 0, no abstract optimization is done. The default plugin simply “unrolls” operations with more than three qubits by accessing their hierarchical [`definition`](/docs/api/qiskit/qiskit.circuit.Instruction#definition "qiskit.circuit.Instruction.definition") fields.

At optimization levels 1 and above, the default plugin also does simple cancellation of adjacent inverse gates, such as two back-to-back `cx` gates.

At optimization levels 2 and 3, the default plugin enables a much wider range of abstract optimizations. This includes:

- “Virtual permutation elision” (see [`ElidePermutations`](/docs/api/qiskit/qiskit.transpiler.passes.ElidePermutations "qiskit.transpiler.passes.ElidePermutations")), where explicit permutation-inducing operations are removed and instead effected as remapping of virtual qubits.
- Analysis of the commutation structure of the IR to find pairs of gates that can be canceled out.
- Numerical splitting of two-qubit operations that can be expressed as a series of separable one-qubit operations.
- Removal of imperceivable operations, such as tiny-angle Pauli rotations and diagonal operations immediately preceding measurements.

### Layout stage

> **See also**
>
> **[Layout stage explanation](/docs/guides/transpiler-stages#layout-stage)**
>
> Higher-level user-facing explanation of the layout stage in the IBM Quantum guide.

The layout stage is responsible for making an initial mapping between the virtual qubits of the input circuit, and the hardware qubits of the target. This includes expanding the input circuit with explicit ancillas so it has as many qubits as the target has, and rewriting all operations in terms of hardware qubits. You may also see this problem called the “placement” problem in other toolkits or literature.

The layout stage must set the properties `layout` and `original_qubit_indices` in the pipeline’s [`PropertySet`](/docs/api/qiskit/qiskit.passmanager.PropertySet "qiskit.passmanager.PropertySet").

> **Note**
>
> All built-in plugins for the layout stage will give priority to an explicit layout selected using the `initial_layout` argument to [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") or [`transpile()`](/docs/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile").

At any given point in a circuit, we can identify a mapping between currently active “virtual” qubits of the input circuit to hardware qubits of the backend. A hardware qubit can only ever represent a single virtual qubit at a given point, but the mapping might vary over the course of the circuit. In principle, some virtual qubits might not be mapped at all points in the circuit execution, if the lifetime of a virtual qubit state can be shortened, though Qiskit’s built-in pipelines do not use this currently.

![Illustration of how virtual qubits from an input circuit could be mapped to hardware qubits on a backend device's connectivity map.](https://eu-de.quantum.cloud.ibm.com/docs/images/api/qiskit/mapping.avif)

The layout stage is not responsible for ensuring that the connectivity of the target is respected all the way through the circuit, nor that all operations are valid for direct execution on the target; these are the responsibilities of the [routing](#transpiler-preset-stage-routing) and [translation](#transpiler-preset-stage-translation) stages, respectively.

The choice of initial layout is one of the most important factors that affects the quality of the output circuit. The layout stage is often the most computationally expensive stage in the default pipelines; the default plugin for layout even tries several different algorithms (described in more detail in [Built-in default plugin](#transpiler-preset-stage-layout-default)).

The ideal situation for the layout stage is to find a “perfect” layout, where all operations respect the connectivity constraints of the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") such that the routing stage is not required. This is typically not possible for arbitrary input circuits, but when it is, the [`VF2Layout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2Layout "qiskit.transpiler.passes.VF2Layout") pass can be used to find a valid initial layout. If multiple perfect layouts are found, a scoring heuristic based on estimated error rates is used to decide which one to use.

In all built-in plugins, passing the [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") argument `initial_layout` causes the given layout to be used verbatim, skipping the individual “choosing” logic. All built-in plugins also handle embedding the circuit into the full width of the device, including assigning ancillas.

If you write your own layout plugin, you might find [`generate_embed_passmanager()`](/docs/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_embed_passmanager "qiskit.transpiler.preset_passmanagers.generate_embed_passmanager") useful for automating the “embedding” stage of the layout application.

When writing [stage plugins](/docs/api/qiskit/transpiler_plugins#transpiler-preset-stage-plugins), the entry point for `layout` is `qiskit.transpiler.layout`. The built-in plugins are:

| Method                                             | Summary                                                                                                                           |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| [default](#transpiler-preset-stage-layout-default) | At the highest optimization levels, attempts to find a perfect layout, then tries a Sabre-based layout-and-routing combined pass. |
| [dense](#transpiler-preset-stage-layout-dense)     | Finds the densest subgraph (in terms of qubit link degrees) of the backend to use as the initial qubits.                          |
| [trivial](#transpiler-preset-stage-layout-trivial) | Maps virtual qubit 0 to physical qubit 0, and so on.                                                                              |
| [sabre](#transpiler-preset-stage-layout-sabre)     | Uses [Qiskit’s enhanced Sabre layout algorithm](https://arxiv.org/abs/2409.08368).                                                |

At all optimization levels, the default layout method is `default`, though the structure of this stage changes dramatically based on the level.

#### Built-in `default` plugin

An amalgamation of several different layout techniques.

At optimization level 0, the trivial layout is chosen.

At optimization levels above 0, there is a two-step process:

1. First, use [`VF2Layout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2Layout "qiskit.transpiler.passes.VF2Layout") to attempt to find a “perfect” layout. The maximum number of calls to the isomorphism evaluator increases with the optimization level. For huge, complex targets, we are not guaranteed to find perfect layouts even if they exist, but the chance increases with the optimization level.
2. If no perfect layout can be found, use [`SabreLayout`](/docs/api/qiskit/qiskit.transpiler.passes.SabreLayout "qiskit.transpiler.passes.SabreLayout") to choose an initial layout, with the numbers of initial layout trials, swap-map trials, and forwards–backwards iterations increasing with the optimization level.

In addition, optimization level 1 also tries the trivial layout before the VF2-based version, for historical backwards compatibility.

#### Built-in `dense` plugin

Uses the [`DenseLayout`](/docs/api/qiskit/qiskit.transpiler.passes.DenseLayout "qiskit.transpiler.passes.DenseLayout") pass to choose the layout. This pass finds the densest connected subgraph of the complete target connectivity graph, where “densest” means that hardware qubits with the greatest number of available connections are preferred. The virtual-to-hardware mapping is completed by assigning the highest-degree virtual qubits to the highest-degree hardware qubits.

This is a relatively cheap heuristic for choosing an initial layout, but typically has far worse output quality than Sabre-based methods. The [default layout plugin](#transpiler-preset-stage-layout-default) uses the initial mapping selected by [`DenseLayout`](/docs/api/qiskit/qiskit.transpiler.passes.DenseLayout "qiskit.transpiler.passes.DenseLayout") as one of its initial layouts to seed the Sabre algorithm.

#### Built-in `trivial` plugin

Uses the [`TrivialLayout`](/docs/api/qiskit/qiskit.transpiler.passes.TrivialLayout "qiskit.transpiler.passes.TrivialLayout") pass to choose the layout. This is the simplest assignment, where each virtual qubit is assigned to the hardware qubit with the same index, so virtual qubit 0 is mapped to hardware qubit 0, and so on.

This method is most useful for hardware-characterization experiments, where the incoming “abstract” circuit is already full-width on the device, its operations correspond to physical operations, and the transpiler is just being invoked to formalize the creation of a physical [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit").

#### Built-in `sabre` plugin

Uses the [`SabreLayout`](/docs/api/qiskit/qiskit.transpiler.passes.SabreLayout "qiskit.transpiler.passes.SabreLayout") to choose an initial layout, using Qiskit’s modified [Sabre routing algorithm](#transpiler-preset-stage-routing-sabre) as the subroutine to swap-map the candidate circuit both forwards and backwards.

Summarily, the layout component of [the original Sabre algorithm](https://arxiv.org/abs/1809.02573) chooses an initial layout arbitrarily, then tries to “improve” it by running routing on the circuit, reversing the circuit, and running routing on the reversed circuit with the previous “final” virtual-to-hardware assignment as the initial state. The configured optimization level decides how many iterations of this to-and-fro to do, and how many different random initial layouts to try.

The principal difference to the [default stage](#transpiler-preset-stage-layout-default) at optimization levels other than 0 is that this plugin *only* runs the Sabre-based algorithm. It does not attempt to find a perfect layout, nor attempt the trivial layout.

### Routing stage

> **See also**
>
> **[Routing stage explanation](/docs/guides/transpiler-stages#routing-stage)**
>
> Higher-level user-facing explanation of the routing stage in the IBM Quantum guide.

The routing stage ensures that the virtual connectivity graph of the circuit is compatible with the hardware connectivity graph of the target. In simpler terms, the routing stage makes sure that all two-qubit gates in the circuit are mapped to hardware qubits that have a defined two-qubit operation in the target ISA. You may also see this problem referred to as the “mapping” or “swap-mapping” problem in other toolkits or literature.

Routing algorithms typically do this by inserting `swap` gates into the circuit, and modifying the virtual-to-hardware mapping of qubits over the course of the circuit execution.

The routing stage does not need to ensure that all the gates in the circuit are valid for the target ISA. For example, a routing plugin can leave literal `swap` gates in the circuit, even if the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") does not contain [`SwapGate`](/docs/api/qiskit/qiskit.circuit.library.SwapGate "qiskit.circuit.library.SwapGate"). However, there must be at least one two-qubit gate defined in the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") for any pair of hardware qubits that has a gate applied in the circuit.

The routing stage must set the `final_layout` and `virtual_permutation_layout` properties in the [`PropertySet`](/docs/api/qiskit/qiskit.passmanager.PropertySet "qiskit.passmanager.PropertySet") if routing has taken place.

All of Qiskit’s built-in routing stages will additionally run the [`VF2PostLayout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2PostLayout "qiskit.transpiler.passes.VF2PostLayout") pass after routing. This might reassign the initial layout, if lower-error qubits can be found. This pass is very similar to the [`VF2Layout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2Layout "qiskit.transpiler.passes.VF2Layout") class that [the default layout plugin](#transpiler-preset-stage-layout-default) uses, except in [`VF2PostLayout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2PostLayout "qiskit.transpiler.passes.VF2PostLayout") we can guarantee that there is at least one isomorphic induced subgraph of the target topology that matches the circuit topology.

> **Note**
>
> Qiskit’s built-in routing plugins all generally assume that all pairs of qubits with a defined two-qubit link have a *universal* set of gates defined for those two qubits. Hardware does not necessarily need to respect this (for example, if the only defined two-qubit gate is `swap`, then entangling operations like `cx` cannot be realized), but Qiskit does not yet consider this possibility.

> **Note**
>
> Finding the minimal number of swaps to insert is known to be a non-polynomial problem. This means it is prohibitively expensive to attempt, so many of Qiskit’s built-in algorithms are stochastic, and you may see large variations between different compilations. If you need reproducibility, be sure to set the `seed_transpiler` argument of [`generate_preset_pass_manager()`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager") or [`transpile()`](/docs/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile").

When writing [stage plugins](/docs/api/qiskit/transpiler_plugins#transpiler-preset-stage-plugins), the entry point for `routing` is `qiskit.transpiler.routing`. The built-in plugins are:

| Method                                                  | Summary                                                                                                  |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [default](#transpiler-preset-stage-routing-default)     | Use a Qiskit-chosen default routing method.                                                              |
| [sabre](#transpiler-preset-stage-routing-sabre)         | Default. Uses [Qiskit’s modified Sabre routing algorithm](https://arxiv.org/abs/2409.08368) to swap map. |
| [none](#transpiler-preset-stage-routing-none)           | Disable routing. Raises an error if routing is required.                                                 |
| [basic](#transpiler-preset-stage-routing-basic)         | Greedy swap insertion to route a single operation at a time.                                             |
| [lookahead](#transpiler-preset-stage-routing-lookahead) | Breadth-first search with heuristic pruning to find swaps that make gates executable.                    |

#### Built-in `default` plugin

Use a Qiskit-chosen default method for routing. As of Qiskit 2.0, the chosen algorithm is the same as [Built-in sabre plugin](#transpiler-preset-stage-routing-sabre), though in practice, usually the [built-in default layout-stage plugin](#transpiler-preset-stage-layout-default) will run the Sabre-based routing algorithm, and the routing stage will only be used to run [`VF2PostLayout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2PostLayout "qiskit.transpiler.passes.VF2PostLayout").

#### Built-in `none` plugin

A dummy plugin used to disable routing entirely. This can occasionally be useful for hardware-configuration experiments, or in certain special cases of partial compilation.

#### Built-in `basic` plugin

Uses the `BasisSwap` greedy swap-insertion algorithm. This is conceptually very simple; for each operation in topological order, insert the shortest-path swaps needed to make the connection executable on the device.

The optimization level only affects the amount of work the [`VF2PostLayout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2PostLayout "qiskit.transpiler.passes.VF2PostLayout") step does to attempt to improve the initial layout after routing.

This method typically has poor output quality.

#### Built-in `lookahead` plugin

Uses the [`LookaheadSwap`](/docs/api/qiskit/qiskit.transpiler.passes.LookaheadSwap "qiskit.transpiler.passes.LookaheadSwap") algorithm to route. This is essentially a breadth-first search at producing a swap network, where the tree being explored is pruned down to a small number of candidate swaps at each depth.

This algorithm is similar to the `basic` heuristic of [the “sabre” plugin](#transpiler-preset-stage-routing-sabre), except it considers the following effects of each swap to a small depth as well.

The optimization level affects the search depth, the amount of per-depth pruning, and amount of work done by [`VF2PostLayout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2PostLayout "qiskit.transpiler.passes.VF2PostLayout") to post-optimize the initial layout.

In practice, [the “sabre” plugin](#transpiler-preset-stage-routing-sabre) runs several orders of magnitude faster, and produces better output.

#### Built-in `sabre` plugin

Uses the [`SabreSwap`](/docs/api/qiskit/qiskit.transpiler.passes.SabreSwap "qiskit.transpiler.passes.SabreSwap") algorithm to route. This uses [Qiskit’s enhanced version](https://arxiv.org/abs/2409.08368) of [the original Sabre routing algorithm](https://arxiv.org/abs/1809.02573).

This routing algorithm runs with threaded parallelism to consider several different possibilities for routing, choosing the one that minimizes the number of inserted swaps.

The optimization level affects how many different stochastic seeds are attempted for the full routing, and the amount of work done by [`VF2PostLayout`](/docs/api/qiskit/qiskit.transpiler.passes.VF2PostLayout "qiskit.transpiler.passes.VF2PostLayout") to post-optimize the initial layout.

This is almost invariably the best-performing built-in plugin, and the one Qiskit uses by default in all cases where routing is necessary.

### Translation stage

> **See also**
>
> **[Translation stage explanation](/docs/guides/transpiler-stages#translation-stage)**
>
> Higher-level user-facing explanation of the translation stage in the IBM Quantum guide.

The translation stage is responsible for rewriting all gates in the circuit into ones that are supported by the target ISA. For example, if a `cx` is requested on hardware qubits 0 and 1, but the ISA only contains a `cz` operation on those qubits, the translation stage must find a way of representing the `cx` gate using the `cz` and available one-qubit gates.

The translation stage is called before entering the optimization stage. Optimization plugins (including Qiskit’s built-in plugins) may also use the translation stage as a “fixup” stage after the optimization loop, if the optimization loop returns a circuit that includes non-ISA gates. This latter situation is fairly common; the optimization loop may only be concerned with minimizing properties like “number of two-qubit gates”, and will leave its output in terms of locally equivalent gates, which the translation stage can easily rewrite without affecting the target optimization properties. This allows easier separation of concerns between the two stages. Some optimization plugins may be stricter in their output, and so this follow-up to the translation stage may no longer be necessary.

When writing [stage plugins](/docs/api/qiskit/transpiler_plugins#transpiler-preset-stage-plugins), the entry point for `translation` is `qiskit.transpiler.translation`. The built-in plugins are:

| Method                                                        | Summary                                                                                                 |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| [default](#transpiler-preset-stage-translation-translator)    | Use a Qiskit-chosen default translation method.                                                         |
| [translator](#transpiler-preset-stage-translation-translator) | Symbolic translation of gates to the target basis using known equivalences.                             |
| [synthesis](#transpiler-preset-stage-translation-synthesis)   | Collect each run of one- and two-qubit gates into a matrix representation, and resynthesize from there. |

#### Built-in `default` plugin

Use a Qiskit-chosen default method for translation. As of Qiskit 2.0, this is the same as [Built-in translator plugin](#transpiler-preset-stage-translation-translator), but the chosen algorithm might change during the 2.x series, either for all targets, or only for certain classes of target.

#### Built-in `synthesis` plugin

Collect runs of gates on the same qubits into matrix form, and then resynthesize using the [`UnitarySynthesis`](/docs/api/qiskit/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") pass (with the configured `unitary_synthesis_method`). This is, in large part, similar to the optimization loop itself at high optimization levels.

The collection into matrices is typically more expensive than matrix-free translations, but in principle the quality of the translations can be better. In practice, this requires a synthesis algorithm tailored to the target ISA, which makes this method less general than other methods. It can produce higher-quality results when targeting simple ISAs that match the synthesis routines already in Qiskit.

If this method is used, you might not need the optimization loop.

The optimization level has no effect on this plugin.

#### Built-in `translator` plugin

Uses the [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator "qiskit.transpiler.passes.BasisTranslator") algorithm to symbolically translate gates into the target basis. At a high level, this starts from the set of gates requested by the circuit, and uses rules from a given [`EquivalenceLibrary`](/docs/api/qiskit/qiskit.circuit.EquivalenceLibrary "qiskit.circuit.EquivalenceLibrary") (typically the [`SessionEquivalenceLibrary`](/docs/api/qiskit/circuit#qiskit.circuit.SessionEquivalenceLibrary "qiskit.circuit.SessionEquivalenceLibrary")) to move towards the ISA.

This is the default translation method.

The optimization level has no effect on this plugin.

### Optimization stage

> **See also**
>
> **[Optimization stage explanation](/docs/guides/transpiler-stages#optimization-stage)**
>
> Higher-level user-facing explanation of the optimization stage in the IBM Quantum guide.

The optimization stage is for low-level hardware-aware optimizations. Unlike [the init stage](#transpiler-preset-stage-init), the input to this stage is a circuit that is already ISA-compatible, so a low-level optimization plugin can be tailored for a particular ISA.

There are very few requirements on an optimization plugin, other than it takes in ISA-supported circuits, and returns ISA-supported circuits. An optimization plugin will often contain a loop, such as the [`DoWhileController`](/docs/api/qiskit/qiskit.passmanager.DoWhileController "qiskit.passmanager.DoWhileController"), and might include the configured translation stage as a fix-up pipeline.

Qiskit’s built-in optimization plugins are general, and apply well to most real-world ISAs for non-error-corrected devices. The built-in plugins are less well-suited to ISAs that have no continuously parametrized single-qubit gate.

When writing [stage plugins](/docs/api/qiskit/transpiler_plugins#transpiler-preset-stage-plugins), the entry point for `optimization` is `qiskit.transpiler.optimization`. The built-in plugins are:

| Method                                                   | Summary                                                                                      |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| [default](#transpiler-preset-stage-optimization-default) | A default set of optimization passes. This varies significantly between optimization levels. |

#### Built-in `default` plugin

This varies significantly depending on the optimization level.

The specifics of this pipeline are subject to change between Qiskit versions. The broad principles are described below.

At optimization level 0, the stage is empty.

At optimization level 1, the stage does matrix-based resynthesis of runs of single-qubit gates, and very simple symbolic inverse cancellation of two-qubit gates, if they appear consecutively. This runs in a loop until the size and depth of the circuit are fixed.

At optimization level 2, in addition the optimizations of level 1, the loop contains commutation analysis of sets of gates to widen the range of gates that can be considered for cancellation. Before the loop, runs of both one- and two-qubit gates undergo a single matrix-based resynthesis.

At optimization level 3, the two-qubit matrix-based resynthesis runs inside the optimization loop. The optimization loop condition also tries multiple runs and chooses the minimum point in the case of fluctuating output; this is necessary because matrix-based resynthesis is relatively unstable in terms of concrete gates.

Optimization level 3 is typically very expensive for large circuits.

### Scheduling stage

> **See also**
>
> **[Scheduling of circuits](#transpiler-scheduling-description)**
>
> A guide-level explanation of scheduling concepts.

The scheduling stage, if requested, is responsible for inserting explicit [`Delay`](/docs/api/qiskit/circuit#qiskit.circuit.Delay "qiskit.circuit.Delay") instructions to make idle periods of qubits explicit. Plugins may optionally choose to do walltime-sensitive transformations, such as inserting dynamical decoupling sequences.

The input to the scheduling stage is an ISA-compatible circuit. The output of the scheduling stage must also be an ISA-compatible circuit, with explicit [`Delay`](/docs/api/qiskit/circuit#qiskit.circuit.Delay "qiskit.circuit.Delay") instructions that satisfy the hardware’s timing information, if appropriate.

The scheduling stage should set the `node_start_time` property in the pipeline’s [`PropertySet`](/docs/api/qiskit/qiskit.passmanager.PropertySet "qiskit.passmanager.PropertySet").

When writing [stage plugins](/docs/api/qiskit/transpiler_plugins#transpiler-preset-stage-plugins), the entry point for `scheduling` is `qiskit.transpiler.scheduling`. The built-in plugins are:

| Method                                                 | Summary                                                                       |
| ------------------------------------------------------ | ----------------------------------------------------------------------------- |
| [default](#transpiler-preset-stage-scheduling-default) | Attempt to satisfy timing alignment constraints without otherwise scheduling. |
| [alap](#transpiler-preset-stage-scheduling-alap)       | Schedule the circuit, preferring operations to be as late as possible.        |
| [asap](#transpiler-preset-stage-scheduling-asap)       | Schedule the circuit, preferring operations to be as soon as possible.        |

#### Built-in `default` plugin

Do nothing, unless the circuit already contains instructions with explicit timings. If there are explicitly timed operations in the circuit, insert additional padding to ensure that these timings satisfy the alignment and other hardware constraints.

#### Builtin `alap` plugin

Explicitly schedule all operations using an “as late as possible” strategy. This uses the [`ALAPScheduleAnalysis`](/docs/api/qiskit/qiskit.transpiler.passes.ALAPScheduleAnalysis "qiskit.transpiler.passes.ALAPScheduleAnalysis") algorithm to decide where to place gates.

#### Builtin `asap` plugin

Explicitly schedule all operations using an “as soon as possible” strategy. This uses the [`ASAPScheduleAnalysis`](/docs/api/qiskit/qiskit.transpiler.passes.ASAPScheduleAnalysis "qiskit.transpiler.passes.ASAPScheduleAnalysis") algorithm to decide where to place gates.

## Custom pass managers

In addition to modifying preset pass managers, it is also possible to construct a pass manager to build an entirely custom pipeline for transforming input circuits. You can use the [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager") class directly to do this. You can define arbitrary stage names and populate them with a [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") instance. For example, the following code creates a new [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager") that has two stages, `init` and `translation`.

```python
from qiskit.transpiler.passes import (
    UnitarySynthesis,
    Collect2qBlocks,
    ConsolidateBlocks,
    UnitarySynthesis,
    Unroll3qOrMore,
)
from qiskit.transpiler import PassManager, StagedPassManager

basis_gates = ["rx", "ry", "rxx"]
init = PassManager([UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()])
translate = PassManager(
    [
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=basis_gates),
        UnitarySynthesis(basis_gates),
    ]
)

staged_pm = StagedPassManager(
    stages=["init", "translation"], init=init, translation=translate
)
```

There is no limit on the number of stages you can put in a [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager"). The stages do not need to correspond to the stages used by Qiskit’s preset pipelines.

The [Stage generator functions](/docs/api/qiskit/transpiler_preset#stage-generators) may be useful for the construction of custom [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager") instances. They generate pass managers which provide common functionality used in many stages. For example, [`generate_embed_passmanager()`](/docs/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_embed_passmanager "qiskit.transpiler.preset_passmanagers.generate_embed_passmanager") generates a [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") to “embed” a selected initial [`Layout`](/docs/api/qiskit/qiskit.transpiler.Layout "qiskit.transpiler.Layout") from a layout pass to the specified target device.

## Writing custom transpiler passes

Qiskit is designed to be extended with custom, specialized transpiler passes.

There are two types of transpiler pass: “analysis” passes ([`AnalysisPass`](/docs/api/qiskit/qiskit.transpiler.AnalysisPass "qiskit.transpiler.AnalysisPass")), which read a circuit and write global analysis properties into the `PropertySet`; and “transformation” passes ([`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.TransformationPass")), which either modify a [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") in place, or return a new `DAGCircuit`. Historically, Qiskit attempted to strongly separate these two types. In modern Qiskit, however, it is rather common to include both analysis and modifications into one stand-alone [`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.TransformationPass"), rather than attempt to split everything. If your pass is purely analysis-based, it is still appropriate to use [`AnalysisPass`](/docs/api/qiskit/qiskit.transpiler.AnalysisPass "qiskit.transpiler.AnalysisPass").

### General principles of pass authorship

If you want to modify or create a new [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit"), you must write a [`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.TransformationPass"). If you only want to write into the `PropertySet` and not modify the [`DAGCircuit`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit"), you should write an [`AnalysisPass`](/docs/api/qiskit/qiskit.transpiler.AnalysisPass "qiskit.transpiler.AnalysisPass"). If you want to do both, write a [`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.TransformationPass"). In both cases, the only required method is `BasePass.run()`, which is the meat of your pass. This should accept a single argument (other than `self`), `dag: DAGCircuit`. If a `TranspilerPass`, it should return a `DAGCircuit` (which can be the input, if modified in place), whereas if a [`AnalysisPass`](/docs/api/qiskit/qiskit.transpiler.AnalysisPass "qiskit.transpiler.AnalysisPass"), it should return `None`.

If your pass has an initializer, you must call `super().__init__()`.

Typically, your pass should accept a [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") in its initializer, which describes the quantum hardware you are compiling for. Accepting “loose” constraints like a separate coupling map and list of basis gates is discouraged; the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") is more correctly descriptive of general heterogeneous hardware.

During execution of a [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") pipeline, when the `run()` method of your pass is called, you can access the attribute `self.property_set` to get the current `PropertySet` state of the transpilation. You should read from and write to this in place. Your pass should clearly document what, if any, attributes in the property set that it reads from and writes to.

### Randomness and determinism

Quantum compilation often involves solving problems that are intractable to globally optimize. In these cases, stochastic and heuristic algorithms are often more appropriate. This leads to problems of reproducibility, however.

There is no formal requirement for a custom pass to be deterministic under [the precise same set of rules](#transpiler-preset-determinism) that built-in Qiskit passes must follow. However, we **strongly** encourage you to follow these rules in your own passes; science thrives on reproducibility, and debugging is a nightmare when you can’t reproduce previously observed behavior.

When writing a transpiler pass, you can rely on the following (representative, and non-exhaustive) examples being deterministic, even though the exact semantics of the ordering may not be fully specified, and passes should **not** rely on any particular order:

- The order nodes are encountered in [`DAGCircuit.op_nodes()`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit#op_nodes "qiskit.dagcircuit.DAGCircuit.op_nodes"). By contrast, [`topological_op_nodes()`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit#topological_op_nodes "qiskit.dagcircuit.DAGCircuit.topological_op_nodes") by default includes an ordering key that makes its order entirely unaffected by the order of node removal/insertion, so is fully deterministic provided the same set of nodes with the same data-flow is specified, even if it was built up in a different order.
- The order edges are encountered in [`DAGCircuit.edges()`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit#edges "qiskit.dagcircuit.DAGCircuit.edges").
- The order that runs are returned from [`DAGCircuit.collect_2q_runs()`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit#collect_2q_runs "qiskit.dagcircuit.DAGCircuit.collect_2q_runs"), and the exact order nodes in a run are encountered.
- The order that nodes are encountered in order-degenerate methods such as [`predecessors()`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit#predecessors "qiskit.dagcircuit.DAGCircuit.predecessors"), [`bfs_successors()`](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit#bfs_successors "qiskit.dagcircuit.DAGCircuit.bfs_successors"), and so on.

In general, the requirement is that **all the same circuit modifications are made, in exactly the same order**. For example, if nodes are to be added, contracted, or removed, the order of these modifications must be done in a deterministic order, and the replacements must be specified deterministically.

Some tips for ensuring this include:

- Be very careful when iterating over hash-based containers. Iteration over Python’s [`set`](https://docs.python.org/3/library/stdtypes.html#set) is non-deterministic due to hash-seed randomization. In Rust, iteration over the standard-library hash-based containers, including `hashbrown` equivalents with their default hashers is non-deterministic.

  > **Note**
  >
  > Iteration over Python’s [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) *is* deterministic, and guaranteed to be in insertion order if there have been no removals, and arbitrary but still deterministic order if there have been deterministic removals.

  In Python, if you need to create a [`set`](https://docs.python.org/3/library/stdtypes.html#set) and then iterate over it, consider instead using a [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) with all the values being `None` as a substitute. Using a [`set`](https://docs.python.org/3/library/stdtypes.html#set) purely for membership testing is no trouble.

  In Rust, use `indexmap` and its structs `IndexMap` and `IndexSet` as replacements for `HashMap` and `HashSet`, respectively; they have similar deterministic-iteration properties to Python’s [`dict`](https://docs.python.org/3/library/stdtypes.html#dict).

- If your pass has stochastic components, ensure that you accept a `seed` input, and make your output pure if this is supplied as an integer. Typically this means storing the seed, and instantiating a new pRNG from this seed at the start of each call to `BasePass.run()`.

- If using threaded parallelism, take care that your output is not dependent on the order that threads do their work or return their partial results. For example, if distributing work across a thread pool and collecting the results at the end, ensure that the output is arranged in a corresponding order to the input. In Python, functions like `concurrent.futures.ThreadPoolExecutor.map()` ensure this. Similarly, in Rust, `rayon`’s parallel iterators will collect their output in the same order as the input.

  Beware that parallel \_reductions\_, such as “apply a function to each item in this iterator, and choose the one that minimizes some metric”, are typically highly susceptible to threaded non-determinism, in the case of degeneracies in the metric. For example, if two items in the iterator produce non-equal output that nevertheless has the same comparison key, the one chosen in a threaded environment is not deterministic. To avoid this, apply a deterministic tie-breaker to lift the degeneracy, such as by enumerating the input and using the sequence number as a tie-breaking key, such that if two items have the same score, the one corresponding to an earlier input is reliably chosen.

## Representing Quantum Computers

To be able to compile a [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") for a specific backend, the transpiler needs a specialized representation of that backend, including its constraints, instruction set, qubit properties, and more, to be able to compile and optimize effectively. While the [`BackendV2`](/docs/api/qiskit/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") class defines an interface for querying and interacting with backends, its scope is larger than just the transpiler’s needs including managing job submission and potentially interfacing with remote services. The specific information needed by the transpiler is described by the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") class

For example, to construct a simple [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") object, one can iteratively add descriptions of the instructions it supports:

```python
from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)
print(target)
```

```text
Target
Number of qubits: 3
Instructions:
    cx
        (0, 1):
            Duration: 5e-07 sec.
            Error Rate: 0.0001
    u
        (0,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (1,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    rz
        (1,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (2,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    ry
        (1,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (2,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    rx
        (1,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (2,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    cz
        (1, 2):
            Duration: 5e-07 sec.
            Error Rate: 0.0001
        (2, 0):
            Duration: 5e-07 sec.
            Error Rate: 0.0001
    measure
        (0,):
            Duration: 5e-05 sec.
            Error Rate: 0.001
        (1,):
            Duration: 6e-05 sec.
            Error Rate: 0.002
        (2,):
            Duration: 5e-07 sec.
            Error Rate: 0.2
```

This [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") represents a 3 qubit backend that supports [`CXGate`](/docs/api/qiskit/qiskit.circuit.library.CXGate "qiskit.circuit.library.CXGate") between qubits 0 and 1, [`UGate`](/docs/api/qiskit/qiskit.circuit.library.UGate "qiskit.circuit.library.UGate") on qubits 0 and 1, [`RZGate`](/docs/api/qiskit/qiskit.circuit.library.RZGate "qiskit.circuit.library.RZGate"), [`RXGate`](/docs/api/qiskit/qiskit.circuit.library.RXGate "qiskit.circuit.library.RXGate"), and [`RYGate`](/docs/api/qiskit/qiskit.circuit.library.RYGate "qiskit.circuit.library.RYGate") on qubits 1 and 2, [`CZGate`](/docs/api/qiskit/qiskit.circuit.library.CZGate "qiskit.circuit.library.CZGate") between qubits 1 and 2, and qubits 2 and 0, and [`Measure`](/docs/api/qiskit/circuit#qiskit.circuit.Measure "qiskit.circuit.Measure") on all qubits.

There are also specific data structures to represent a specific subset of information from the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target"). For example, the [`CouplingMap`](/docs/api/qiskit/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap") class is used to solely represent the connectivity constraints of a backend as a directed graph. A coupling map can be generated from a [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") using the [`Target.build_coupling_map()`](/docs/api/qiskit/qiskit.transpiler.Target#build_coupling_map "qiskit.transpiler.Target.build_coupling_map") method. These data structures typically pre-date the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") class but are still used by some transpiler passes that do not work natively with a [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") instance yet or when dealing with backends that aren’t using the latest [`BackendV2`](/docs/api/qiskit/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") interface.

For example, if we wanted to visualize the [`CouplingMap`](/docs/api/qiskit/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap") for the example 3 qubit [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") above:

```python
from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)

target.build_coupling_map().draw()
```

This shows the global connectivity of the [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") which is the combination of the supported qubits for [`CXGate`](/docs/api/qiskit/qiskit.circuit.library.CXGate "qiskit.circuit.library.CXGate") and [`CZGate`](/docs/api/qiskit/qiskit.circuit.library.CZGate "qiskit.circuit.library.CZGate"). To see the individual connectivity, you can pass the operation name to `CouplingMap.build_coupling_map()`:

```python
from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)

target.build_coupling_map('cx').draw()
```

```python
from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)

target.build_coupling_map('cz').draw()
```

## Scheduling of circuits

> **See also**
>
> **[Scheduling stage](#transpiler-preset-stage-scheduling)**
>
> How to configure the scheduling stages of the preset pass managers.

After the circuit has been translated to the target basis, mapped to the device, and optimized, a scheduling phase can be applied to optionally account for all the idle time in the circuit. At a high level, the scheduling can be thought of as inserting delays into the circuit to account for idle time on the qubits between the execution of instructions. For example, if we start with a circuit such as:

![Diagram illustrating the previously described circuit.](https://eu-de.quantum.cloud.ibm.com/docs/images/api/qiskit/transpiler-8.avif)

we can then call [`transpile()`](/docs/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") on it with `scheduling_method` set:

```python
from qiskit import QuantumCircuit, transpile
from qiskit.providers.fake_provider import GenericBackendV2

backend = GenericBackendV2(5)

ghz = QuantumCircuit(5)
ghz.h(0)
ghz.cx(0,range(1,5))

circ = transpile(ghz, backend, scheduling_method="asap")
circ.draw(output='mpl')
```

![Circuit diagram output by the previous code.](https://eu-de.quantum.cloud.ibm.com/docs/images/api/qiskit/transpiler-9.avif)

You can see here that the transpiler inserted [`Delay`](/docs/api/qiskit/circuit#qiskit.circuit.Delay "qiskit.circuit.Delay") instructions to account for idle time on each qubit. To get a better idea of the timing of the circuit we can also look at it with the `timeline.draw()` function:

![Output from circuit timeline drawer.](https://eu-de.quantum.cloud.ibm.com/docs/images/api/qiskit/transpiler-10.avif)

The scheduling of a circuit involves two parts: analysis and constraint mapping, followed by a padding pass. The first part requires running a scheduling analysis pass such as `ALAPSchedulingAnalysis` or `ASAPSchedulingAnalysis` which analyzes the circuit and records the start time of each instruction in the circuit using a scheduling algorithm (“as late as possible” for `ALAPSchedulingAnalysis` and “as soon as possible” for `ASAPSchedulingAnalysis`) in the property set. Once the circuit has an initial scheduling, additional passes can be run to account for any timing constraints on the target backend, such as alignment constraints. This is typically done with the [`ConstrainedReschedule`](/docs/api/qiskit/qiskit.transpiler.passes.ConstrainedReschedule "qiskit.transpiler.passes.ConstrainedReschedule") pass which will adjust the scheduling set in the property set to the constraints of the target backend. Once all the scheduling and adjustments/rescheduling are finished, a padding pass, such as [`PadDelay`](/docs/api/qiskit/qiskit.transpiler.passes.PadDelay "qiskit.transpiler.passes.PadDelay") or [`PadDynamicalDecoupling`](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling "qiskit.transpiler.passes.PadDynamicalDecoupling") is run to insert the instructions into the circuit, which completes the scheduling.

## Transpiler API

### Hardware description

|                                                                                                                                                   |                                                                                                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`Target`](/docs/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target")(\[description, num\_qubits, dt, ...])                            | The intent of the `Target` object is to inform Qiskit's compiler about the constraints of a particular backend so the compiler can compile an input circuit to something that works and is optimized for a device. |
| [`InstructionProperties`](/docs/api/qiskit/qiskit.transpiler.InstructionProperties "qiskit.transpiler.InstructionProperties")(\[duration, error]) | A representation of the properties of a gate implementation.                                                                                                                                                       |
| [`WrapAngleRegistry`](/docs/api/qiskit/qiskit.transpiler.WrapAngleRegistry "qiskit.transpiler.WrapAngleRegistry")()                               | Registry of Angle Wrapping function                                                                                                                                                                                |

### Pass Manager Definition

|                                                                                                                                                                                             |                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager")(\[stages])                                                                | A pass manager pipeline built from individual stages.                                                                                           |
| [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager")(\[passes, max\_iteration])                                                                  | Manager for a set of Passes and their scheduling during transpilation.                                                                          |
| [`PassManagerConfig`](/docs/api/qiskit/qiskit.transpiler.PassManagerConfig "qiskit.transpiler.PassManagerConfig")(\[initial\_layout, ...])                                                  | Pass Manager Configuration.                                                                                                                     |
| [`PassManagerCliffordTConfig`](/docs/api/qiskit/qiskit.transpiler.PassManagerCliffordTConfig "qiskit.transpiler.PassManagerCliffordTConfig")(\[initial\_layout, ...])                       | Pass Manager Configuration for Clifford+T transpilation.                                                                                        |
| [`generate_preset_pass_manager`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager "qiskit.transpiler.generate_preset_pass_manager")(\[...])                                  | Generate a preset [`PassManager`](/docs/api/qiskit/qiskit.transpiler.PassManager "qiskit.transpiler.PassManager")                               |
| [`generate_preset_clifford_t_pass_manager`](/docs/api/qiskit/qiskit.transpiler.generate_preset_clifford_t_pass_manager "qiskit.transpiler.generate_preset_clifford_t_pass_manager")(\[...]) | Generate a preset Clifford+T [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager"). |
| [`generate_preset_pbc_pass_manager`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pbc_pass_manager "qiskit.transpiler.generate_preset_pbc_pass_manager")(\[...])                      | Generate a preset PBC [`StagedPassManager`](/docs/api/qiskit/qiskit.transpiler.StagedPassManager "qiskit.transpiler.StagedPassManager").        |

### Layout and Topology

|                                                                                                                                           |                                                           |
| ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| [`Layout`](/docs/api/qiskit/qiskit.transpiler.Layout "qiskit.transpiler.Layout")(\[input\_dict])                                          | Two-ways dict to represent a Layout.                      |
| [`CouplingMap`](/docs/api/qiskit/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap")(\[couplinglist, description])             | Directed graph specifying fixed coupling.                 |
| [`TranspileLayout`](/docs/api/qiskit/qiskit.transpiler.TranspileLayout "qiskit.transpiler.TranspileLayout")(initial\_layout, ...\[, ...]) | Layout attributes for the output circuit from transpiler. |

### Scheduling

|                                                                                                                                                           |                                                                   |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [`InstructionDurations`](/docs/api/qiskit/qiskit.transpiler.InstructionDurations "qiskit.transpiler.InstructionDurations")(\[instruction\_durations, dt]) | Helper class to provide durations of instructions for scheduling. |

### Abstract Passes

|                                                                                                                                          |                                                      |
| ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.TransformationPass")(\*args, \*\*kwargs) | A transformation pass: change DAG, not property set. |
| [`AnalysisPass`](/docs/api/qiskit/qiskit.transpiler.AnalysisPass "qiskit.transpiler.AnalysisPass")(\*args, \*\*kwargs)                   | An analysis pass: change property set, not DAG.      |

### Exceptions

#### TranspilerError

*exception* `qiskit.transpiler.TranspilerError(*message)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/exceptions.py#L24-L25)

Bases: [`TranspilerAccessError`](#qiskit.transpiler.TranspilerAccessError "qiskit.transpiler.exceptions.TranspilerAccessError")

Exceptions raised during transpilation.

Set the error message.

#### TranspilerAccessError

*exception* `qiskit.transpiler.TranspilerAccessError(*message)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/exceptions.py#L20-L21)

Bases: [`PassManagerError`](/docs/api/qiskit/passmanager#qiskit.passmanager.PassManagerError "qiskit.passmanager.exceptions.PassManagerError")

DEPRECATED: Exception of access error in the transpiler passes.

Set the error message.

#### CouplingError

*exception* `qiskit.transpiler.CouplingError(*msg)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/exceptions.py#L28-L38)

Bases: [`QiskitError`](/docs/api/qiskit/exceptions#qiskit.exceptions.QiskitError "qiskit.exceptions.QiskitError")

Base class for errors raised by the coupling graph object.

Set the error message.

#### LayoutError

*exception* `qiskit.transpiler.LayoutError(*msg)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/exceptions.py#L41-L51)

Bases: [`QiskitError`](/docs/api/qiskit/exceptions#qiskit.exceptions.QiskitError "qiskit.exceptions.QiskitError")

Errors raised by the layout object.

Set the error message.

#### CircuitTooWideForTarget

*exception* `qiskit.transpiler.CircuitTooWideForTarget(*message)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/exceptions.py#L54-L55)

Bases: [`TranspilerError`](#qiskit.transpiler.TranspilerError "qiskit.transpiler.exceptions.TranspilerError")

Error raised if the circuit is too wide for the target.

Set the error message.

#### InvalidLayoutError

*exception* `qiskit.transpiler.InvalidLayoutError(*message)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/exceptions.py#L58-L59)

Bases: [`TranspilerError`](#qiskit.transpiler.TranspilerError "qiskit.transpiler.exceptions.TranspilerError")

Error raised when a user provided layout is invalid.

Set the error message.

### Optimization metric

|                                                                                                                                |                                                      |
| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- |
| [`OptimizationMetric`](/docs/api/qiskit/qiskit.transpiler.OptimizationMetric "qiskit.transpiler.OptimizationMetric")(\*values) | Optimization metric considered during transpilation. |
