Skip to content

Commit 740a9dc

Browse files
authored
Allow circuits using only SI units to pass through TimeUnitConversion (#14027)
* Allow circuits using only SI units to pass through TimeUnitConversion In f0576fa, the `TimeUnitConversion` pass was modified so that it raises an exception if a circuit has only SI unit delays with no `dt` value set, but the intent seemed to be catch cases where SI units were used alongside instructions with `dt` units. Here the conditions for raising an exception are modified to allow circuits with all SI unit delays (which usually only happens when working with a backend like `AerSimulator`) to pass through. Closes #14016 * Add TimeUnitConverion tests * Update test description * Remove comment * lint test file * Refactor TimeUnitConversion for readability * Move time unit converison tests to test_transpiler * lint * lint
1 parent 56a16ab commit 740a9dc

2 files changed

Lines changed: 47 additions & 6 deletions

File tree

qiskit/transpiler/passes/scheduling/time_unit_conversion.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,19 @@ def run(self, dag: DAGCircuit):
126126
# Check what units are used in other instructions: dt or SI or mixed
127127
units_other = inst_durations.units_used()
128128
unified_unit = self._unified(units_other)
129-
if unified_unit == "SI" and not has_dt:
130-
time_unit = "s"
131-
elif unified_unit == "dt" and not has_si:
132-
time_unit = "dt"
133-
else:
129+
has_si = has_si or unified_unit in {"SI", "mixed"}
130+
has_dt = has_dt or unified_unit in {"dt", "mixed"}
131+
if has_si and has_dt:
134132
raise TranspilerError(
135133
"Fail to unify time units. SI units "
136134
"and dt unit must not be mixed when dt is not supplied."
137135
)
136+
if has_si:
137+
time_unit = "s"
138+
else:
139+
# Either dt units were used or no units were used and we
140+
# default to dt
141+
time_unit = "dt"
138142
else:
139143
time_unit = "dt"
140144

@@ -154,7 +158,7 @@ def run(self, dag: DAGCircuit):
154158
@staticmethod
155159
def _unified(unit_set: Set[str]) -> str:
156160
if not unit_set:
157-
return "dt"
161+
return "none"
158162

159163
if len(unit_set) == 1 and "dt" in unit_set:
160164
return "dt"

test/python/compiler/test_transpiler.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,28 @@ def test_delay_converts_to_dt(self):
13721372
out = transpile(qc, dt=1e-9, seed_transpiler=42)
13731373
self.assertEqual(out.data[0].operation.unit, "dt")
13741374

1375+
def test_delay_converts_to_seconds(self):
1376+
"""Test that a delay instruction is converted to units of seconds when there is no dt."""
1377+
qc = QuantumCircuit(2)
1378+
qc.delay(1000, [0], unit="us")
1379+
qc.x(0)
1380+
1381+
# No backend
1382+
out = transpile([qc, qc], seed_transpiler=42)
1383+
self.assertEqual(out[0].data[0].operation.unit, "s")
1384+
self.assertEqual(out[1].data[0].operation.unit, "s")
1385+
self.assertEqual(out[0].data[0].operation.params[0], 1e-3)
1386+
self.assertEqual(out[1].data[0].operation.params[0], 1e-3)
1387+
1388+
# Backend without dt
1389+
backend = GenericBackendV2(num_qubits=4)
1390+
backend.target.dt = None
1391+
out = transpile([qc, qc], backend, seed_transpiler=42)
1392+
self.assertEqual(out[0].data[0].operation.unit, "s")
1393+
self.assertEqual(out[1].data[0].operation.unit, "s")
1394+
self.assertEqual(out[0].data[0].operation.params[0], 1e-3)
1395+
self.assertEqual(out[1].data[0].operation.params[0], 1e-3)
1396+
13751397
def test_delay_converts_expr_to_dt(self):
13761398
"""Test that a delay instruction with a duration expression of type Duration
13771399
is converted to units of dt given a backend."""
@@ -1513,6 +1535,21 @@ def test_rejects_negative_delay_expr(self):
15131535
seed_transpiler=42,
15141536
)
15151537

1538+
def test_rejects_mixed_units_delay_without_target_dt(self):
1539+
"""Test that delay instructions with SI and dt units are rejected without dt."""
1540+
qc = QuantumCircuit(2)
1541+
qc.delay(10, 1, unit="dt")
1542+
qc.delay(10, 1, unit="ns")
1543+
1544+
backend = GenericBackendV2(num_qubits=2)
1545+
backend.target.dt = None
1546+
with self.assertRaisesRegex(TranspilerError, ".*SI units and dt unit must not be mixed"):
1547+
transpile(
1548+
qc,
1549+
backend=backend,
1550+
seed_transpiler=42,
1551+
)
1552+
15161553
def test_rejects_mixed_units_delay_expr_without_target_dt(self):
15171554
"""Test that a delay instruction with wall time and cycles without target DT
15181555
is rejected."""

0 commit comments

Comments
 (0)