Transpiling `Delay` without a scheduling_method raises `TranspilerError`
See original GitHub issueEnvironment
- Qiskit Terra version: 0.23.0.dev0+c34e0b9
- Python version: 3.7
- Operating system: osx 11.7
What is happening?
For any circuit including a Delay
operation, transpiling that circuit for a backend with non-null TimingConstraints
will raise a TranaspilerError
that is not user something the user can take action on.
How can we reproduce the issue?
>>> qc = qk.QuantumCircuit(1)
>>> qc.x(0)
>>> qc.delay(0.123, 0, 'us')
>>> qc.x(0)
>>> qc.draw()
ββββββββββββββββββββββββββββββ
q: β€ X ββ€ Delay(0.123[us]) ββ€ X β
ββββββββββββββββββββββββββββββ
>>> provider.get_backend('ibmq_belem').configuration().timing_constraints
{'acquire_alignment': 16, 'granularity': 16, 'min_length': 64, 'pulse_alignment': 1}
>>> qk.transpile(qc, provider.get_backend('ibmq_belem'))
/Users/kdk/q/qiskit-terra/qiskit/circuit/duration.py:40: UserWarning: Duration is rounded to 554 [dt] = 1.231111e-07 [s] from 1.230000e-07 [s]
UserWarning,
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/kdk/q/qiskit-terra/qiskit/compiler/transpiler.py", line 389, in transpile
transpile_config["pass_manager_config"].backend_properties,
File "/Users/kdk/q/qiskit-terra/qiskit/compiler/transpiler.py", line 475, in _serial_transpile_circuit
result = pass_manager.run(circuit, callback=callback, output_name=output_name)
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/passmanager.py", line 528, in run
return super().run(circuits, output_name, callback)
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/passmanager.py", line 228, in run
return self._run_single_circuit(circuits, output_name, callback)
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/passmanager.py", line 283, in _run_single_circuit
result = running_passmanager.run(circuit, output_name=output_name, callback=callback)
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/runningpassmanager.py", line 125, in run
dag = self._do_pass(pass_, dag, passset.options)
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/runningpassmanager.py", line 172, in _do_pass
dag = self._run_this_pass(pass_, dag)
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/runningpassmanager.py", line 226, in _run_this_pass
pass_.run(FencedDAGCircuit(dag))
File "/Users/kdk/q/qiskit-terra/qiskit/transpiler/passes/scheduling/alignments/reschedule.py", line 207, in run
f"The input circuit {dag.name} is not scheduled. Call one of scheduling passes "
qiskit.transpiler.exceptions.TranspilerError: 'The input circuit None is not scheduled. Call one of scheduling passes before running the ConstrainedReschedule pass.'
What should happen?
Itβs not clear to me that the ConstrainedReschedule
pass needs to be called in this case. In particular, it should be possible for users to use both Delay
instructions and rely on backend scheduling (so not needing to specify a scheduling_method
).
Converting the Delay
operations to units of dt
should be sufficient for it to be executable by a backend. The TimeUnitConversion
pass currently handles this conversion, but does not appear to look at timing_constraints
.
If ConstrainedReschedule
is decided to be needed, the error message should guide users that they need to specify a scheduling_method
in order to use Delay
s.
Any suggestions?
No response
Issue Analytics
- State:
- Created a year ago
- Comments:5 (5 by maintainers)
Top GitHub Comments
Thanks both, I think this raises some interesting questions.
This is true, the example above is probably oversimplified, but I think the same question could be asked of >=2Q circuits, should the presence of a
delay
always be sufficient to trigger rescheduling?I believe this is true if we expect
delay
instruction to result in an idle period of exactly some duration within the circuit, but not if they are expected to generate an idle period of at least some duration within the circuit (e.g., if they are equivalent to an 0-amplitude pulse gate of the same duration, which may be pushed around as needed by the scheduler). I havenβt seen anywhere where itβs specified which of these two behaviors users should expect.The two open questions I see at the moment are:
delay
instruction in the circuit imply an idle period of exactly the duration of thatdelay
, or of at least the duration of thatdelay
? (My leaning is toward the latter, because the former introduces the possibility of the user building a circuit with unresolvable constraints.)delay
durations into units ofdt
, we currently round to the nearest multiple ofdt
. Should we also round to the nearest multiple oftiming_constraints.{pulse,aquire}_alignment
so that scheduling can be avoided in these cases?Current timing constraints and rescheduling strategy come from IBM devices. AWG there requires a chunk of 16 samples per clock (i.e. 1 clock is 16 dt), thus instruction and acquisition must placed at t0 which is multiple of this chunk size (old devices can place instructions at arbitrary t0 though). This means, given IBM device,
This will never happen, i.e. even if we use pulse gate, that instruction duration must be multiple of the chunk size and it automatically satisfies other constraints. However this model is too much tied to our architecture, and we must define some generic model for constraints (this is why itβs not written in Qiskit). In IBM device, instruction with timing violation yields error, and acquisition with violation yields broken output due to frame offset. So truncating the delay duration into the LCM of all constraint values always give you executable circuit. This is what we are doing in Qiskit Experiments.
Depends on context. If you write circuit in target-agnostic way this is exact duration. Qiskit doesnβt distinguish logical/virtual/physical circuits. IMO this is where these confusions come.
I think this is the reasonable solution. Invoking schedule/reschedule pass is kind of overkill. As @taalexander mentioned, scheduled circuit doesnβt ALWAYS guarantee actual instruction time across measurement and conditional operation. In your example circuit above, we can expect consistency between frontend and backend.