---
title: Represent quantum computers for the transpiler
description: Learn about coupling maps, basis gates, and processor errors for transpiling
source: https://eu-de.quantum.cloud.ibm.com/docs/en/guides/represent-quantum-computers
---

# Represent quantum computers for the transpiler

### Package versions

The code on this page was developed using the following requirements.
We recommend using these versions or newer.

```
qiskit[all]~=2.5.1
qiskit-ibm-runtime~=0.47.0
```

To convert an abstract circuit to an ISA circuit that can run on a specific QPU (quantum processing unit), the transpiler needs certain information about the QPU. This information is found in two places: the `BackendV2` (or legacy `BackendV1`) object you plan to submit jobs to, and the backend's `Target` attribute.

- The [`Target`](/docs/api/qiskit/qiskit.transpiler.Target) contains all the relevant constraints of a device, such as its supported instruction set, qubit connectivity, and pulse or timing information.
- The [`Backend`](/docs/api/qiskit/qiskit.providers.BackendV2) possesses a `Target` by default, contains additional information -- such as the [`InstructionScheduleMap`](/docs/api/qiskit/1.4/qiskit.pulse.InstructionScheduleMap), and provides the interface for submitting quantum circuit jobs.

You can also explicitly provide information for the transpiler to use, for example, if you have a specific use case, or if you believe this information will help the transpiler generate a more optimized circuit.

The precision with which the transpiler produces the most appropriate circuit for specific hardware depends on how much information the `Target` or `Backend` has about its constraints.

> **Note**
>
> Because many of the underlying transpilation algorithms are stochastic, there is no guarantee that a better circuit will be found.

This page shows several examples of passing QPU information to the transpiler.

## Default configuration

The simplest use of the transpiler is to provide all the QPU information by providing the `Backend` or `Target`. To better understand how the transpiler works, construct a circuit and transpile it with different information, as follows.

Import the necessary libraries and instantiate the QPU:
In order to convert an abstract circuit to an ISA circuit that can run on a specific processor, the transpiler needs certain information about the processor.  Typically, this information is stored in the [`Backend`](/docs/api/qiskit/qiskit.providers.Backend#backend) or [`Target`](/docs/api/qiskit/qiskit.transpiler.Target#target) provided to the transpiler, and no further information is needed. However, you can also explicitly provide information for the transpiler to use, for example, if you have a specific use case, or if you believe this information will help the transpiler generate a more optimized circuit.

This topic shows several examples of passing information to the transpiler.

> **Note**
>
> These examples use the target from the `qiskit_ibm_runtime` [`FakeSherbrooke`](/docs/api/qiskit-ibm-runtime/fake-provider-fake-sherbrooke#fakesherbrooke) mock backend.  However, you can try it on any Qiskit-compatible real or fake backend.  Your results might be different.

```python
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()
target = backend.target
```

The example circuit uses an instance of [`efficient_su2`](/docs/api/qiskit/qiskit.circuit.library.efficient_su2) from Qiskit's circuit library.

```python
from qiskit.circuit.library import efficient_su2

qc = efficient_su2(12, entanglement="circular", reps=1)

qc.draw("mpl")
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/97f9acc1-ac53-4025-b413-485777932a9b-0.svg)

This example uses default settings to transpile to the `backend`'s `target`, which provides all the information needed to convert the circuit to one that will run on the backend.

```python
from qiskit.transpiler import generate_preset_pass_manager

pass_manager = generate_preset_pass_manager(
    optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/4b81fb9d-d199-45c5-b119-c1f0b973afe9-0.svg)

This example is used in later sections of this topic to illustrate that the coupling map and supported instruction set are the essential pieces of information to pass to the transpiler for optimal circuit construction. The QPU can usually select default settings for other information that is not passed in, such as timing and scheduling.

## Coupling map

The coupling map is a graph that shows which qubits are connected and hence have two-qubit gates between them. Sometimes this graph is directional, meaning that the two-qubit gates can only go in one direction. However, the transpiler can always flip a gate's direction by adding additional single-qubit gates. An abstract quantum circuit can always be represented on this graph, even if its connectivity is limited, by introducing SWAP gates to move the quantum information around.

The qubits from our abstract circuits are called *virtual qubits* and those on the coupling map are *physical qubits*. The transpiler provides a mapping between virtual and physical qubits. One of the first steps in transpilation, the *layout* stage, performs this mapping.

> **Note**
>
> Although the routing stage is intertwined with the *layout* stage — which selects the actual qubits — by default, this topic treats them as separate stages for simplicity. The combination of routing and layout is called *qubit mapping*.  Learn more about these stages in the [Transpiler stages](/docs/guides/transpiler-stages) topic.

Pass the `coupling_map` keyword argument to see its effect on the transpiler:

```python
coupling_map = target.build_coupling_map()

pass_manager = generate_preset_pass_manager(
    optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/ec354bee-e06b-42ea-a117-6c1a9308ca73-0.svg)

As shown above, several SWAP gates were inserted (each consisting of three CX gates), which will cause a lot of errors on current devices. To see which qubits are selected on the actual qubit topology, use `plot_circuit_layout` from Qiskit Visualizations:

```python
from qiskit.visualization import plot_circuit_layout

plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/9be74535-ed36-4d51-afeb-ee53c3f8a046-0.svg)

This shows that our virtual qubits 0-11 were trivially mapped to the line of physical qubits 0-11. Let's return to the default (`optimization_level=1`), which uses `VF2Layout` if any routing is required.

```python
pass_manager = generate_preset_pass_manager(
    optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/8035fd05-f7cd-4151-b19a-4968202246e6-0.svg)

Now there are no SWAP gates inserted and the physical qubits selected are the same when using the `target` class.

```python
from qiskit.visualization import plot_circuit_layout

plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/25d9fac3-abda-4b2d-81b4-351dc0772722-0.svg)

Now the layout is in a ring.  Because this layout respects the circuit's connectivity, there are no SWAP gates, providing a much better circuit for execution.

## Supported instructions

Every quantum computer supports a limited instruction set.  Every gate in the circuit must be translated to the elements of this set. This set should consist of single- and two-qubit gates that provide a universal gate set, meaning that any quantum operation can be decomposed into those gates.  This is done by the [BasisTranslator](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator), and `basis_gates` can be specified as a keyword argument to the transpiler to provide this information.

```python
basis_gates = list(target.operation_names)
print(basis_gates)
```

Output:

```
['sx', 'switch_case', 'if_else', 'rz', 'for_loop', 'ecr', 'id', 'reset', 'measure', 'x', 'delay']
```

The default single-qubit gates on `FakeSherbrooke` are `rz`, `x`, and `sx`, and the default two-qubit gate is `ecr` (echoed cross-resonance). CX gates are constructed from `ecr` gates, so on some QPUs `ecr` is specified as the two-qubit basis gate, while on others `cx` is the default. The `ecr` gate is the *entangling* part of the `cx` gate. In addition to the control gates, there are also `delay` and `measurement` instructions.

> **Note**
>
> QPUs have default basis gates, but you can choose whatever gates you want, as long as you provide the instruction or add pulse gates (see [Create transpiler passes](/docs/guides/custom-transpiler-pass).) The default basis gates are those that calibrations have been done for on the QPU, so no further instruction/pulse gates need to be provided. For example, on some QPUs `cx` is the default two-qubit gate and `ecr` on others. See the list of possible [native gates and operations](/docs/guides/qpu-information#native-gates) for more details.

```python
pass_manager = generate_preset_pass_manager(
    optimization_level=1,
    coupling_map=coupling_map,
    basis_gates=basis_gates,
    seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/313e4743-0.svg)

Note that the `CXGate` objects have been decomposed to `ecr` gates and single-qubit basis gates.

## Device error rates

The `Target` class can contain information about the error rates for operations on the device.
For example, the following code retrieves the properties for the echoed cross-resonance (ECR) gate between qubit 1 and 0 (note that the ECR gate is directional):

```python
target["ecr"][(1, 0)]
```

Output:

```
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)
```

The output displays the duration of the gate (in seconds) and its error rate. To reveal error information to the transpiler, build a target model with the `basis_gates` and `coupling_map` from above and populate it with error values from the backend `FakeSherbrooke`.

```python
from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp

err_targ = Target.from_configuration(
    basis_gates=basis_gates,
    coupling_map=coupling_map,
    num_qubits=target.num_qubits,
    custom_name_mapping={
        "if_else": IfElseOp,
        "switch_case": SwitchCaseOp,
        "for_loop": ForLoopOp,
    },
)

for i, (op, qargs) in enumerate(target.instructions):
    if op.name in basis_gates:
        err_targ[op.name][qargs] = target.instruction_properties(i)
```

Transpile with our new target `err_targ` as the target:

```python
pass_manager = generate_preset_pass_manager(
    optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)
```

Output:

![Output of the previous code cell](https://eu-de.quantum.cloud.ibm.com/docs/images/guides/represent-quantum-computers/extracted-outputs/f1e270c4-e2cc-487e-a050-4180bc321b0b-0.svg)

Because the target includes error information, the `VF2PostLayout` pass tries to find the optimal qubits to use, resulting in the same circuit that was originally found with the same physical qubits.

## Next steps

> **Recommendations**
>
> - Understand [Transpilation default settings and configuration options](/docs/guides/defaults-and-configuration-options).
> - Review the [Commonly used parameters for transpilation](/docs/guides/common-parameters) topic.
> - Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) guide.
> - See the [Transpile API documentation](/docs/api/qiskit/transpiler).
