Skip to content

Commit

Permalink
Fix the output macros.measure with backendV2 (#10135) (#10241)
Browse files Browse the repository at this point in the history
* fix measure_v2

* modify measure_all

* fix meas_map input in measure_v2

* add reno

* fix reno

* Update reno.

Co-authored-by: Naoki Kanazawa <[email protected]>

* fix reno again

---------

Co-authored-by: Naoki Kanazawa <[email protected]>
(cherry picked from commit f911366)

Co-authored-by: Kento Ueda <[email protected]>
  • Loading branch information
mergify[bot] and to24toro authored Jun 7, 2023
1 parent 4d5f830 commit c3617e8
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 34 deletions.
22 changes: 8 additions & 14 deletions qiskit/pulse/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,11 @@ def measure(

# backend is V2.
if hasattr(backend, "target"):
try:
meas_map = backend.configuration().meas_map
except AttributeError:
# TODO add meas_map to Target in 0.25
meas_map = [list(range(backend.num_qubits))]

return _measure_v2(
qubits=qubits,
target=backend.target,
meas_map=meas_map,
meas_map=meas_map or backend.meas_map,
qubit_mem_slots=qubit_mem_slots or dict(zip(qubits, range(len(qubits)))),
measure_name=measure_name,
)
Expand Down Expand Up @@ -198,20 +193,14 @@ def _measure_v2(
channels.AcquireChannel(measure_qubit),
]
)
else:
default_sched = target.get_calibration(measure_name, (measure_qubit,)).filter(
channels=[
channels.AcquireChannel(measure_qubit),
]
)
schedule += _schedule_remapping_memory_slot(default_sched, qubit_mem_slots)
except KeyError as ex:
raise exceptions.PulseError(
"We could not find a default measurement schedule called '{}'. "
"Please provide another name using the 'measure_name' keyword "
"argument. For assistance, the instructions which are defined are: "
"{}".format(measure_name, target.instructions)
) from ex
schedule += _schedule_remapping_memory_slot(default_sched, qubit_mem_slots)
return schedule


Expand All @@ -226,7 +215,12 @@ def measure_all(backend) -> Schedule:
Returns:
A schedule corresponding to the inputs provided.
"""
return measure(qubits=list(range(backend.configuration().n_qubits)), backend=backend)
# backend is V2.
if hasattr(backend, "target"):
qubits = list(range(backend.num_qubits))
else:
qubits = list(range(backend.configuration().n_qubits))
return measure(qubits=qubits, backend=backend)


def _schedule_remapping_memory_slot(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
fixes:
- |
Fixed the output of pulse :func:`~qiskit.pulse.macros.measure` and
:func:`~qiskit.pulse.macros.measure_all` when functions are called
with the :class:`.BackendV2` backend.
92 changes: 72 additions & 20 deletions test/python/pulse/test_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
)
from qiskit.pulse import macros
from qiskit.pulse.exceptions import PulseError
from qiskit.providers.fake_provider import FakeOpenPulse2Q, FakeHanoiV2
from qiskit.providers.fake_provider import FakeOpenPulse2Q, FakeHanoi, FakeHanoiV2
from qiskit.test import QiskitTestCase


Expand Down Expand Up @@ -95,13 +95,8 @@ def test_measure_v2(self):
"""Test macro - measure with backendV2."""
sched = macros.measure(qubits=[0], backend=self.backend_v2)
expected = self.backend_v2.target.get_calibration("measure", (0,)).filter(
channels=[
MeasureChannel(0),
]
channels=[MeasureChannel(0), AcquireChannel(0)]
)
measure_duration = expected.filter(instruction_types=[Play]).duration
for qubit in range(self.backend_v2.num_qubits):
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(qubit))
self.assertEqual(sched.instructions, expected.instructions)

def test_measure_v2_sched_with_qubit_mem_slots(self):
Expand All @@ -113,15 +108,7 @@ def test_measure_v2_sched_with_qubit_mem_slots(self):
]
)
measure_duration = expected.filter(instruction_types=[Play]).duration
for qubit in range(self.backend_v2.num_qubits):
if qubit == 0:
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(2))
elif qubit == 1:
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(0))
elif qubit == 2:
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(1))
else:
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(qubit))
expected += Acquire(measure_duration, AcquireChannel(0), MemorySlot(2))
self.assertEqual(sched.instructions, expected.instructions)

def test_measure_v2_sched_with_meas_map(self):
Expand All @@ -138,8 +125,7 @@ def test_measure_v2_sched_with_meas_map(self):
]
)
measure_duration = expected.filter(instruction_types=[Play]).duration
for qubit in range(self.backend_v2.num_qubits):
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(qubit))
expected += Acquire(measure_duration, AcquireChannel(0), MemorySlot(0))
self.assertEqual(sched_with_meas_map_list.instructions, expected.instructions)
self.assertEqual(sched_with_meas_map_dict.instructions, expected.instructions)

Expand All @@ -159,21 +145,87 @@ def test_multiple_measure_v2(self):
measure_duration = expected.filter(instruction_types=[Play]).duration
expected += Acquire(measure_duration, AcquireChannel(0), MemorySlot(0))
expected += Acquire(measure_duration, AcquireChannel(1), MemorySlot(1))
for qubit in range(2, self.backend_v2.num_qubits):
expected += Acquire(measure_duration, AcquireChannel(qubit), MemorySlot(qubit))
self.assertEqual(sched.instructions, expected.instructions)

def test_output_with_measure_v1_and_measure_v2(self):
"""Test make outputs of measure_v1 and measure_v2 consistent."""
sched_measure_v1 = macros.measure(qubits=[0, 1], backend=FakeHanoi())
sched_measure_v2 = macros.measure(qubits=[0, 1], backend=self.backend_v2)
self.assertEqual(sched_measure_v1.instructions, sched_measure_v2.instructions)

def test_output_with_measure_v1_and_measure_v2_sched_with_qubit_mem_slots(self):
"""Test make outputs of measure_v1 and measure_v2 with custom qubit_mem_slots consistent."""
sched_measure_v1 = macros.measure(qubits=[0], backend=FakeHanoi(), qubit_mem_slots={0: 2})
sched_measure_v2 = macros.measure(
qubits=[0], backend=self.backend_v2, qubit_mem_slots={0: 2}
)
self.assertEqual(sched_measure_v1.instructions, sched_measure_v2.instructions)

def test_output_with_measure_v1_and_measure_v2_sched_with_meas_map(self):
"""Test make outputs of measure_v1 and measure_v2
with custom meas_map as list and dict consistent."""
num_qubits_list_measure_v1 = list(range(FakeHanoi().configuration().num_qubits))
num_qubits_list_measure_v2 = list(range(self.backend_v2.num_qubits))
sched_with_meas_map_list_v1 = macros.measure(
qubits=[0], backend=FakeHanoi(), meas_map=[num_qubits_list_measure_v1]
)
sched_with_meas_map_dict_v1 = macros.measure(
qubits=[0],
backend=FakeHanoi(),
meas_map={0: num_qubits_list_measure_v1, 1: num_qubits_list_measure_v1},
)
sched_with_meas_map_list_v2 = macros.measure(
qubits=[0], backend=self.backend_v2, meas_map=[num_qubits_list_measure_v2]
)
sched_with_meas_map_dict_v2 = macros.measure(
qubits=[0],
backend=self.backend_v2,
meas_map={0: num_qubits_list_measure_v2, 1: num_qubits_list_measure_v2},
)
self.assertEqual(
sched_with_meas_map_list_v1.instructions,
sched_with_meas_map_list_v2.instructions,
)
self.assertEqual(
sched_with_meas_map_dict_v1.instructions,
sched_with_meas_map_dict_v2.instructions,
)

def test_output_with_multiple_measure_v1_and_measure_v2(self):
"""Test macro - consistent output of multiple qubit measure with backendV1 and backendV2."""
sched_measure_v1 = macros.measure(qubits=[0, 1], backend=FakeHanoi())
sched_measure_v2 = macros.measure(qubits=[0, 1], backend=self.backend_v2)
self.assertEqual(sched_measure_v1.instructions, sched_measure_v2.instructions)


class TestMeasureAll(QiskitTestCase):
"""Pulse measure all macro."""

def setUp(self):
super().setUp()
self.backend = FakeOpenPulse2Q()
self.backend_v2 = FakeHanoiV2()
self.inst_map = self.backend.defaults().instruction_schedule_map

def test_measure_all(self):
"""Test measure_all function."""
sched = macros.measure_all(self.backend)
expected = Schedule(self.inst_map.get("measure", [0, 1]))
self.assertEqual(sched.instructions, expected.instructions)

def test_measure_all_v2(self):
"""Test measure_all function with backendV2."""
backend_v1 = FakeHanoi()
sched = macros.measure_all(self.backend_v2)
expected = Schedule(
backend_v1.defaults().instruction_schedule_map.get(
"measure", list(range(backend_v1.configuration().num_qubits))
)
)
self.assertEqual(sched.instructions, expected.instructions)

def test_output_of_measure_all_with_backend_v1_and_v2(self):
"""Test make outputs of measure_all with backendV1 and backendV2 consistent."""
sched_measure_v1 = macros.measure_all(backend=FakeHanoi())
sched_measure_v2 = macros.measure_all(backend=self.backend_v2)
self.assertEqual(sched_measure_v1.instructions, sched_measure_v2.instructions)

0 comments on commit c3617e8

Please sign in to comment.