Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix scheduling in control flow with instructions of non-uniform durations #1378

Merged
merged 10 commits into from
Feb 15, 2024
4 changes: 2 additions & 2 deletions qiskit_ibm_runtime/transpiler/passes/scheduling/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# Generate the main Qiskit transpile passes.
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
# Configure the as-late-as-possible scheduling pass
pm.scheduling = PassManager([ALAPScheduleAnalysis(durations), PadDelay()])
pm.scheduling = PassManager([ALAPScheduleAnalysis(durations), PadDelay(durations)])

qr = QuantumRegister(3)
crz = ClassicalRegister(1, name="crz")
Expand Down Expand Up @@ -162,7 +162,7 @@
[
ConvertConditionsToIfOps(),
ALAPScheduleAnalysis(durations),
PadDelay(),
PadDelay(durations),
]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def _get_node_duration(self, node: DAGNode) -> int:
cal_key = tuple(indices), tuple(float(p) for p in node.op.params)
duration = self._block_dag.calibrations[node.op.name][cal_key].duration
else:
duration = node.op.duration
duration = self._durations.get(node.op, indices, unit="dt")

if isinstance(duration, ParameterExpression):
raise TranspilerError(
Expand Down
10 changes: 9 additions & 1 deletion qiskit_ibm_runtime/transpiler/passes/scheduling/pad_delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from qiskit.circuit import Qubit
from qiskit.circuit.delay import Delay
from qiskit.dagcircuit import DAGNode, DAGOutNode
from qiskit.transpiler.instruction_durations import InstructionDurations

from .block_base_padder import BlockBasePadder

Expand Down Expand Up @@ -50,16 +51,23 @@ class PadDelay(BlockBasePadder):
See :class:`BlockBasePadder` pass for details.
"""

def __init__(self, fill_very_end: bool = True, schedule_idle_qubits: bool = False):
def __init__(
self,
durations: InstructionDurations,
fill_very_end: bool = True,
schedule_idle_qubits: bool = False,
):
"""Create new padding delay pass.

Args:
durations: Durations of instructions to be used in scheduling.
fill_very_end: Set ``True`` to fill the end of circuit with delay.
schedule_idle_qubits: Set to true if you'd like a delay inserted on idle qubits.
This is useful for timeline visualizations, but may cause issues for execution
on large backends.
"""
super().__init__(schedule_idle_qubits=schedule_idle_qubits)
self._durations = durations
self.fill_very_end = fill_very_end

def _pad(
Expand Down
3 changes: 2 additions & 1 deletion qiskit_ibm_runtime/transpiler/passes/scheduling/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ def _get_duration(self, node: DAGNode, dag: Optional[DAGCircuit] = None) -> int:
duration = dag.calibrations[node.op.name][cal_key].duration
node.op.duration = duration
else:
duration = node.op.duration
# map to outer dag to get the appropriate durations
duration = self._durations.get(node.op, indices, unit="dt")

if isinstance(duration, ParameterExpression):
raise TranspilerError(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
fixes:
- |
Fix assignment of instruction durations when scheduling circuits with
control flow. Prior to this fix, the indices for instructions on inner
blocks were not mapped to the physical indices in the outer dag.
other:
- |
The :class:`~InstructionDurations` `durations` input is now also required
for the constructor of :class:`~PadDelay`.
Loading
Loading