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 under qiskit.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#
set_two_qubit_error(self: mqt.qmap.pyqmap.Architecture.Properties, control: int, target: int, error_rate: float, operation: str = 'cx') None#
__init__(*args, **kwargs)#

Overloaded function.

  1. __init__(self: mqt.qmap.pyqmap.Architecture) -> None

  2. __init__(self: mqt.qmap.pyqmap.Architecture, num_qubits: int, coupling_map: Set[Tuple[int, int]]) -> None

  3. __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.

  1. load_coupling_map(self: mqt.qmap.pyqmap.Architecture, available_architecture: mqt.qmap.pyqmap.Arch) -> None

  2. load_coupling_map(self: mqt.qmap.pyqmap.Architecture, coupling_map_file: str) -> None

load_properties(*args, **kwargs)#

Overloaded function.

  1. load_properties(self: mqt.qmap.pyqmap.Architecture, properties: mqt.qmap.pyqmap.Architecture.Properties) -> None

  2. 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#