Add a new argument concurrent_measurements to target class (#10258)

* fix measure_v2

* modify measure_all

* dispatch backend

* add test of the builder with backendV2

* reconfigure test codes and some func

* refactoring

* add reno

* fix _measure_v2

* fix backend.meas_map in measure_v2

* fix reno

* delete get_qubit_channels from utils

* add get_qubits_channels in qubit_channels

* recostruct test about the builder with backendV2

* add meas_map to Target class

* fix after mergin main branch

* fix documents about meas_map

* format target.py

* add reno

* add meas_map to target in convert_to_target

* add the more description about meas_map

* Update releasenotes/notes/enable_target_aware_meas_map-0d8542402a74e9d8.yaml

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* fix test_meas_map

* remove format_meas_map

* rename meas_map in target to concurrent_measuments

* change reno

* remove Unused Union Dict

* concurrent_measurements set as getattr(configuration, meas_map)

* Update qiskit/transpiler/target.py

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* Update qiskit/transpiler/target.py

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* format

---------

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
This commit is contained in:
Kento Ueda 2023-07-20 09:15:50 +09:00 committed by GitHub
parent 722b452149
commit f492c450a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 5 deletions

View File

@ -70,7 +70,11 @@ def convert_to_target(
if filter_faulty:
faulty_qubits = set(properties.faulty_qubits())
qubit_properties = qubit_props_list_from_props(properties=properties)
target = Target(num_qubits=configuration.n_qubits, qubit_properties=qubit_properties)
target = Target(
num_qubits=configuration.n_qubits,
qubit_properties=qubit_properties,
concurrent_measurements=getattr(configuration, "meas_map", None),
)
# Parse instructions
gates: Dict[str, Any] = {}
for gate in properties.gates:
@ -122,7 +126,10 @@ def convert_to_target(
target.add_instruction(Measure(), measure_props)
# Parse from configuration because properties doesn't exist
else:
target = Target(num_qubits=configuration.n_qubits)
target = Target(
num_qubits=configuration.n_qubits,
concurrent_measurements=getattr(configuration, "meas_map", None),
)
for gate in configuration.gates:
name = gate.name
gate_props = (

View File

@ -43,7 +43,7 @@ def convert_to_target(conf_dict: dict, props_dict: dict = None, defs_dict: dict
qubit_props = None
if props_dict:
qubit_props = qubit_props_from_props(props_dict)
target = Target(qubit_properties=qubit_props)
target = Target(qubit_properties=qubit_props, concurrent_measurements=conf_dict.get("meas_map"))
# Parse from properties if it exsits
if props_dict is not None:
# Parse instructions

View File

@ -21,7 +21,7 @@ from __future__ import annotations
import itertools
from typing import Any
from typing import Optional, List, Any
from collections.abc import Mapping
from collections import defaultdict
import datetime
@ -239,6 +239,7 @@ class Target(Mapping):
"_non_global_strict_basis",
"qubit_properties",
"_global_operations",
"concurrent_measurements",
)
@deprecate_arg("aquire_alignment", new_alias="acquire_alignment", since="0.23.0")
@ -252,6 +253,7 @@ class Target(Mapping):
pulse_alignment=1,
acquire_alignment=1,
qubit_properties=None,
concurrent_measurements=None,
):
"""
Create a new Target object
@ -287,7 +289,9 @@ class Target(Mapping):
matches the qubit number the properties are defined for. If some
qubits don't have properties available you can set that entry to
``None``
Raises:
concurrent_measurements(list): A list of sets of qubits that must be
measured together. This must be provided
as a nested list like [[0, 1], [2, 3, 4]].
ValueError: If both ``num_qubits`` and ``qubit_properties`` are both
defined and the value of ``num_qubits`` differs from the length of
``qubit_properties``.
@ -322,6 +326,7 @@ class Target(Mapping):
"length of the input qubit_properties list"
)
self.qubit_properties = qubit_properties
self.concurrent_measurements = concurrent_measurements
def add_instruction(self, instruction, properties=None, name=None):
"""Add a new instruction to the :class:`~qiskit.transpiler.Target`
@ -1215,6 +1220,7 @@ class Target(Mapping):
inst_map: InstructionScheduleMap | None = None,
backend_properties: BackendProperties | None = None,
instruction_durations: InstructionDurations | None = None,
concurrent_measurements: Optional[List[List[int]]] = None,
dt: float | None = None,
timing_constraints: TimingConstraints | None = None,
custom_name_mapping: dict[str, Any] | None = None,
@ -1263,6 +1269,9 @@ class Target(Mapping):
instruction_durations: Optional instruction durations for instructions. If specified
it will take priority for setting the ``duration`` field in the
:class:`~InstructionProperties` objects for the instructions in the target.
concurrent_measurements(list): A list of sets of qubits that must be
measured together. This must be provided
as a nested list like [[0, 1], [2, 3, 4]].
dt: The system time resolution of input signals in seconds
timing_constraints: Optional timing constraints to include in the
:class:`~.Target`
@ -1306,6 +1315,7 @@ class Target(Mapping):
pulse_alignment=pulse_alignment,
acquire_alignment=acquire_alignment,
qubit_properties=qubit_properties,
concurrent_measurements=concurrent_measurements,
)
name_mapping = get_standard_gate_name_mapping()
if custom_name_mapping is not None:

View File

@ -0,0 +1,16 @@
---
features:
- |
Added :attr:`~.Target.concurrent_measurements` which represents a hardware constraint of qubits
measured concurrently. This constraint is provided in the nested list form,
in which each element represents qubit group to be measured together.
In an example below,
.. code-block:: python
[[0, 1], [2, 3, 4]]
qubits 0 and 1, and 2, 3 and 4 are measured together on the device.
This constraint doesn't block measuring an individual qubit,
however, Qiskit scheduler must consider the alignment of
measure operations for those qubits.

View File

@ -1903,6 +1903,15 @@ class TestTargetFromConfiguration(QiskitTestCase):
self.assertEqual(target.pulse_alignment, constraints.pulse_alignment)
self.assertEqual(target.acquire_alignment, constraints.acquire_alignment)
def test_concurrent_measurements(self):
fake_backend = FakeVigo()
config = fake_backend.configuration()
target = Target.from_configuration(
basis_gates=config.basis_gates,
concurrent_measurements=config.meas_map,
)
self.assertEqual(target.concurrent_measurements, config.meas_map)
def test_custom_basis_gates(self):
basis_gates = ["my_x", "cx"]
custom_name_mapping = {"my_x": XGate()}