qiskit 1.1.0rc1__cp38-abi3-win_amd64.whl → 1.1.1__cp38-abi3-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/_accelerate.pyd +0 -0
  3. qiskit/assembler/__init__.py +5 -10
  4. qiskit/circuit/__init__.py +21 -153
  5. qiskit/circuit/_classical_resource_map.py +3 -0
  6. qiskit/circuit/classical/expr/__init__.py +1 -1
  7. qiskit/circuit/classical/types/__init__.py +5 -4
  8. qiskit/circuit/classicalfunction/__init__.py +1 -0
  9. qiskit/circuit/library/__init__.py +3 -19
  10. qiskit/circuit/library/data_preparation/pauli_feature_map.py +1 -1
  11. qiskit/circuit/library/n_local/two_local.py +1 -1
  12. qiskit/circuit/parameterexpression.py +3 -0
  13. qiskit/circuit/parametervector.py +22 -16
  14. qiskit/circuit/quantumcircuit.py +1098 -200
  15. qiskit/converters/__init__.py +17 -2
  16. qiskit/dagcircuit/dagcircuit.py +1 -1
  17. qiskit/passmanager/passmanager.py +11 -11
  18. qiskit/primitives/__init__.py +15 -9
  19. qiskit/primitives/containers/__init__.py +1 -0
  20. qiskit/primitives/containers/bit_array.py +1 -0
  21. qiskit/primitives/containers/shape.py +3 -3
  22. qiskit/providers/__init__.py +49 -17
  23. qiskit/providers/backend.py +0 -6
  24. qiskit/providers/basic_provider/__init__.py +2 -23
  25. qiskit/providers/fake_provider/__init__.py +1 -1
  26. qiskit/providers/models/__init__.py +2 -2
  27. qiskit/pulse/builder.py +2 -2
  28. qiskit/qasm2/parse.py +8 -0
  29. qiskit/qasm3/exporter.py +2 -2
  30. qiskit/qobj/converters/pulse_instruction.py +6 -6
  31. qiskit/qpy/__init__.py +60 -62
  32. qiskit/qpy/binary_io/value.py +1 -1
  33. qiskit/quantum_info/operators/symplectic/pauli.py +7 -4
  34. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +8 -4
  35. qiskit/result/__init__.py +6 -0
  36. qiskit/scheduler/__init__.py +10 -1
  37. qiskit/scheduler/methods/__init__.py +1 -8
  38. qiskit/synthesis/__init__.py +1 -6
  39. qiskit/transpiler/passes/__init__.py +4 -2
  40. qiskit/transpiler/passes/basis/basis_translator.py +2 -2
  41. qiskit/transpiler/passes/layout/vf2_layout.py +10 -4
  42. qiskit/transpiler/passes/layout/vf2_utils.py +2 -2
  43. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  44. qiskit/transpiler/passes/routing/star_prerouting.py +5 -5
  45. qiskit/transpiler/preset_passmanagers/__init__.py +27 -1
  46. qiskit/transpiler/target.py +1 -1
  47. qiskit/utils/__init__.py +3 -2
  48. qiskit/utils/parallel.py +24 -15
  49. qiskit/visualization/gate_map.py +9 -1
  50. qiskit/visualization/pulse_v2/device_info.py +58 -31
  51. {qiskit-1.1.0rc1.dist-info → qiskit-1.1.1.dist-info}/METADATA +1 -1
  52. {qiskit-1.1.0rc1.dist-info → qiskit-1.1.1.dist-info}/RECORD +56 -56
  53. {qiskit-1.1.0rc1.dist-info → qiskit-1.1.1.dist-info}/LICENSE.txt +0 -0
  54. {qiskit-1.1.0rc1.dist-info → qiskit-1.1.1.dist-info}/WHEEL +0 -0
  55. {qiskit-1.1.0rc1.dist-info → qiskit-1.1.1.dist-info}/entry_points.txt +0 -0
  56. {qiskit-1.1.0rc1.dist-info → qiskit-1.1.1.dist-info}/top_level.txt +0 -0
@@ -104,15 +104,21 @@ class VF2Layout(AnalysisPass):
104
104
  limit on the number of trials will be set.
105
105
  target (Target): A target representing the backend device to run ``VF2Layout`` on.
106
106
  If specified it will supersede a set value for ``properties`` and
107
- ``coupling_map``.
107
+ ``coupling_map`` if the :class:`.Target` contains connectivity constraints. If the value
108
+ of ``target`` models an ideal backend without any constraints then the value of
109
+ ``coupling_map``
110
+ will be used.
108
111
 
109
112
  Raises:
110
113
  TypeError: At runtime, if neither ``coupling_map`` or ``target`` are provided.
111
114
  """
112
115
  super().__init__()
113
116
  self.target = target
114
- if target is not None:
115
- self.coupling_map = self.target.build_coupling_map()
117
+ if (
118
+ target is not None
119
+ and (target_coupling_map := self.target.build_coupling_map()) is not None
120
+ ):
121
+ self.coupling_map = target_coupling_map
116
122
  else:
117
123
  self.coupling_map = coupling_map
118
124
  self.properties = properties
@@ -145,7 +151,7 @@ class VF2Layout(AnalysisPass):
145
151
  )
146
152
  # Filter qubits without any supported operations. If they don't support any operations
147
153
  # They're not valid for layout selection
148
- if self.target is not None:
154
+ if self.target is not None and self.target.qargs is not None:
149
155
  has_operations = set(itertools.chain.from_iterable(self.target.qargs))
150
156
  to_remove = set(range(len(cm_nodes))).difference(has_operations)
151
157
  if to_remove:
@@ -145,7 +145,7 @@ def score_layout(
145
145
  def build_average_error_map(target, properties, coupling_map):
146
146
  """Build an average error map used for scoring layouts pre-basis translation."""
147
147
  num_qubits = 0
148
- if target is not None:
148
+ if target is not None and target.qargs is not None:
149
149
  num_qubits = target.num_qubits
150
150
  avg_map = ErrorMap(len(target.qargs))
151
151
  elif coupling_map is not None:
@@ -157,7 +157,7 @@ def build_average_error_map(target, properties, coupling_map):
157
157
  # object
158
158
  avg_map = ErrorMap(0)
159
159
  built = False
160
- if target is not None:
160
+ if target is not None and target.qargs is not None:
161
161
  for qargs in target.qargs:
162
162
  if qargs is None:
163
163
  continue
@@ -160,8 +160,13 @@ class Commuting2qGateRouter(TransformationPass):
160
160
  if len(dag.qubits) != next(iter(dag.qregs.values())).size:
161
161
  raise TranspilerError("Circuit has qubits not contained in the qubit register.")
162
162
 
163
- new_dag = dag.copy_empty_like()
163
+ # Fix output permutation -- copied from ElidePermutations
164
+ input_qubit_mapping = {qubit: index for index, qubit in enumerate(dag.qubits)}
165
+ self.property_set["original_layout"] = Layout(input_qubit_mapping)
166
+ if self.property_set["original_qubit_indices"] is None:
167
+ self.property_set["original_qubit_indices"] = input_qubit_mapping
164
168
 
169
+ new_dag = dag.copy_empty_like()
165
170
  current_layout = Layout.generate_trivial_layout(*dag.qregs.values())
166
171
 
167
172
  # Used to keep track of nodes that do not decompose using swap strategies.
@@ -183,6 +188,8 @@ class Commuting2qGateRouter(TransformationPass):
183
188
 
184
189
  self._compose_non_swap_nodes(accumulator, current_layout, new_dag)
185
190
 
191
+ self.property_set["virtual_permutation_layout"] = current_layout
192
+
186
193
  return new_dag
187
194
 
188
195
  def _compose_non_swap_nodes(
@@ -329,13 +329,13 @@ class StarPreRouting(TransformationPass):
329
329
  last_2q_gate = None
330
330
 
331
331
  int_digits = floor(log10(len(processing_order))) + 1
332
- processing_order_s = set(processing_order)
332
+ processing_order_index_map = {
333
+ node: f"a{str(index).zfill(int(int_digits))}"
334
+ for index, node in enumerate(processing_order)
335
+ }
333
336
 
334
337
  def tie_breaker_key(node):
335
- if node in processing_order_s:
336
- return "a" + str(processing_order.index(node)).zfill(int(int_digits))
337
- else:
338
- return node.sort_key
338
+ return processing_order_index_map.get(node, node.sort_key)
339
339
 
340
340
  for node in dag.topological_op_nodes(key=tie_breaker_key):
341
341
  block_id = node_to_block_id.get(node, None)
@@ -99,8 +99,34 @@ def generate_preset_pass_manager(
99
99
  This function is used to quickly generate a preset pass manager. A preset pass
100
100
  manager are the default pass managers used by the :func:`~.transpile`
101
101
  function. This function provides a convenient and simple method to construct
102
- a standalone :class:`~.PassManager` object that mirrors what the transpile
102
+ a standalone :class:`~.PassManager` object that mirrors what the :func:`~.transpile`
103
+ function internally builds and uses.
103
104
 
105
+ The target constraints for the pass manager construction can be specified through a :class:`.Target`
106
+ instance, a :class:`.BackendV1` or :class:`.BackendV2` instance, or via loose constraints
107
+ (``basis_gates``, ``inst_map``, ``coupling_map``, ``backend_properties``, ``instruction_durations``,
108
+ ``dt`` or ``timing_constraints``).
109
+ The order of priorities for target constraints works as follows: if a ``target``
110
+ input is provided, it will take priority over any ``backend`` input or loose constraints.
111
+ If a ``backend`` is provided together with any loose constraint
112
+ from the list above, the loose constraint will take priority over the corresponding backend
113
+ constraint. This behavior is independent of whether the ``backend`` instance is of type
114
+ :class:`.BackendV1` or :class:`.BackendV2`, as summarized in the table below. The first column
115
+ in the table summarizes the potential user-provided constraints, and each cell shows whether
116
+ the priority is assigned to that specific constraint input or another input
117
+ (`target`/`backend(V1)`/`backend(V2)`).
118
+
119
+ ============================ ========= ======================== =======================
120
+ User Provided target backend(V1) backend(V2)
121
+ ============================ ========= ======================== =======================
122
+ **basis_gates** target basis_gates basis_gates
123
+ **coupling_map** target coupling_map coupling_map
124
+ **instruction_durations** target instruction_durations instruction_durations
125
+ **inst_map** target inst_map inst_map
126
+ **dt** target dt dt
127
+ **timing_constraints** target timing_constraints timing_constraints
128
+ **backend_properties** target backend_properties backend_properties
129
+ ============================ ========= ======================== =======================
104
130
 
105
131
  Args:
106
132
  optimization_level (int): The optimization level to generate a
@@ -890,7 +890,7 @@ class Target(Mapping):
890
890
  return False
891
891
  if qargs not in self._gate_map[operation_name]:
892
892
  return False
893
- return getattr(self._gate_map[operation_name][qargs], "_calibration") is not None
893
+ return getattr(self._gate_map[operation_name][qargs], "_calibration", None) is not None
894
894
 
895
895
  def get_calibration(
896
896
  self,
qiskit/utils/__init__.py CHANGED
@@ -44,7 +44,7 @@ Multiprocessing
44
44
  .. autofunction:: local_hardware_info
45
45
  .. autofunction:: is_main_process
46
46
 
47
- A helper function for calling a custom function with python
47
+ A helper function for calling a custom function with Python
48
48
  :class:`~concurrent.futures.ProcessPoolExecutor`. Tasks can be executed in parallel using this function.
49
49
 
50
50
  .. autofunction:: parallel_map
@@ -70,7 +70,7 @@ from .lazy_tester import LazyDependencyManager, LazyImportTester, LazySubprocess
70
70
 
71
71
  from . import optionals
72
72
 
73
- from .parallel import parallel_map
73
+ from .parallel import parallel_map, should_run_in_parallel
74
74
 
75
75
  __all__ = [
76
76
  "LazyDependencyManager",
@@ -85,4 +85,5 @@ __all__ = [
85
85
  "is_main_process",
86
86
  "apply_prefix",
87
87
  "parallel_map",
88
+ "should_run_in_parallel",
88
89
  ]
qiskit/utils/parallel.py CHANGED
@@ -48,6 +48,8 @@ Routines for running Python functions in parallel using process pools
48
48
  from the multiprocessing library.
49
49
  """
50
50
 
51
+ from __future__ import annotations
52
+
51
53
  import os
52
54
  from concurrent.futures import ProcessPoolExecutor
53
55
  import sys
@@ -101,6 +103,21 @@ def _task_wrapper(param):
101
103
  return task(value, *task_args, **task_kwargs)
102
104
 
103
105
 
106
+ def should_run_in_parallel(num_processes: int | None = None) -> bool:
107
+ """Return whether the current parallelisation configuration suggests that we should run things
108
+ like :func:`parallel_map` in parallel (``True``) or degrade to serial (``False``).
109
+
110
+ Args:
111
+ num_processes: the number of processes requested for use (if given).
112
+ """
113
+ num_processes = CPU_COUNT if num_processes is None else num_processes
114
+ return (
115
+ num_processes > 1
116
+ and os.getenv("QISKIT_IN_PARALLEL", "FALSE") == "FALSE"
117
+ and CONFIG.get("parallel_enabled", PARALLEL_DEFAULT)
118
+ )
119
+
120
+
104
121
  def parallel_map( # pylint: disable=dangerous-default-value
105
122
  task, values, task_args=(), task_kwargs={}, num_processes=CPU_COUNT
106
123
  ):
@@ -110,21 +127,20 @@ def parallel_map( # pylint: disable=dangerous-default-value
110
127
 
111
128
  result = [task(value, *task_args, **task_kwargs) for value in values]
112
129
 
113
- On Windows this function defaults to a serial implementation to avoid the
114
- overhead from spawning processes in Windows.
130
+ This will parallelise the results if the number of ``values`` is greater than one, and the
131
+ current system configuration permits parallelization.
115
132
 
116
133
  Args:
117
134
  task (func): Function that is to be called for each value in ``values``.
118
- values (array_like): List or array of values for which the ``task``
119
- function is to be evaluated.
135
+ values (array_like): List or array of values for which the ``task`` function is to be
136
+ evaluated.
120
137
  task_args (list): Optional additional arguments to the ``task`` function.
121
138
  task_kwargs (dict): Optional additional keyword argument to the ``task`` function.
122
139
  num_processes (int): Number of processes to spawn.
123
140
 
124
141
  Returns:
125
- result: The result list contains the value of
126
- ``task(value, *task_args, **task_kwargs)`` for
127
- each value in ``values``.
142
+ result: The result list contains the value of ``task(value, *task_args, **task_kwargs)`` for
143
+ each value in ``values``.
128
144
 
129
145
  Raises:
130
146
  QiskitError: If user interrupts via keyboard.
@@ -147,12 +163,7 @@ def parallel_map( # pylint: disable=dangerous-default-value
147
163
  if len(values) == 1:
148
164
  return [task(values[0], *task_args, **task_kwargs)]
149
165
 
150
- # Run in parallel if not Win and not in parallel already
151
- if (
152
- num_processes > 1
153
- and os.getenv("QISKIT_IN_PARALLEL") == "FALSE"
154
- and CONFIG.get("parallel_enabled", PARALLEL_DEFAULT)
155
- ):
166
+ if should_run_in_parallel(num_processes):
156
167
  os.environ["QISKIT_IN_PARALLEL"] = "TRUE"
157
168
  try:
158
169
  results = []
@@ -173,8 +184,6 @@ def parallel_map( # pylint: disable=dangerous-default-value
173
184
  os.environ["QISKIT_IN_PARALLEL"] = "FALSE"
174
185
  return results
175
186
 
176
- # Cannot do parallel on Windows , if another parallel_map is running in parallel,
177
- # or len(values) == 1.
178
187
  results = []
179
188
  for _, value in enumerate(values):
180
189
  result = task(value, *task_args, **task_kwargs)
@@ -1039,7 +1039,9 @@ def plot_coupling_map(
1039
1039
  graph = CouplingMap(coupling_map).graph
1040
1040
 
1041
1041
  if not plot_directed:
1042
+ line_color_map = dict(zip(graph.edge_list(), line_color))
1042
1043
  graph = graph.to_undirected(multigraph=False)
1044
+ line_color = [line_color_map[edge] for edge in graph.edge_list()]
1043
1045
 
1044
1046
  for node in graph.node_indices():
1045
1047
  graph[node] = node
@@ -1122,7 +1124,13 @@ def plot_circuit_layout(circuit, backend, view="virtual", qubit_coordinates=None
1122
1124
  Args:
1123
1125
  circuit (QuantumCircuit): Input quantum circuit.
1124
1126
  backend (Backend): Target backend.
1125
- view (str): Layout view: either 'virtual' or 'physical'.
1127
+ view (str): How to label qubits in the layout. Options:
1128
+
1129
+ - ``"virtual"``: Label each qubit with the index of the virtual qubit that
1130
+ mapped to it.
1131
+ - ``"physical"``: Label each qubit with the index of the physical qubit that it
1132
+ corresponds to on the device.
1133
+
1126
1134
  qubit_coordinates (Sequence): An optional sequence input (list or array being the
1127
1135
  most common) of 2d coordinates for each qubit. The length of the
1128
1136
  sequence must match the number of qubits on the backend. The sequence
@@ -40,7 +40,7 @@ from typing import Dict, List, Union, Optional
40
40
 
41
41
  from qiskit import pulse
42
42
  from qiskit.providers import BackendConfigurationError
43
- from qiskit.providers.backend import Backend
43
+ from qiskit.providers.backend import Backend, BackendV2
44
44
 
45
45
 
46
46
  class DrawerBackendInfo(ABC):
@@ -106,40 +106,67 @@ class OpenPulseBackendInfo(DrawerBackendInfo):
106
106
  Returns:
107
107
  OpenPulseBackendInfo: New configured instance.
108
108
  """
109
- configuration = backend.configuration()
110
- defaults = backend.defaults()
111
-
112
- # load name
113
- name = backend.name()
114
-
115
- # load cycle time
116
- dt = configuration.dt
117
-
118
- # load frequencies
119
109
  chan_freqs = {}
120
-
121
- chan_freqs.update(
122
- {pulse.DriveChannel(qind): freq for qind, freq in enumerate(defaults.qubit_freq_est)}
123
- )
124
- chan_freqs.update(
125
- {pulse.MeasureChannel(qind): freq for qind, freq in enumerate(defaults.meas_freq_est)}
126
- )
127
- for qind, u_lo_mappers in enumerate(configuration.u_channel_lo):
128
- temp_val = 0.0 + 0.0j
129
- for u_lo_mapper in u_lo_mappers:
130
- temp_val += defaults.qubit_freq_est[u_lo_mapper.q] * u_lo_mapper.scale
131
- chan_freqs[pulse.ControlChannel(qind)] = temp_val.real
132
-
133
- # load qubit channel mapping
134
110
  qubit_channel_map = defaultdict(list)
135
- for qind in range(configuration.n_qubits):
136
- qubit_channel_map[qind].append(configuration.drive(qubit=qind))
137
- qubit_channel_map[qind].append(configuration.measure(qubit=qind))
138
- for tind in range(configuration.n_qubits):
111
+
112
+ if hasattr(backend, "configuration") and hasattr(backend, "defaults"):
113
+ configuration = backend.configuration()
114
+ defaults = backend.defaults()
115
+
116
+ name = configuration.backend_name
117
+ dt = configuration.dt
118
+
119
+ # load frequencies
120
+ chan_freqs.update(
121
+ {
122
+ pulse.DriveChannel(qind): freq
123
+ for qind, freq in enumerate(defaults.qubit_freq_est)
124
+ }
125
+ )
126
+ chan_freqs.update(
127
+ {
128
+ pulse.MeasureChannel(qind): freq
129
+ for qind, freq in enumerate(defaults.meas_freq_est)
130
+ }
131
+ )
132
+ for qind, u_lo_mappers in enumerate(configuration.u_channel_lo):
133
+ temp_val = 0.0 + 0.0j
134
+ for u_lo_mapper in u_lo_mappers:
135
+ temp_val += defaults.qubit_freq_est[u_lo_mapper.q] * u_lo_mapper.scale
136
+ chan_freqs[pulse.ControlChannel(qind)] = temp_val.real
137
+
138
+ # load qubit channel mapping
139
+ for qind in range(configuration.n_qubits):
140
+ qubit_channel_map[qind].append(configuration.drive(qubit=qind))
141
+ qubit_channel_map[qind].append(configuration.measure(qubit=qind))
142
+ for tind in range(configuration.n_qubits):
143
+ try:
144
+ qubit_channel_map[qind].extend(configuration.control(qubits=(qind, tind)))
145
+ except BackendConfigurationError:
146
+ pass
147
+ elif isinstance(backend, BackendV2):
148
+ # Pure V2 model doesn't contain channel frequency information.
149
+ name = backend.name
150
+ dt = backend.dt
151
+
152
+ # load qubit channel mapping
153
+ for qind in range(backend.num_qubits):
154
+ # channels are NotImplemented by default so we must catch arbitrary error.
155
+ try:
156
+ qubit_channel_map[qind].append(backend.drive_channel(qind))
157
+ except Exception: # pylint: disable=broad-except
158
+ pass
139
159
  try:
140
- qubit_channel_map[qind].extend(configuration.control(qubits=(qind, tind)))
141
- except BackendConfigurationError:
160
+ qubit_channel_map[qind].append(backend.measure_channel(qind))
161
+ except Exception: # pylint: disable=broad-except
142
162
  pass
163
+ for tind in range(backend.num_qubits):
164
+ try:
165
+ qubit_channel_map[qind].extend(backend.control_channel(qubits=(qind, tind)))
166
+ except Exception: # pylint: disable=broad-except
167
+ pass
168
+ else:
169
+ raise RuntimeError("Backend object not yet supported")
143
170
 
144
171
  return OpenPulseBackendInfo(
145
172
  name=name, dt=dt, channel_frequency_map=chan_freqs, qubit_channel_map=qubit_channel_map
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qiskit
3
- Version: 1.1.0rc1
3
+ Version: 1.1.1
4
4
  Summary: An open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
5
5
  Author-email: Qiskit Development Team <qiskit@us.ibm.com>
6
6
  License: Apache 2.0