Skip to content

Hardware-Aware Synthesis

Quantum computers differ from each other in many significant parameters, such as basis gates, connectivity, error rates etc. The device specifications determine the possibility of executing the quantum circuit, and logically-equivalent programs might require different implementations to optimize the success probability.

The Classiq platform allows you to provide information about the hardware you want to use to run your circuit. The synthesis engine takes the parameters of this hardware into account. For example, the engine could choose the implementation of a function that would require the least amount of swaps given the connectivity of the hardware.

Specifying a Backend

If you wish to synthesize your circuit for a specific backend, you can simply specify the backend provider and the name of the backend.

The Classiq platform supports the following backend providers:

  • AWS Braket
    • Classiq supports all gate-based backends in AWS Braket
    • Namely, this includes all Rigetti devices, Lucy and IonQ Device
  • Azure Quantum
    • The supported backends are ionq and quantinuum
  • IBM Quantum
    • The list of available backends can be found on IBM Quantum's official website
    • Note that the name of the backend should be specified without the ibmq_ prefix
{
  "logic_flow": [],
  "preferences": {
    "backend_service_provider": "IBM Quantum",
    "backend_name": "Lima"
  }
}
from classiq.interface.generator.model import Preferences

from classiq import ModelDesigner

model_designer = ModelDesigner()
preferences = Preferences(backend_service_provider="IBM Quantum", backend_name="Lima")
model_designer.synthesize(preferences=preferences)

Custom Hardware Settings

In case you want to synthesize the circuit for some hardware that is not available in the Classiq platform, you can instead specify the custom settings of the desirable hardware. This includes the basis gate set and the connectivity map of the hardware.

Note that all hardware parameters are optional.

Basis Gate Set

The allowed gates are listed as follows:

  • Single-qubit gates: u1, u2, u, p, x, y, z, t, tdg, s, sdg, sx, sxdg, rx, ry, rz, id, h
  • Basic two-qubit gates: cx, cy, cz
  • Extra two-qubit gates: swap, rxx, ryy, rzz, rzx, ecr, crx, cry, crz, csx, cu1, cu, cp, ch
  • Three-qubit gates: ccx, cswap

If none are specified, the default set consists of all single-qubit gates and the basic two-qubit gates.

Connectivity Map

The connectivity map is given by a list of pairs of qubit IDs. Each pair in the list means that a two-qubit gate (e.g., cx) can be performed on the pair of qubits. If the coupling map is symmetric, then both qubits can act as control. If the coupling map is asymmetric, then the first qubit can act only as control, and the second qubit can act only as target. You can determine whether the provided map is symmetric or not by setting the is_symmetric_connectivity argument.

If the connectivity map is not specified, the engine assumes full connectivity.

Example

In the following example, we specify a backend with 6 qubits in a 2-by-3 grid, where each qubit is connected to its immediate neighbors. The backend uses 4 basis gates: cx, rz, sx and x.

{
  "logic_flow": [{
    "function": "QFT",
    "function_params": { "num_qubits": 6 }
  }],
  "preferences": {
    "custom_hardware_settings": {
      "basis_gates": ["cx", "rz", "sx", "x"],
      "connectivity_map": [[0, 1], [0, 3], [1, 4], [1, 2], [2, 5], [3, 4], [4, 5]],
      "is_symmetric_connectivity": true
    }
  }
}
from classiq.interface.generator.model import Preferences
from classiq.interface.generator.model.preferences.preferences import (
    CustomHardwareSettings,
)

from classiq import ModelDesigner
from classiq.builtin_functions import QFT

custom_hardware_settings = CustomHardwareSettings(
    basis_gates=["cx", "rz", "sx", "x"],
    connectivity_map=[(0, 1), (0, 3), (1, 4), (1, 2), (2, 5), (3, 4), (4, 5)],
    is_symmetric_connectivity=True,
)
preferences = Preferences(custom_hardware_settings=custom_hardware_settings)

model_designer = ModelDesigner()
qft_params = QFT(num_qubits=6)
model_designer.QFT(params=qft_params)

model_designer.synthesize(preferences=preferences)