Architecture¶
The architecture describes the properties of the target device when mapping a quantum circuit.
An Architecture can be constructed in various ways:
From a Qiskit
Backend
instance such as those defined underqiskit.providers.fake_provider
(recommended),From a coupling map defined as a set of tuples of qubits.
From the path to a file containing the number of qubits and a line-by-line enumeration of the qubit connections.
Constructing an Architecture¶
From a Qiskit Backend¶
Architectures can be imported directly from Qiskit backends. Assuming backend
is a Qiskit backend, converting it to an Architecture is done as follows:
from mqt.qmap.qiskit.backend import import_backend architecture = import_backend(backend)
From a Coupling Map¶
A coupling map is defined as a set of tuples of qubits. The qubits are given as integers ranging from \(0\) to \(num\_qubits - 1\).
from mqt import qmap coupling_map = {(0, 1), (1, 2), (2, 3)} num_qubits = 4 arch = qmap.Architecture(num_qubits, coupling_map)
The architecture above is a directional architecture, meaning that control and target between connected qubits cannot be arbitrarily assigned. In the above example, a CNOT with qubit 0 as control and qubit 1 as target is possible, while the reverse CNOT with qubit 1 as control and qubit 0 as target is invalid.
A bidirectional architecture where any qubit can be either control or target of a CNOT gate can be defined by adding both directions for each edge.
from mqt import qmap coupling_map = {(0, 1), (1, 0), (1, 2), (2, 1), (2, 3), (3, 2)} num_qubits = 4 arch = qmap.Architecture(num_qubits, coupling_map)
In addition to the number of qubits and the coupling map, QMAP’s Architecture class also holds further device information such as gate and readout errors (see below for details). Note that QMAP does not consider this information during mapping at this point. Noise-aware mapping is planned for future releases of QMAP.
From a File¶
An architecture can be imported from a file. Assuming path
is a string variable containing the path to an architecture file, this is done as follows:
arch = Architecture() arch.load_coupling_map(path)
The first line of an architecture file is the number of qubits of the architecture. The remaining lines are tuples defining the connections of the coupling map. More explicitly, the file format is defined by the following Backus-Naur-Form.
<coupling_map> ::= <integer>"\n"(<qubit>" "<qubit>"\n")* <qubit> ::= 0|1|2| ... |nqubits-2|nqubits-1
Here the first integer defines the number of qubits of the architecture.
Full API of the Architecture class¶
- class Architecture¶
Class representing device/backend information
- class Properties¶
Class representing properties of an architecture
- __init__(self: mqt.qmap.pyqmap.Architecture.Properties) None ¶
- get_calibration_date(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int) str ¶
- get_frequency(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int) float ¶
- get_readout_error(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int) float ¶
- get_single_qubit_error(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, operation: str) float ¶
- get_t1(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int) float ¶
- get_t2(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int) float ¶
- get_two_qubit_error(self: mqt.qmap.pyqmap.Architecture.Properties, control: int, target: int, operation: str = 'cx') float ¶
- json(self: mqt.qmap.pyqmap.Architecture.Properties) json ¶
Returns a JSON-style dictionary of all the information present in the
Properties
- property name¶
- property num_qubits¶
- set_calibration_date(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, calibration_date: str) None ¶
- set_frequency(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, qubit_frequency: float) None ¶
- set_readout_error(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, readout_error_rate: float) None ¶
- set_single_qubit_error(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, operation: str, error_rate: float) None ¶
- set_t1(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, t1: float) None ¶
- set_t2(self: mqt.qmap.pyqmap.Architecture.Properties, qubit: int, t2: float) None ¶
- __init__(*args, **kwargs)¶
Overloaded function.
__init__(self: mqt.qmap.pyqmap.Architecture) -> None
__init__(self: mqt.qmap.pyqmap.Architecture, num_qubits: int, coupling_map: set[tuple[int, int]]) -> None
__init__(self: mqt.qmap.pyqmap.Architecture, num_qubits: int, coupling_map: set[tuple[int, int]], properties: mqt.qmap.pyqmap.Architecture.Properties) -> None
- property coupling_map¶
- load_coupling_map(*args, **kwargs)¶
Overloaded function.
load_coupling_map(self: mqt.qmap.pyqmap.Architecture, available_architecture: mqt.qmap.pyqmap.Arch) -> None
load_coupling_map(self: mqt.qmap.pyqmap.Architecture, coupling_map_file: str) -> None
- load_properties(*args, **kwargs)¶
Overloaded function.
load_properties(self: mqt.qmap.pyqmap.Architecture, properties: mqt.qmap.pyqmap.Architecture.Properties) -> None
load_properties(self: mqt.qmap.pyqmap.Architecture, properties: str) -> None
- property name¶
- property num_qubits¶
- property properties¶
For convenience, this module provides several pre-defined architectures.
- class Arch¶
Members:
IBM_QX4 : 5 qubit, directed bow tie layout
IBM_QX5 : 16 qubit, directed ladder layout
IBMQ_Yorktown : 5 qubit, undirected bow tie layout
IBMQ_London : 5 qubit, undirected T-shape layout
IBMQ_Bogota : 5 qubit, undirected linear chain layout
IBMQ_Casablanca : 7 qubit, undirected H-shape layout
IBMQ_Tokyo : 20 qubit, undirected brick-like layout
Rigetti_Agave : 8 qubit, undirected ring layout
Rigetti_Aspen : 16 qubit, undirected dumbbell layout
- property name¶