Fix ConstrainedReschedule Rust port giving wrong node_start_time (#16186)#16210
Draft
bnayahu wants to merge 2 commits into
Draft
Fix ConstrainedReschedule Rust port giving wrong node_start_time (#16186)#16210bnayahu wants to merge 2 commits into
bnayahu wants to merge 2 commits into
Conversation
338a38a to
7b6af51
Compare
…kit#16186) Three bugs in the Rust port of `ConstrainedReschedule` (PR Qiskit#14883): 1. **Delay duration ignored when `target` is provided**: `push_node_back` computed `new_t1q` using `target.get_duration("delay", …)`, which returns `None` → `0` because Delay is not in the target gate table. The Delay end-time was therefore `this_t0 + 0` instead of `this_t0 + delay_duration`, causing a u64 underflow in the successor overlap calculation and silently setting the measure start time to a wrapped garbage value (160 dt instead of 272 dt). Fixed by always reading Delay duration from the instruction parameter first, falling back to the target only for non-Delay ops. 2. **`pulse_align`/`acquire_align` swapped in the `push_node_back` call**: `run_constrained_reschedule` passed the two alignment arguments in the wrong order. As a result `acquire_align` inside `push_node_back` received the pulse alignment value (1) and Measure/Reset were never shifted to the correct acquire-alignment boundary. Fixed by correcting the argument order. 3. **u64 underflow in overlap arithmetic**: `new_t1q - next_t0q` and `t1c - t0c` used plain subtraction; when the current node ends before the successor starts (no real overlap) this wraps to a large value and incorrectly shifts successors. Changed to `saturating_sub`. Also adds `is_measure_or_reset()` helper to consolidate the three Measure/Reset checks and to handle Python-level Measure/Reset operations (stored as `OperationRef::Instruction`) that do not match the `StandardInstruction::Measure/Reset` pattern. Adds regression tests in `test_scheduling_padding_pass.py`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8ada766 to
ca90988
Compare
gkneighb
added a commit
to gkneighb/qiskit
that referenced
this pull request
May 22, 2026
- Reno: adopt @jakelishman's shorter suggested wording. - Test: trim the long docstring (git holds the rest). - Test: replace the implicit "doesn't raise" assertion with a positive assertion that the alignment-only path returns the expected node_start_time for an already-aligned circuit. The shifted-alignment behaviour is tracked separately in Qiskit#16186 / Qiskit#16210, so this PR's test exercises the no-shift case. - Test: add the Claude Opus 4.7 attribution comment per the LLM policy discussion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: #16186.
Three bugs in the Rust port of
ConstrainedReschedule(PR #14883):Delay duration ignored when
targetis provided:push_node_backcomputednew_t1qusingtarget.get_duration("delay", …), which returnsNone→0because Delay is not in the target gate table. The Delay end-time was thereforethis_t0 + 0instead ofthis_t0 + delay_duration, causing a u64 underflow in the successor overlap calculation and silently setting the measure start time to a wrapped garbage value (160 dt instead of 272 dt). Fixed by always reading Delay duration from the instruction parameter first, falling back to the target only for non-Delay ops.pulse_align/acquire_alignswapped in thepush_node_backcall:run_constrained_reschedulepassed the two alignment arguments in the wrong order. As a resultacquire_aligninsidepush_node_backreceived the pulse alignment value (1) and Measure/Reset were never shifted to the correct acquire-alignment boundary. Fixed by correcting the argument order.u64 underflow in overlap arithmetic:
new_t1q - next_t0qandt1c - t0cused plain subtraction; when the current node ends before the successor starts (no real overlap) this wraps to a large value and incorrectly shifts successors. Changed tosaturating_sub.Also adds
is_measure_or_reset()helper to consolidate the three Measure/Reset checks and to handle Python-level Measure/Reset operations (stored asOperationRef::Instruction) that do not match theStandardInstruction::Measure/Resetpattern.Adds regression tests in
test_scheduling_padding_pass.py.AI/LLM disclosure