-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
[WIP] Solve a bug of scheduling with backendV2 #9912
Conversation
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the the following people are requested to review this:
|
qiskit/pulse/macros.py
Outdated
if backend is None or hasattr(backend, "target"): | ||
if target is None: | ||
target = backend.target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the logic here is problematic.
If you provide as arguments inst_map
and meas_map
, the macro has all the information it needs, but the condition here will raise the exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
qiskit/pulse/macros.py
Outdated
"inst_map or meas_map, and backend cannot be None simultaneously" | ||
) from ex | ||
if isinstance(meas_map, list): | ||
meas_map = utils.format_meas_map(meas_map) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you integrate this into MeasureGrouping
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is used in only _measure_v1. So I think that it is no necessary to move into MeasureGrouping
.
qiskit/pulse/macros.py
Outdated
def measure_v2( | ||
qubits: List[int], | ||
backend=None, | ||
target: Optional[Target] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can reduce backend
and target
by formatting the arguments in measure
function before dispatching the logic. Please keep interface minimum for maintainability. Same for v1.
qiskit/pulse/macros.py
Outdated
measure_groups.add(tuple(meas_map[qubit])) | ||
for measure_group_qubits in measure_groups: | ||
try: | ||
default_sched = target.get_calibration(measure_name, measure_group_qubits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work because Target
has calibration for single qubit (because attached Measure
class is single qubit operation). Here, you need to iterate over all qubits in the group and combine them.
Also, I have been wondering if grouping is really needed without constraints. For example, if you combine meas calibration for group of [0, 1] and [2, 3], this will eventually generate a left-aligned block of [0, 1, 2, 3]. I think we just need to combine them without considering the grouping, as long as backend meas map doesn't provide constraint. Probably, we need to pad non-measured qubit timeslot in the group with delays (so that they don't cause overlap within the group). Any thoughts @wshanks ?
qiskit/pulse/macros.py
Outdated
@@ -104,3 +189,21 @@ def measure_all(backend) -> Schedule: | |||
A schedule corresponding to the inputs provided. | |||
""" | |||
return measure(qubits=list(range(backend.configuration().n_qubits)), backend=backend) | |||
|
|||
|
|||
def combine_schedules(qubits: List, schedule: Schedule, default_schedule: Union[Schedule, ScheduleBlock],measure_group_qubits: List, qubit_mem_slots: Optional[Dict[int, int]] = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a function remap_memory_slot(schedule: Schedule, qubit_mem_slots: Dict[int, int]) -> Schedule
because it seems just replacing the slot index. @TsafrirA does it help creg index matching? Let us know if you have other ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I change the code at 509392a
qiskit/pulse/macros.py
Outdated
if hasattr(backend, "target"): | ||
return measure_v2(qubits, backend, target, meas_map, qubit_mem_slots, measure_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if hasattr(backend, "target"): | |
return measure_v2(qubits, backend, target, meas_map, qubit_mem_slots, measure_name) | |
if target or hasattr(backend, "target"): | |
return measure_v2( | |
qubits=qubits, | |
target=target or backend.target, | |
meas_map=meas_map or getattr(backend, "meas_map", MeasureGrouping()), | |
qubit_mem_slots=qubit_mem_slots, | |
measure_name=measure_name, | |
) |
Note that backend is optional here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I change the code at 509392a
qiskit/transpiler/target.py
Outdated
@@ -1045,6 +1048,10 @@ def build_coupling_map(self, two_q_gate=None): | |||
else: | |||
return None | |||
|
|||
def add_measuregrouping(self, meas_map=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can update the constructor of Target
with meas_map (because this is hardware constraints and user cannot modify once it's set). Then store it as a protected member and provide only property method for it so that user cannot override.
@@ -16,12 +16,14 @@ | |||
|
|||
from qiskit.pulse import channels, exceptions, instructions, utils | |||
from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap | |||
from qiskit.pulse.schedule import Schedule | |||
from qiskit.pulse.schedule import Schedule, ScheduleBlock | |||
from qiskit.transpiler.target import Target | |||
|
|||
|
|||
def measure( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you start pending deprecation for inst_map
and V1 backend? We have a convenient decorator now:
https://github.com/Qiskit/qiskit-terra/blob/58aceb59e9bc1e16f29b09402e1984b16d211da3/qiskit/utils/deprecation.py#L100-L111
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I move deprecate_arg
part to _measure_v1
?
qiskit/transpiler/measuregrouping.py
Outdated
""" | ||
Gets qubit groups including at least one qubit of `qubits` from meas_map. | ||
""" | ||
return [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For backward compatibility, you need to add case for self.meas_map = None
. I think, in this case, you just need to return input qubits as-is (because no grouping constraint is applied).
5da678c
to
509392a
Compare
qiskit/pulse/macros.py
Outdated
from qiskit.transpiler.target import Target | ||
from qiskit.utils.deprecation import deprecate_arg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that this import statement causes a circular import, so we need to resolve it.
qiskit/pulse/macros.py
Outdated
if meas_map is not None: | ||
if meas_map is Dict: | ||
pass | ||
else: | ||
pass | ||
|
||
meas_map = target.meas_map.get_qubit_groups(qubits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In _measure_v2, meas_map
is assumed to be a List. For example, the conventional meas_map
= [[1, 2], [2, 3, 4]] will be converted to [1, 2, 3, 4].
If meas_map
is None
as input, you can obtain a List like [1, 2, 3, 4] from meas_map = target.meas_map.get_qubit_groups(qubits)
.
However, processing for Dict and List[List] types of meas_map has not been implemented yet.
I would like to know what would be the best way to handle Dict and List[List] types of meas_map.
qiskit/transpiler/target.py
Outdated
@@ -315,6 +319,7 @@ def __init__( | |||
"length of the input qubit_properties list" | |||
) | |||
self.qubit_properties = qubit_properties | |||
self._meas_group = MeasureGrouping(meas_group) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I defined MeasureGrouping
in meas_group
. I named as meas_group
because meas_map
exists in MeasureGrouping
. I would like to know if the naming is reasonable.
f89279e
to
5977d0f
Compare
macros.py target delete raise statement in measure_v2 modify instructions.Acquire to Acquire
5977d0f
to
5930369
Compare
I would like to re-submit a PR to organize it again. See #10105. |
Summary
Based on the comment,
I added a new class
MeasureGrouping
. It is assumed to be called bytarget.meas_map
.Using this class, we can become to create scheduling for quantum circuits dynamically.
This PR includes
MeasureGrouping
.macros.measure
.Details and comments
fix #9488
Solving this issue leads to working on #9420.
[TODO]
get_qubit_groups
inMeasureGrouping
.inst_schedule_map
.MeasureGrouping
when createTarget
class in backendV2.add_measuregrouping
to qiskit_ibm_provider/backend_converter.py