0
# Circuit Transpilation
1
2
Qiskit's transpilation system optimizes and maps quantum circuits for execution on specific quantum hardware backends. It provides comprehensive pass management, hardware-aware optimization, and automatic circuit compilation pipelines.
3
4
## Capabilities
5
6
### Main Transpilation Interface
7
8
The primary transpilation function provides a high-level interface for circuit optimization and backend mapping.
9
10
```python { .api }
11
def transpile(circuits, backend=None, basis_gates=None, inst_map=None,
12
coupling_map=None, backend_properties=None, initial_layout=None,
13
layout_method=None, routing_method=None, translation_method=None,
14
scheduling_method=None, instruction_durations=None, dt=None,
15
approximation_degree=None, timing_constraints=None, seed_transpiler=None,
16
optimization_level=None, callback=None, output_name=None,
17
unroll_3q=None, target=None, hls_config=None, init_method=None,
18
optimization_method=None):
19
"""
20
Transpile quantum circuits for a backend.
21
22
Parameters:
23
- circuits: Circuit or list of circuits to transpile
24
- backend: Target backend (provides coupling_map, basis_gates, etc.)
25
- basis_gates: Allowed gate set for target backend
26
- coupling_map: Coupling constraints between qubits
27
- backend_properties: Backend calibration data
28
- initial_layout: Initial qubit mapping
29
- layout_method: Qubit layout algorithm ('trivial', 'dense', 'noise_adaptive', 'sabre')
30
- routing_method: Routing algorithm ('basic', 'lookahead', 'stochastic', 'sabre')
31
- translation_method: Basis translation method ('translator', 'synthesis', 'unroller')
32
- scheduling_method: Instruction scheduling method ('alap', 'asap')
33
- optimization_level: Optimization level (0-3)
34
- seed_transpiler: Random seed for reproducible transpilation
35
- target: Backend target specification (alternative to backend)
36
37
Returns:
38
QuantumCircuit or List[QuantumCircuit]: Transpiled circuit(s)
39
"""
40
41
def generate_preset_pass_manager(optimization_level, backend=None, target=None,
42
basis_gates=None, inst_map=None, coupling_map=None,
43
instruction_durations=None, backend_properties=None,
44
timing_constraints=None, initial_layout=None,
45
layout_method=None, routing_method=None,
46
translation_method=None, scheduling_method=None,
47
approximation_degree=None, seed_transpiler=None,
48
unroll_3q=None, hls_config=None, init_method=None,
49
optimization_method=None):
50
"""
51
Generate preset pass manager for given optimization level.
52
53
Parameters:
54
- optimization_level: Optimization level (0-3)
55
- backend: Target backend
56
- target: Backend target specification
57
- Other parameters: Same as transpile()
58
59
Returns:
60
PassManager: Configured pass manager
61
"""
62
```
63
64
### Pass Manager Framework
65
66
The pass manager system orchestrates transpilation passes for flexible circuit optimization workflows.
67
68
```python { .api }
69
class PassManager:
70
def __init__(self, passes=None, max_iteration=1000):
71
"""
72
Initialize pass manager.
73
74
Parameters:
75
- passes: Initial passes to add
76
- max_iteration: Maximum iterations for iterative passes
77
"""
78
79
def append(self, passes, **kwargs):
80
"""
81
Add passes to the pass manager.
82
83
Parameters:
84
- passes: Pass or list of passes to add
85
- **kwargs: Pass execution conditions
86
"""
87
88
def replace(self, index, passes, **kwargs):
89
"""Replace pass at given index."""
90
91
def remove(self, index):
92
"""Remove pass at given index."""
93
94
def run(self, circuits):
95
"""
96
Execute all passes on circuits.
97
98
Parameters:
99
- circuits: Circuit or list of circuits
100
101
Returns:
102
Transpiled circuits
103
"""
104
105
def draw(self, filename=None, style=None, raw=False):
106
"""Visualize pass manager structure."""
107
108
@property
109
def passes(self):
110
"""List of passes in the manager."""
111
112
class StagedPassManager(PassManager):
113
def __init__(self, stages=None):
114
"""
115
Multi-stage pass manager.
116
117
Parameters:
118
- stages: List of pass manager stages
119
"""
120
121
def append(self, passes, **kwargs):
122
"""Append passes to the last stage."""
123
124
def replace(self, stage_index, passes, **kwargs):
125
"""Replace entire stage."""
126
127
@property
128
def stages(self):
129
"""List of pass manager stages."""
130
```
131
132
### Backend Target Specification
133
134
Hardware target specification and coupling constraints for backend-aware transpilation.
135
136
```python { .api }
137
class Target:
138
def __init__(self, description=None, num_qubits=0, dt=None, granularity=1,
139
min_length=1, pulse_alignment=1, acquire_alignment=1,
140
qubit_properties=None, concurrent_measurements=None):
141
"""
142
Backend target specification.
143
144
Parameters:
145
- description: Target description
146
- num_qubits: Number of qubits
147
- dt: System time resolution
148
- granularity: Pulse granularity
149
- min_length: Minimum pulse length
150
- pulse_alignment: Pulse alignment constraint
151
- acquire_alignment: Acquisition alignment constraint
152
- qubit_properties: Physical qubit properties
153
- concurrent_measurements: Concurrent measurement constraints
154
"""
155
156
def add_instruction(self, instruction, qargs=None, properties=None):
157
"""
158
Add supported instruction to target.
159
160
Parameters:
161
- instruction: Instruction class or instance
162
- qargs: Qubit arguments (None for all combinations)
163
- properties: Instruction properties (error rate, duration, etc.)
164
"""
165
166
def instruction_supported(self, operation_name, qargs):
167
"""Check if instruction is supported."""
168
169
def operation_from_name(self, operation_name):
170
"""Get operation class from name."""
171
172
def operations_for_qargs(self, qargs):
173
"""Get supported operations for qubit arguments."""
174
175
def instruction_properties(self, index):
176
"""Get instruction properties by index."""
177
178
@property
179
def num_qubits(self):
180
"""Number of qubits in target."""
181
182
@property
183
def instructions(self):
184
"""List of supported instructions."""
185
186
class CouplingMap:
187
def __init__(self, couplinglist=None, description=None):
188
"""
189
Coupling map representing qubit connectivity.
190
191
Parameters:
192
- couplinglist: List of [control, target] qubit pairs
193
- description: Description of coupling map
194
"""
195
196
def add_edge(self, src, dst):
197
"""Add coupling edge between qubits."""
198
199
def get_edges(self):
200
"""Get list of coupling edges."""
201
202
def neighbors(self, physical_qubit):
203
"""Get neighboring qubits."""
204
205
def distance(self, physical_qubit1, physical_qubit2):
206
"""Calculate distance between qubits."""
207
208
def shortest_undirected_path(self, physical_qubit1, physical_qubit2):
209
"""Find shortest path between qubits."""
210
211
def is_connected(self):
212
"""Check if coupling map is fully connected."""
213
214
def connected_components(self):
215
"""Get connected components."""
216
217
def reduce(self, mapping):
218
"""Reduce coupling map to subset of qubits."""
219
220
def compose(self, other, qubits):
221
"""Compose with another coupling map."""
222
223
@property
224
def physical_qubits(self):
225
"""List of physical qubits."""
226
227
@property
228
def size(self):
229
"""Number of qubits in coupling map."""
230
231
class Layout:
232
def __init__(self, input_dict=None):
233
"""
234
Layout mapping logical to physical qubits.
235
236
Parameters:
237
- input_dict: Dictionary mapping logical to physical qubits
238
"""
239
240
def add(self, virtual_bit, physical_bit=None):
241
"""Add mapping from virtual to physical bit."""
242
243
def add_register(self, reg):
244
"""Add register to layout."""
245
246
def get_registers(self):
247
"""Get all registers in layout."""
248
249
def get_physical_bits(self):
250
"""Get all physical bits."""
251
252
def get_virtual_bits(self):
253
"""Get all virtual bits."""
254
255
def swap(self, left, right):
256
"""Swap two physical bits in layout."""
257
258
def combine_into_edge_map(self, another_layout):
259
"""Combine layouts into edge map."""
260
261
def copy(self):
262
"""Create copy of layout."""
263
264
@classmethod
265
def generate_trivial_layout(cls, *regs):
266
"""Generate trivial layout for registers."""
267
268
@classmethod
269
def from_dict(cls, input_dict):
270
"""Create layout from dictionary."""
271
```
272
273
### Pass Base Classes
274
275
Base classes for implementing custom transpilation passes.
276
277
```python { .api }
278
class BasePass:
279
def __init__(self):
280
"""Base class for all transpiler passes."""
281
282
def name(self):
283
"""Pass name."""
284
return self.__class__.__name__
285
286
def run(self, dag):
287
"""
288
Execute pass on DAGCircuit.
289
290
Parameters:
291
- dag: DAGCircuit to transform
292
293
Returns:
294
DAGCircuit: Transformed circuit
295
"""
296
raise NotImplementedError
297
298
class AnalysisPass(BasePass):
299
def __init__(self):
300
"""Base class for analysis passes that collect information."""
301
302
def run(self, dag):
303
"""Analyze circuit and store results in property_set."""
304
raise NotImplementedError
305
306
class TransformationPass(BasePass):
307
def __init__(self):
308
"""Base class for passes that transform circuits."""
309
310
def run(self, dag):
311
"""Transform circuit and return modified DAG."""
312
raise NotImplementedError
313
```
314
315
### Property Set and Flow Control
316
317
Shared state management and conditional pass execution.
318
319
```python { .api }
320
class PropertySet:
321
def __init__(self):
322
"""Storage for pass analysis results and shared properties."""
323
324
def __getitem__(self, key):
325
"""Get property value."""
326
327
def __setitem__(self, key, value):
328
"""Set property value."""
329
330
def __contains__(self, key):
331
"""Check if property exists."""
332
333
def keys(self):
334
"""Get all property keys."""
335
336
def values(self):
337
"""Get all property values."""
338
339
def items(self):
340
"""Get all (key, value) pairs."""
341
342
class FlowController:
343
def __init__(self, passes, options=None, **partial_controller):
344
"""
345
Control pass execution flow.
346
347
Parameters:
348
- passes: Passes to control
349
- options: Flow control options
350
- **partial_controller: Partial controller arguments
351
"""
352
353
def iter_tasks(self, max_iteration):
354
"""Iterate through controlled tasks."""
355
356
class ConditionalController(FlowController):
357
def __init__(self, passes, condition=None, **partial_controller):
358
"""
359
Execute passes conditionally.
360
361
Parameters:
362
- passes: Passes to execute conditionally
363
- condition: Condition function or property name
364
"""
365
366
class DoWhileController(FlowController):
367
def __init__(self, passes, do_while=None, **partial_controller):
368
"""
369
Execute passes in do-while loop.
370
371
Parameters:
372
- passes: Passes to execute in loop
373
- do_while: Loop continuation condition
374
"""
375
```
376
377
### Common Analysis Passes
378
379
Built-in passes for circuit analysis and property collection.
380
381
```python { .api }
382
class Depth(AnalysisPass):
383
def __init__(self):
384
"""Analyze circuit depth."""
385
386
class Size(AnalysisPass):
387
def __init__(self):
388
"""Count total number of operations."""
389
390
class Width(AnalysisPass):
391
def __init__(self):
392
"""Analyze circuit width (total qubits + clbits)."""
393
394
class CountOps(AnalysisPass):
395
def __init__(self):
396
"""Count operations by type."""
397
398
class CountOpsLongestPath(AnalysisPass):
399
def __init__(self):
400
"""Count operations on longest path."""
401
402
class NumTensorFactors(AnalysisPass):
403
def __init__(self):
404
"""Count number of tensor factors."""
405
406
class GatesInBasis(AnalysisPass):
407
def __init__(self, basis_gates, target=None):
408
"""
409
Check if all gates are in basis.
410
411
Parameters:
412
- basis_gates: Allowed gate set
413
- target: Backend target (alternative to basis_gates)
414
"""
415
```
416
417
### Common Transformation Passes
418
419
Built-in passes for circuit transformation and optimization.
420
421
```python { .api }
422
class Unroller(TransformationPass):
423
def __init__(self, basis):
424
"""
425
Unroll custom gates to basis gates.
426
427
Parameters:
428
- basis: Target basis gate set
429
"""
430
431
class BasisTranslator(TransformationPass):
432
def __init__(self, equivalence_library, target_basis):
433
"""
434
Translate gates using equivalence library.
435
436
Parameters:
437
- equivalence_library: Gate equivalence rules
438
- target_basis: Target gate basis
439
"""
440
441
class Optimize1qGates(TransformationPass):
442
def __init__(self, basis=None, eps=1e-15, target=None):
443
"""
444
Optimize single-qubit gate chains.
445
446
Parameters:
447
- basis: Single-qubit basis gates
448
- eps: Tolerance for optimization
449
- target: Backend target
450
"""
451
452
class CXCancellation(TransformationPass):
453
def __init__(self):
454
"""Cancel adjacent CX gates."""
455
456
class CommutativeCancellation(TransformationPass):
457
def __init__(self, basis_gates=None, target=None):
458
"""
459
Cancel commuting gates.
460
461
Parameters:
462
- basis_gates: Allowed gate set
463
- target: Backend target
464
"""
465
```
466
467
### Usage Examples
468
469
```python
470
from qiskit import QuantumCircuit, transpile
471
from qiskit.transpiler import PassManager, CouplingMap, Target
472
from qiskit.transpiler.passes import Unroller, Optimize1qGates, CXCancellation
473
from qiskit.providers.fake_provider import FakeManila
474
import numpy as np
475
476
# Basic transpilation
477
circuit = QuantumCircuit(3)
478
circuit.h(0)
479
circuit.cx(0, 1)
480
circuit.cx(1, 2)
481
circuit.rz(np.pi/4, 2)
482
483
# Transpile for specific backend
484
backend = FakeManila()
485
transpiled = transpile(circuit, backend=backend, optimization_level=2)
486
print(f"Original depth: {circuit.depth()}, Transpiled depth: {transpiled.depth()}")
487
488
# Manual pass manager construction
489
pass_manager = PassManager()
490
pass_manager.append(Unroller(['cx', 'u3'])) # Unroll to basis gates
491
pass_manager.append(Optimize1qGates()) # Optimize single-qubit gates
492
pass_manager.append(CXCancellation()) # Cancel adjacent CX gates
493
494
optimized_circuit = pass_manager.run(circuit)
495
496
# Custom coupling map
497
coupling_list = [[0, 1], [1, 2], [2, 3], [3, 4]]
498
coupling_map = CouplingMap(coupling_list)
499
500
# Transpile with custom coupling
501
routed_circuit = transpile(circuit,
502
coupling_map=coupling_map,
503
basis_gates=['cx', 'u3'],
504
optimization_level=1)
505
506
# Target specification for custom backend
507
target = Target(num_qubits=5)
508
target.add_instruction('cx', [(0, 1), (1, 2), (2, 3), (3, 4)])
509
target.add_instruction('u3', None) # Available on all qubits
510
511
# Transpile with target
512
target_transpiled = transpile(circuit, target=target)
513
514
# Preset pass managers for different optimization levels
515
pm_level_0 = generate_preset_pass_manager(0, backend=backend) # No optimization
516
pm_level_1 = generate_preset_pass_manager(1, backend=backend) # Light optimization
517
pm_level_2 = generate_preset_pass_manager(2, backend=backend) # Heavy optimization
518
pm_level_3 = generate_preset_pass_manager(3, backend=backend) # Maximum optimization
519
520
# Compare optimization levels
521
results = {}
522
for level in [0, 1, 2, 3]:
523
pm = generate_preset_pass_manager(level, backend=backend)
524
result = pm.run(circuit)
525
results[level] = {
526
'depth': result.depth(),
527
'size': len(result),
528
'cx_count': result.count_ops().get('cx', 0)
529
}
530
531
for level, metrics in results.items():
532
print(f"Level {level}: depth={metrics['depth']}, size={metrics['size']}, cx={metrics['cx_count']}")
533
534
# Parameterized transpilation options
535
circuits = [circuit] * 4
536
transpiled_batch = transpile(
537
circuits,
538
backend=backend,
539
initial_layout=[0, 1, 2], # Force specific qubit assignment
540
layout_method='sabre', # Use SABRE layout algorithm
541
routing_method='sabre', # Use SABRE routing
542
optimization_level=2,
543
seed_transpiler=42 # Reproducible results
544
)
545
546
print(f"Batch transpiled {len(transpiled_batch)} circuits")
547
```