Skip to content

Commit

Permalink
Fix missing round when converting expr to 'dt'.
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinhartman committed Feb 24, 2025
1 parent 51dd954 commit 58a7811
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
17 changes: 13 additions & 4 deletions qiskit/transpiler/passes/scheduling/time_unit_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,24 @@ def run(self, dag: DAGCircuit):

visitor = _EvalDurationImpl(inst_durations.dt)
duration = node.op.duration.accept(visitor)
if visitor.in_cycles():
has_dt = True
# We need to round in case the expression evaluated to a non-integral 'dt'.
rounded_duration = round(duration)
rounding_error = abs(duration - rounded_duration)
if rounding_error > 1e-15:
warnings.warn(
f"Duration is rounded to {rounded_duration:d} [dt] from {duration:f}",
UserWarning,
)
duration = rounded_duration
else:
has_si = True
if duration < 0:
raise TranspilerError(
f"Expression '{node.op.duration}' resolves to a negative duration!"
)
expression_durations[node._node_id] = duration
if visitor.in_cycles():
has_dt = True
else:
has_si = True
else:
if node.op.unit == "dt":
has_dt = True
Expand Down
18 changes: 17 additions & 1 deletion test/python/compiler/test_transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,7 @@ def test_delay_converts_to_dt(self):
out = transpile(qc, dt=1e-9, seed_transpiler=42)
self.assertEqual(out.data[0].operation.unit, "dt")

def test_delay_converts_to_dt_expr(self):
def test_delay_converts_expr_to_dt(self):
"""Test that a delay instruction with a duration expression of type Duration
is converted to units of dt given a backend."""
qc = QuantumCircuit(2)
Expand All @@ -1545,6 +1545,22 @@ def test_delay_converts_to_dt_expr(self):
out = transpile(qc, dt=1e-9, seed_transpiler=42)
self.assertEqual(out.data[0].operation.unit, "dt")

def test_delay_converts_expr_to_dt_with_rounding(self):
"""Test that converting to 'dt' from wall-time correctly rounds to nearest
integer."""
qc = QuantumCircuit(2)
qc.delay(expr.lift(Duration.ns(1234560)), [0])

backend = GenericBackendV2(num_qubits=4)
backend.target.dt = 5e-7

with self.assertWarnsRegex(UserWarning, "Duration is rounded"):
out = transpile(qc, backend, seed_transpiler=42)

self.assertEqual(out.data[0].operation.unit, "dt")
self.assertEqual(type(out.data[0].duration), int)
self.assertEqual(out.data[0].duration, round(float(1234560) / 1e9 / 5e-7))

def test_delay_expr_evaluation_dt(self):
"""Test that a delay instruction with a complex duration expression
of type Duration is evaluated to 'dt' properly."""
Expand Down

0 comments on commit 58a7811

Please sign in to comment.