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

# TwoQubitPeepholeOptimization

*class* `qiskit.transpiler.passes.TwoQubitPeepholeOptimization(*args, **kwargs)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/passes/optimization/two_qubit_peephole.py#L24-L126)

Bases: [`TransformationPass`](/docs/api/qiskit/qiskit.transpiler.TransformationPass "qiskit.transpiler.basepasses.TransformationPass")

Unified two qubit unitary peephole optimization

This transpiler pass is designed to perform two qubit unitary peephole optimization. This pass finds all the 2 qubit blocks in the circuit, computes the unitary of that block, and then synthesizes that unitary. If the synthesized two qubit unitary is “better” than the original subcircuit that subcircuit is used to replace the original. The heuristic used to determine if it’s better first looks at the two qubit gate count in the circuit, and prefers the synthesis with fewer two qubit gates, if the two qubit gate counts are the same then it looks at the estimated fidelity of the circuit and picks the subcircuit with higher estimated fidelity, and finally if needed it picks the subcircuit with the fewest total gates.

In case the target is overcomplete the pass will try all the decomposers supported for all the gates supported on a given qubit. The decomposition that has the best expected performance using the above heuristic will be selected and used to replace the block.

This pass is designed to be run on a physical circuit and the details of operations on a given qubit is assumed to be the hardware qubit from the target. However, the output of the pass might not use hardware operations, specifically single qubit gates might be emitted outside the target’s supported operations, typically only if a parameterized gate supported by the [`TwoQubitControlledUDecomposer`](/docs/api/qiskit/qiskit.synthesis.TwoQubitControlledUDecomposer "qiskit.synthesis.TwoQubitControlledUDecomposer") is used for synthesis. As such if running this pass in a physical optimization stage (such as [Optimization stage](/docs/api/qiskit/transpiler#transpiler-preset-stage-optimization)) this should be paired with passes such as [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator "qiskit.transpiler.passes.BasisTranslator") and/or [`Optimize1qGatesDecomposition`](/docs/api/qiskit/qiskit.transpiler.passes.Optimize1qGatesDecomposition "qiskit.transpiler.passes.Optimize1qGatesDecomposition") to ensure that these errant single qubit gates are replaced with hardware supported operations prior to exiting the stage.

This pass is multithreaded, and will perform the analysis in parallel and use all the cores available on your local system. You can refer to the [configuration guide](/docs/guides/configure-qiskit-local) for details on how to control the threading behavior for Qiskit more broadly which will also control this pass

This pass is similar in functionality to running [`ConsolidateBlocks`](/docs/api/qiskit/qiskit.transpiler.passes.ConsolidateBlocks "qiskit.transpiler.passes.ConsolidateBlocks") and [`UnitarySynthesis`](/docs/api/qiskit/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") sequentially in your pass manager. However, this pass offers improved runtime performance by performing the synthesis in parallel. It also has improved heuristics enabled by doing the optimization in a single step which can result in better quality output, especially in cases of overcomplete and/or heterogeneous targets. However, these heuristics and this pass as a whole are only valid for physical circuits. Additionally, unlike [`UnitarySynthesis`](/docs/api/qiskit/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") pass this does not use [Unitary Synthesis Plugins](/docs/api/qiskit/transpiler_synthesis_plugins#unitary-synth-plugin). This is a tradeoff for performance and it forgoes the pluggability exposed via that interface. Internally it currently only uses the [`TwoQubitBasisDecomposer`](/docs/api/qiskit/qiskit.synthesis.TwoQubitBasisDecomposer "qiskit.synthesis.TwoQubitBasisDecomposer") and [`TwoQubitControlledUDecomposer`](/docs/api/qiskit/qiskit.synthesis.TwoQubitControlledUDecomposer "qiskit.synthesis.TwoQubitControlledUDecomposer") for synthesizing the two qubit unitaries. You should not use this pass if you need to use the pluggable interface and the ability to use different synthesis algorithms, instead you should use a combination of [`ConsolidateBlocks`](/docs/api/qiskit/qiskit.transpiler.passes.ConsolidateBlocks "qiskit.transpiler.passes.ConsolidateBlocks") and [`UnitarySynthesis`](/docs/api/qiskit/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") to leverage the plugin mechanism in [`UnitarySynthesis`](/docs/api/qiskit/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis").

```python
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler.passes import TwoQubitPeepholeOptimization
from qiskit.providers.fake_provider import GenericBackendV2

# Build an unoptimized 2 qubit circuit
unoptimized = QuantumCircuit(2)
for i in range(10):
  if i % 2:
    unoptimized.cx(0, 1)
  else:
    unoptimized.cx(1, 0)
# Generate a target with random error rates
backend = GenericBackendV2(2, ["u", "cx"], coupling_map=[[0, 1], [1, 0]])
# Instantiate pass
peephole_pass = TwoQubitPeepholeOptimization(backend.target)
# Run pass and visualize output
optimized = peephole_pass(unoptimized)
optimized.draw("mpl")
```

![Optimized circuit](https://eu-de.quantum.cloud.ibm.com/docs/images/api/qiskit/qiskit-transpiler-passes-TwoQubitPeepholeOptimization-1.avif)

Initialize the pass

**Parameters**

- **target** – The target to run the pass for
- **approximation\_degree** – heuristic dial used for circuit approximation (1.0=no approximation, 0.0=maximal approximation). Approximation can decrease the number of gates used in the synthesized unitaries smaller at the cost of straying from the original unitary. If `None`, approximation is done based on gate fidelities specified in the `target`.

## Attributes

### is\_analysis\_pass

Check if the pass is an analysis pass.

If the pass is an AnalysisPass, that means that the pass can analyze the DAG and write the results of that analysis in the property set. Modifications on the DAG are not allowed by this kind of pass.

### is\_transformation\_pass

Check if the pass is a transformation pass.

If the pass is a TransformationPass, that means that the pass can manipulate the DAG, but cannot modify the property set (but it can be read).

## Methods

### execute

`execute(passmanager_ir, state, callback=None)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/basepasses.py#L162-L181)

Execute optimization task for input Qiskit IR.

**Parameters**

- **passmanager\_ir** ([*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit._accelerate.circuit.DAGCircuit")) – Qiskit IR to optimize.
- **state** ([*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit._accelerate.circuit.DAGCircuit")) – State associated with workflow execution by the pass manager itself.
- **callback** ([*Callable*](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)*\[\[*[*Task*](/docs/api/qiskit/qiskit.passmanager.Task "qiskit.passmanager.base_tasks.Task")*,* [*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit._accelerate.circuit.DAGCircuit")*,* [*PropertySet*](/docs/api/qiskit/qiskit.passmanager.PropertySet "qiskit.passmanager.compilation_status.PropertySet")*,* [*float*](https://docs.python.org/3/library/functions.html#float)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*], None] | None*) – A callback function which is called per execution of optimization task.

**Returns**

Optimized Qiskit IR and state of the workflow.

**Return type**

[tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit._accelerate.circuit.DAGCircuit"), [*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState "qiskit.passmanager.compilation_status.PassManagerState")]

### name

`name()`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/passmanager/base_tasks.py#L72-L74)

Name of the pass.

**Return type**

[str](https://docs.python.org/3/library/stdtypes.html#str)

### run

`run(dag)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/passes/optimization/two_qubit_peephole.py#L121-L126)

Run a pass on the DAGCircuit. This is implemented by the pass developer.

**Parameters**

**dag** ([*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit._accelerate.circuit.DAGCircuit")) – the dag on which the pass is run.

**Raises**

[**NotImplementedError**](https://docs.python.org/3/library/exceptions.html#NotImplementedError) – when this is left unimplemented for a pass.

**Return type**

[*DAGCircuit*](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit._accelerate.circuit.DAGCircuit")

### update\_status

`update_status(state, run_state)`

[GitHub](https://github.com/Qiskit/qiskit/tree/stable/2.5/qiskit/transpiler/basepasses.py#L183-L191)

Update workflow status.

**Parameters**

- **state** ([*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState "qiskit.passmanager.compilation_status.PassManagerState")) – Pass manager state to update.
- **run\_state** (*RunState*) – Completion status of current task.

**Returns**

Updated pass manager state.

**Return type**

[*PassManagerState*](/docs/api/qiskit/qiskit.passmanager.PassManagerState "qiskit.passmanager.compilation_status.PassManagerState")
