# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH
# All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License
"""File to create target devices for IQM with hardcoded mean calibration data."""
from __future__ import annotations
from qiskit.circuit import IfElseOp, Parameter
from qiskit.circuit.library import CZGate, Measure, RGate
from qiskit.transpiler import InstructionProperties, Target
from ._registry import register_device
[docs]
@register_device("iqm_crystal_5")
def get_iqm_crystal_5() -> Target:
"""Get the target for a 5-qubit IQM Crystal architecture."""
return _build_iqm_target(
name="iqm_crystal_5",
num_qubits=5,
connectivity=[[0, 2], [1, 2], [3, 2], [4, 2]],
oneq_error=0.00132,
twoq_error=0.0311,
readout_error=0.0278,
oneq_duration=4e-8,
twoq_duration=8e-8,
readout_duration=1.5e-5,
)
[docs]
@register_device("iqm_crystal_20")
def get_iqm_crystal_20() -> Target:
"""Get the target for a 20-qubit IQM Crystal architecture."""
return _build_iqm_target(
name="iqm_crystal_20",
num_qubits=20,
connectivity=[
[0, 1],
[0, 3],
[1, 4],
[2, 3],
[7, 2],
[3, 4],
[8, 3],
[4, 5],
[9, 4],
[5, 6],
[10, 5],
[11, 6],
[7, 8],
[7, 12],
[8, 9],
[8, 13],
[9, 10],
[9, 14],
[10, 11],
[15, 10],
[16, 11],
[12, 13],
[13, 14],
[17, 13],
[15, 14],
[18, 14],
[15, 16],
[15, 19],
[17, 18],
[18, 19],
],
oneq_error=0.001259,
twoq_error=0.01474,
readout_error=0.05075,
oneq_duration=4.2e-8,
twoq_duration=1.3e-7,
readout_duration=1.5e-5,
)
[docs]
@register_device("iqm_crystal_54")
def get_iqm_crystal_54() -> Target:
"""Get the target for a 54-qubit IQM Crystal architecture."""
return _build_iqm_target(
name="iqm_crystal_54",
num_qubits=54,
connectivity=[
[0, 1],
[0, 4],
[1, 5],
[2, 3],
[2, 8],
[3, 4],
[3, 9],
[4, 5],
[4, 10],
[5, 6],
[5, 11],
[6, 12],
[7, 8],
[7, 15],
[8, 9],
[8, 16],
[9, 10],
[9, 17],
[10, 11],
[10, 18],
[11, 12],
[11, 19],
[12, 13],
[12, 20],
[13, 21],
[14, 15],
[14, 22],
[15, 16],
[15, 23],
[16, 17],
[16, 24],
[17, 18],
[17, 25],
[18, 19],
[18, 26],
[19, 20],
[19, 27],
[20, 21],
[20, 28],
[21, 29],
[22, 23],
[23, 24],
[23, 31],
[24, 25],
[24, 32],
[25, 26],
[25, 33],
[26, 27],
[26, 34],
[27, 28],
[27, 35],
[28, 29],
[28, 36],
[29, 30],
[29, 37],
[30, 38],
[31, 32],
[31, 39],
[32, 33],
[32, 40],
[33, 34],
[33, 41],
[34, 35],
[34, 42],
[35, 36],
[35, 43],
[36, 37],
[36, 44],
[37, 38],
[37, 45],
[39, 40],
[40, 41],
[40, 46],
[41, 42],
[41, 47],
[42, 43],
[42, 48],
[43, 44],
[43, 49],
[44, 45],
[44, 50],
[46, 47],
[47, 48],
[47, 51],
[48, 49],
[48, 52],
[49, 50],
[49, 53],
[51, 52],
[52, 53],
],
oneq_error=0.001259,
twoq_error=0.01474,
readout_error=0.05075,
oneq_duration=4.2e-8,
twoq_duration=1.3e-7,
readout_duration=1.5e-5,
)
def _build_iqm_target(
*,
name: str,
num_qubits: int,
connectivity: list[list[int]],
oneq_error: float,
twoq_error: float,
readout_error: float,
oneq_duration: float,
twoq_duration: float,
readout_duration: float,
) -> Target:
"""Construct a hardcoded IQM target using mean values and bidirectional connectivity."""
target = Target(num_qubits=num_qubits, description=name)
theta = Parameter("theta")
phi = Parameter("phi")
# === Add single-qubit gates ===
r_props = {(q,): InstructionProperties(duration=oneq_duration, error=oneq_error) for q in range(num_qubits)}
measure_props = {
(q,): InstructionProperties(duration=readout_duration, error=readout_error) for q in range(num_qubits)
}
target.add_instruction(RGate(theta, phi), r_props)
target.add_instruction(Measure(), measure_props)
# === Add two-qubit gates ===
# Account for bidirectionality of CZ gate
connectivity += [[q1, q0] for q0, q1 in connectivity]
cz_props = {(q1, q2): InstructionProperties(duration=twoq_duration, error=twoq_error) for q1, q2 in connectivity}
target.add_instruction(CZGate(), cz_props)
# === Add control-flow ops ===
target.add_instruction(IfElseOp, name="if_else")
return target