Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/qc_compiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
from qc_compiler.scheduling import CoherenceAwareScheduler, ScheduleResult
from qc_compiler.transpiler import OptimizerConfig, QCompiler, QCompilerResult
from qc_compiler.utils import (
DEFAULT_READOUT_ERROR,
DEFAULT_SINGLE_QUBIT_ERROR,
DEFAULT_SINGLE_QUBIT_GATE_TIME,
DEFAULT_T2_TIME,
DEFAULT_TWO_QUBIT_ERROR,
DEFAULT_TWO_QUBIT_GATE_TIME,
TWO_QUBIT_GATES,
compute_circuit_depth,
compute_cnot_count,
Expand All @@ -30,6 +36,12 @@
)

__all__ = [
"DEFAULT_READOUT_ERROR",
"DEFAULT_SINGLE_QUBIT_ERROR",
"DEFAULT_SINGLE_QUBIT_GATE_TIME",
"DEFAULT_T2_TIME",
"DEFAULT_TWO_QUBIT_ERROR",
"DEFAULT_TWO_QUBIT_GATE_TIME",
"TWO_QUBIT_GATES",
"AdaptiveErrorMitigation",
"AutoTuner",
Expand Down
19 changes: 10 additions & 9 deletions src/qc_compiler/cost_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
from qiskit import QuantumCircuit

from qc_compiler.utils import (
DEFAULT_READOUT_ERROR,
DEFAULT_SINGLE_QUBIT_ERROR,
DEFAULT_SINGLE_QUBIT_GATE_TIME,
DEFAULT_T2_TIME,
DEFAULT_TWO_QUBIT_ERROR,
TWO_QUBIT_GATES,
compute_circuit_depth,
get_backend_properties,
Expand Down Expand Up @@ -342,15 +347,15 @@ def _get_gate_fidelity_for_pair(
def _avg_single_qubit_error(self) -> float:
"""Compute average single-qubit gate error across all qubits."""
if not self.device.single_qubit_gate_errors:
return 0.0005
return DEFAULT_SINGLE_QUBIT_ERROR

errors = list(self.device.single_qubit_gate_errors.values())
return sum(errors) / len(errors)

def _avg_two_qubit_error(self) -> float:
"""Compute average two-qubit gate error across all qubit pairs."""
if not self.device.two_qubit_gate_errors:
return 0.01
return DEFAULT_TWO_QUBIT_ERROR

errors = list(self.device.two_qubit_gate_errors.values())
return sum(errors) / len(errors)
Expand Down Expand Up @@ -401,20 +406,17 @@ def _estimate_decoherence_error_default(

Uses typical superconducting qubit T2 time of 150 μs.
"""
DEFAULT_T2 = 150e-6
DEFAULT_GATE_TIME = 50e-9

depth = compute_circuit_depth(circuit)
total_time = depth * DEFAULT_GATE_TIME
fidelity = float(2.0 ** (-total_time / DEFAULT_T2))
total_time = depth * DEFAULT_SINGLE_QUBIT_GATE_TIME
fidelity = float(2.0 ** (-total_time / DEFAULT_T2_TIME))
product = fidelity**circuit.num_qubits

return 1.0 - product

def _avg_gate_time(self) -> float:
"""Compute average gate duration across all gate types."""
if not self.device.gate_lengths:
return 50e-9
return DEFAULT_SINGLE_QUBIT_GATE_TIME

times = list(self.device.gate_lengths.values())
return sum(times) / len(times)
Expand All @@ -435,7 +437,6 @@ def estimate_measurement_error(
measured_qubits = self._get_measured_qubits(circuit)

if not self.device.readout_errors:
DEFAULT_READOUT_ERROR = 0.015
return 1.0 - (1.0 - DEFAULT_READOUT_ERROR) ** len(measured_qubits)

product = 1.0
Expand Down
18 changes: 12 additions & 6 deletions src/qc_compiler/cutting.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@
from qiskit import QuantumCircuit

from qc_compiler.cost_model import CostModel
from qc_compiler.utils import TWO_QUBIT_GATES
from qc_compiler.utils import (
DEFAULT_SINGLE_QUBIT_ERROR,
DEFAULT_SINGLE_QUBIT_GATE_TIME,
DEFAULT_T2_TIME,
DEFAULT_TWO_QUBIT_ERROR,
TWO_QUBIT_GATES,
)


@dataclass
Expand Down Expand Up @@ -535,8 +541,8 @@ def _estimate_cut_error(
depth = max(1, circuit.depth() // num_groups)
avg_t2 = self._avg_t2()
decoherence_error = 1 - float(
2.0 ** (-depth * 50e-9 / avg_t2)
) if avg_t2 > 0 else 0.01
2.0 ** (-depth * DEFAULT_SINGLE_QUBIT_GATE_TIME / avg_t2)
) if avg_t2 > 0 else DEFAULT_TWO_QUBIT_ERROR

group_error = 1 - (1 - gate_error) * (1 - decoherence_error)
group_errors.append(group_error)
Expand Down Expand Up @@ -654,7 +660,7 @@ def _avg_single_qubit_error(self) -> float:
self.cost_model.device.single_qubit_gate_errors.values()
)
return sum(errors) / len(errors)
return 0.0005
return DEFAULT_SINGLE_QUBIT_ERROR

def _avg_two_qubit_error(self) -> float:
"""Get average two-qubit gate error from device or default."""
Expand All @@ -663,11 +669,11 @@ def _avg_two_qubit_error(self) -> float:
self.cost_model.device.two_qubit_gate_errors.values()
)
return sum(errors) / len(errors)
return 0.01
return DEFAULT_TWO_QUBIT_ERROR

def _avg_t2(self) -> float:
"""Get average T2 time from device or default."""
if self.cost_model.device.t2_times:
times = list(self.cost_model.device.t2_times.values())
return sum(times) / len(times)
return 150e-6
return DEFAULT_T2_TIME
3 changes: 2 additions & 1 deletion src/qc_compiler/scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from qiskit import QuantumCircuit

from qc_compiler.cost_model import CostModel
from qc_compiler.utils import DEFAULT_SINGLE_QUBIT_GATE_TIME


@dataclass
Expand Down Expand Up @@ -504,7 +505,7 @@ def _avg_gate_time(self) -> float:
if self.cost_model.device.gate_lengths:
times = list(self.cost_model.device.gate_lengths.values())
return sum(times) / len(times)
return 50e-9
return DEFAULT_SINGLE_QUBIT_GATE_TIME

def _compute_t2_priority(self, num_qubits: int) -> dict[int, float]:
"""Compute per-qubit T2-based scheduling priority.
Expand Down
15 changes: 11 additions & 4 deletions src/qc_compiler/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@

TWO_QUBIT_GATES = {"cx", "cz", "ecr", "swap", "rxx", "rzz", "ryy", "crx", "cry", "crz"}

DEFAULT_SINGLE_QUBIT_ERROR = 0.0005
DEFAULT_TWO_QUBIT_ERROR = 0.01
DEFAULT_READOUT_ERROR = 0.015
DEFAULT_T2_TIME = 150e-6
DEFAULT_SINGLE_QUBIT_GATE_TIME = 50e-9
DEFAULT_TWO_QUBIT_GATE_TIME = 300e-9


def get_backend_properties(backend: BackendV2) -> dict:
"""Extract calibration properties from a quantum backend.
Expand Down Expand Up @@ -164,8 +171,8 @@ def get_avg_gate_time(device_props: dict, gate_type: str = "all") -> float:

if not gate_lengths:
if gate_type == "two":
return 300e-9
return 50e-9
return DEFAULT_TWO_QUBIT_GATE_TIME
return DEFAULT_SINGLE_QUBIT_GATE_TIME

times = []
for (gate_name, qubits), duration in gate_lengths.items():
Expand All @@ -174,7 +181,7 @@ def get_avg_gate_time(device_props: dict, gate_type: str = "all") -> float:

if not times:
if gate_type == "two":
return 300e-9
return 50e-9
return DEFAULT_TWO_QUBIT_GATE_TIME
return DEFAULT_SINGLE_QUBIT_GATE_TIME

return sum(times) / len(times)
Loading