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
29 changes: 26 additions & 3 deletions src/qc_compiler/scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,12 @@ def _get_gate_duration(
) -> int:
"""Get the duration of a gate in abstract time units.

Uses device calibration data when available. Falls back to
a simple model: single-qubit gates = 1 unit, two-qubit gates
= 3 units (reflecting typical duration ratios on IBM hardware).
Uses device calibration data when available. Looks up the
actual gate duration from gate_lengths and converts it to
abstract units relative to a single-qubit gate. Falls back
to a simple model: single-qubit gates = 1 unit, two-qubit
gates = 3 units (reflecting typical duration ratios on IBM
hardware).

Args:
gate_name: Name of the gate.
Expand All @@ -492,6 +495,26 @@ def _get_gate_duration(
Returns:
Duration in abstract time units.
"""
gate_lengths = self.cost_model.device.gate_lengths

if gate_lengths:
avg_sq_time = DEFAULT_SINGLE_QUBIT_GATE_TIME

sq_times = [
v for (g, qs), v in gate_lengths.items()
if len(qs) == 1
]
if sq_times:
avg_sq_time = sum(sq_times) / len(sq_times)

key = (gate_name, tuple(qubits))
if key in gate_lengths:
return max(1, round(gate_lengths[key] / avg_sq_time))

for (g, qs), v in gate_lengths.items():
if g == gate_name and len(qs) == len(qubits):
return max(1, round(v / avg_sq_time))

if qubits and len(qubits) >= 2:
return 3
return 1
Expand Down
50 changes: 49 additions & 1 deletion tests/test_scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,4 +442,52 @@ def test_alap_produces_different_schedule_than_asap(self, scheduler):

assert asap_result.method == "asap"
assert alap_result.method == "alap"
assert asap_result.method != alap_result.method
assert asap_result.method != alap_result.method


class TestGateDurationCalibration:
"""Regression tests for gate duration from device calibration (issue #57)."""

def test_gate_duration_uses_device_data(self):
from qc_compiler.cost_model import DeviceCharacterization

device = DeviceCharacterization(
backend_name="test",
num_qubits=2,
gate_lengths={
("sx", (0,)): 50e-9,
("sx", (1,)): 60e-9,
("cx", (0, 1)): 300e-9,
},
)
model = CostModel()
model.device = device
scheduler = CoherenceAwareScheduler(cost_model=model)

assert scheduler._get_gate_duration("sx", [0]) == 1
assert scheduler._get_gate_duration("sx", [1]) == 1
assert scheduler._get_gate_duration("cx", [0, 1]) == 5

def test_gate_duration_fallback_without_device(self):
scheduler = CoherenceAwareScheduler(cost_model=CostModel())
assert scheduler._get_gate_duration("sx", [0]) == 1
assert scheduler._get_gate_duration("cx", [0, 1]) == 3

def test_gate_duration_matches_same_size_gate(self):
from qc_compiler.cost_model import DeviceCharacterization

device = DeviceCharacterization(
backend_name="test",
num_qubits=3,
gate_lengths={
("sx", (0,)): 50e-9,
("cx", (0, 1)): 250e-9,
("cx", (1, 2)): 400e-9,
},
)
model = CostModel()
model.device = device
scheduler = CoherenceAwareScheduler(cost_model=model)

assert scheduler._get_gate_duration("cx", [0, 1]) == 5
assert scheduler._get_gate_duration("cx", [1, 2]) == 8
Loading