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

Dispatch a builder with backendV1 and backendV2 #10150

Merged
merged 25 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6a3b145
fix measure_v2
to24toro May 22, 2023
3cd1192
modify measure_all
to24toro May 23, 2023
58023f5
dispatch backend
to24toro May 23, 2023
93a9262
add test of the builder with backendV2
to24toro May 24, 2023
2cc5451
reconfigure test codes and some func
to24toro May 26, 2023
a21cc84
refactoring
to24toro May 26, 2023
b3607ee
add reno
to24toro May 31, 2023
bd1e169
fix _measure_v2
to24toro May 31, 2023
d70796f
fix backend.meas_map in measure_v2
to24toro May 31, 2023
2a651dd
fix reno
to24toro May 31, 2023
8d92531
delete get_qubit_channels from utils
to24toro Jun 5, 2023
9b2b80d
add get_qubits_channels in qubit_channels
to24toro Jun 5, 2023
891c1bd
recostruct test about the builder with backendV2
to24toro Jun 5, 2023
1d3b471
Merge branch 'main' into feature/dispatch_backend
to24toro Jun 5, 2023
a6363c3
fix descriptions of test_macros
to24toro Jun 5, 2023
3aeba17
fix descriptions of test_macros again
to24toro Jun 7, 2023
f3127df
Merge branch 'main' into feature/dispatch_backend
to24toro Jun 7, 2023
9fee85e
delete import of backendV2 in utils
to24toro Jun 7, 2023
c8d13f5
revert no need to modify code
to24toro Jun 7, 2023
fecdcae
Update releasenotes/notes/fix-dispatching-backends-28aff96f726ca9c5.yaml
to24toro Jun 7, 2023
f0ee72f
Merge remote-tracking branch 'origin/feature/dispatch_backend' into f…
to24toro Jun 7, 2023
c7a36dc
Update a commnet in qiskit/pulse/builder.py
to24toro Jun 7, 2023
117931d
Merge branch 'main' into feature/dispatch_backend
to24toro Jun 7, 2023
817d04a
remove import TYPE_CHECKING
to24toro Jun 7, 2023
0e204eb
removed test_builder.py utils.py and test_analyzation.py from pull re…
to24toro Jun 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions qiskit/pulse/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@
library,
transforms,
)
from qiskit.providers.backend import BackendV2
from qiskit.pulse.instructions import directives
from qiskit.pulse.schedule import Schedule, ScheduleBlock
from qiskit.pulse.transforms.alignments import AlignmentKind
Expand Down Expand Up @@ -677,6 +678,9 @@ def get_context(self) -> ScheduleBlock:
@_requires_backend
def num_qubits(self):
"""Get the number of qubits in the backend."""
# backendV2
if isinstance(self.backend, BackendV2):
return self.backend.num_qubits
return self.backend.configuration().n_qubits

@property
Expand Down Expand Up @@ -1105,6 +1109,8 @@ def num_qubits() -> int:

.. note:: Requires the active builder context to have a backend set.
"""
if isinstance(active_backend(), BackendV2):
return active_backend().num_qubits
return active_backend().configuration().n_qubits


Expand All @@ -1120,6 +1126,12 @@ def seconds_to_samples(seconds: Union[float, np.ndarray]) -> Union[int, np.ndarr
Returns:
The number of samples for the time to elapse
"""
# backendV2
if isinstance(active_backend(), BackendV2):
if isinstance(seconds, np.ndarray):
return (seconds / active_backend().dt).astype(int)
else:
return int(seconds / active_backend().dt)
if isinstance(seconds, np.ndarray):
return (seconds / active_backend().configuration().dt).astype(int)
return int(seconds / active_backend().configuration().dt)
Expand All @@ -1135,6 +1147,9 @@ def samples_to_seconds(samples: Union[int, np.ndarray]) -> Union[float, np.ndarr
Returns:
The time that elapses in ``samples``.
"""
# backendV2
if isinstance(active_backend(), BackendV2):
return samples * active_backend().dt
return samples * active_backend().configuration().dt


Expand Down Expand Up @@ -1163,6 +1178,31 @@ def qubit_channels(qubit: int) -> Set[chans.Channel]:
such as in the case where significant crosstalk exists.

"""

# implement as the inner function to avoid API change for a patch release in 0.24.2.
def get_qubit_channels_v2(backend: BackendV2, qubit: int):
r"""Return a list of channels which operate on the given ``qubit``.
Returns:
List of ``Channel``\s operated on my the given ``qubit``.
"""
channels = []

# add multi-qubit channels
for node_qubits in backend.coupling_map:
if qubit in node_qubits:
control_channel = backend.control_channel(node_qubits)
if control_channel:
channels.extend(control_channel)

# add single qubit channels
channels.append(backend.drive_channel(qubit))
channels.append(backend.measure_channel(qubit))
channels.append(backend.acquire_channel(qubit))
return channels

# backendV2
if isinstance(active_backend(), BackendV2):
return set(get_qubit_channels_v2(active_backend(), qubit))
return set(active_backend().configuration().get_qubit_channels(qubit))


Expand Down Expand Up @@ -1648,7 +1688,11 @@ def frequency_offset(
finally:
if compensate_phase:
duration = builder.get_context().duration - t0
dt = active_backend().configuration().dt
# backendV2
if isinstance(active_backend(), BackendV2):
dt = active_backend().dt
else:
dt = active_backend().configuration().dt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this logic to get dt everywhere in this file. This is of course not the scope of this PR, but could you please add new builder command to get backend dt in 0.25 for cleanup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to add like below?

def get_dt_from_backend(backend):
  if isinstance(backend. backendV2):
    return backend.dt
  else:
    return backend.configuration().dt

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in the followup PR for 0.25. I think this makes some logic cleaner.

accumulated_phase = 2 * np.pi * ((duration * dt * frequency) % 1)
for channel in channels:
shift_phase(-accumulated_phase, channel)
Expand All @@ -1675,6 +1719,9 @@ def drive_channel(qubit: int) -> chans.DriveChannel:

.. note:: Requires the active builder context to have a backend set.
"""
# backendV2
if isinstance(active_backend(), BackendV2):
return active_backend().drive_channel(qubit)
return active_backend().configuration().drive(qubit)


Expand All @@ -1695,6 +1742,9 @@ def measure_channel(qubit: int) -> chans.MeasureChannel:

.. note:: Requires the active builder context to have a backend set.
"""
# backendV2
if isinstance(active_backend(), BackendV2):
return active_backend().measure_channel(qubit)
return active_backend().configuration().measure(qubit)


Expand All @@ -1715,6 +1765,9 @@ def acquire_channel(qubit: int) -> chans.AcquireChannel:

.. note:: Requires the active builder context to have a backend set.
"""
# backendV2
if isinstance(active_backend(), BackendV2):
return active_backend().acquire_channel(qubit)
return active_backend().configuration().acquire(qubit)


Expand Down Expand Up @@ -1745,6 +1798,9 @@ def control_channels(*qubits: Iterable[int]) -> List[chans.ControlChannel]:
List of control channels associated with the supplied ordered list
of qubits.
"""
# backendV2
if isinstance(active_backend(), BackendV2):
return active_backend().control_channel(qubits)
return active_backend().configuration().control(qubits=qubits)


Expand Down Expand Up @@ -2428,11 +2484,9 @@ def measure(
registers = list(registers)
except TypeError:
registers = [registers]

measure_sched = macros.measure(
qubits=qubits,
inst_map=backend.defaults().instruction_schedule_map,
meas_map=backend.configuration().meas_map,
backend=backend,
to24toro marked this conversation as resolved.
Show resolved Hide resolved
qubit_mem_slots={qubit: register.index for qubit, register in zip(qubits, registers)},
)

Expand Down Expand Up @@ -2478,10 +2532,10 @@ def measure_all() -> List[chans.MemorySlot]:
backend = active_backend()
qubits = range(num_qubits())
registers = [chans.MemorySlot(qubit) for qubit in qubits]

measure_sched = macros.measure(
qubits=qubits,
inst_map=backend.defaults().instruction_schedule_map,
meas_map=backend.configuration().meas_map,
backend=backend,
qubit_mem_slots={qubit: qubit for qubit in qubits},
)

Expand Down
5 changes: 3 additions & 2 deletions qiskit/pulse/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from qiskit.pulse import channels, exceptions, instructions, utils
from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap
from qiskit.pulse.schedule import Schedule
from qiskit.providers.backend import BackendV2


if TYPE_CHECKING:
Expand Down Expand Up @@ -62,7 +63,7 @@ def measure(
"""

# backend is V2.
if hasattr(backend, "target"):
if isinstance(backend, BackendV2):

return _measure_v2(
qubits=qubits,
Expand Down Expand Up @@ -216,7 +217,7 @@ def measure_all(backend) -> Schedule:
A schedule corresponding to the inputs provided.
"""
# backend is V2.
if hasattr(backend, "target"):
if isinstance(backend, BackendV2):
qubits = list(range(backend.num_qubits))
else:
qubits = list(range(backend.configuration().n_qubits))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
fixes:
- |
Fixed an failure of the pulse builder when the context is initialized with :class:`.BackendV2`.
Loading