qiskit 1.3.2__cp39-abi3-win32.whl → 1.4.0__cp39-abi3-win32.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 (65) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +1 -0
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/circuit/__init__.py +5 -2
  5. qiskit/circuit/bit.py +12 -0
  6. qiskit/circuit/classicalfunction/__init__.py +13 -1
  7. qiskit/circuit/classicalfunction/boolean_expression.py +10 -1
  8. qiskit/circuit/classicalfunction/classicalfunction.py +10 -1
  9. qiskit/circuit/classicalfunction/exceptions.py +7 -1
  10. qiskit/circuit/delay.py +5 -0
  11. qiskit/circuit/library/generalized_gates/mcmt.py +5 -6
  12. qiskit/circuit/library/phase_oracle.py +24 -17
  13. qiskit/circuit/library/standard_gates/rz.py +7 -7
  14. qiskit/circuit/library/standard_gates/xx_minus_yy.py +0 -30
  15. qiskit/circuit/parametervector.py +25 -5
  16. qiskit/circuit/quantumcircuit.py +68 -2
  17. qiskit/circuit/register.py +13 -0
  18. qiskit/compiler/assembler.py +16 -8
  19. qiskit/compiler/transpiler.py +1 -1
  20. qiskit/dagcircuit/dagdependency_v2.py +4 -2
  21. qiskit/passmanager/passmanager.py +19 -1
  22. qiskit/primitives/backend_estimator_v2.py +17 -0
  23. qiskit/primitives/backend_sampler_v2.py +15 -0
  24. qiskit/providers/backend_compat.py +46 -11
  25. qiskit/providers/basic_provider/basic_simulator.py +15 -3
  26. qiskit/providers/exceptions.py +23 -2
  27. qiskit/providers/models/backendproperties.py +19 -1
  28. qiskit/providers/models/backendstatus.py +10 -0
  29. qiskit/providers/models/jobstatus.py +11 -0
  30. qiskit/pulse/schedule.py +1 -1
  31. qiskit/quantum_info/operators/channel/transformations.py +15 -0
  32. qiskit/result/result.py +109 -20
  33. qiskit/synthesis/evolution/product_formula.py +1 -2
  34. qiskit/synthesis/evolution/qdrift.py +1 -2
  35. qiskit/synthesis/evolution/suzuki_trotter.py +1 -2
  36. qiskit/transpiler/__init__.py +772 -542
  37. qiskit/transpiler/layout.py +6 -6
  38. qiskit/transpiler/passes/calibration/rzx_templates.py +7 -0
  39. qiskit/transpiler/passes/layout/dense_layout.py +12 -0
  40. qiskit/transpiler/passes/layout/sabre_layout.py +13 -0
  41. qiskit/transpiler/passes/layout/vf2_layout.py +11 -0
  42. qiskit/transpiler/passes/layout/vf2_post_layout.py +22 -0
  43. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +8 -0
  44. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +2 -3
  45. qiskit/transpiler/passes/routing/star_prerouting.py +17 -2
  46. qiskit/transpiler/passes/scheduling/scheduling/alap.py +1 -1
  47. qiskit/transpiler/passes/scheduling/scheduling/asap.py +1 -1
  48. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +11 -0
  49. qiskit/transpiler/passmanager_config.py +11 -0
  50. qiskit/transpiler/preset_passmanagers/__init__.py +26 -6
  51. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +188 -118
  52. qiskit/transpiler/preset_passmanagers/common.py +133 -83
  53. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +29 -3
  54. qiskit/transpiler/preset_passmanagers/plugin.py +33 -42
  55. qiskit/transpiler/target.py +41 -9
  56. qiskit/visualization/circuit/text.py +3 -2
  57. qiskit/visualization/gate_map.py +50 -0
  58. qiskit/visualization/pulse_v2/interface.py +0 -2
  59. qiskit/visualization/timeline/interface.py +3 -3
  60. {qiskit-1.3.2.dist-info → qiskit-1.4.0.dist-info}/METADATA +4 -7
  61. {qiskit-1.3.2.dist-info → qiskit-1.4.0.dist-info}/RECORD +65 -65
  62. {qiskit-1.3.2.dist-info → qiskit-1.4.0.dist-info}/LICENSE.txt +0 -0
  63. {qiskit-1.3.2.dist-info → qiskit-1.4.0.dist-info}/WHEEL +0 -0
  64. {qiskit-1.3.2.dist-info → qiskit-1.4.0.dist-info}/entry_points.txt +0 -0
  65. {qiskit-1.3.2.dist-info → qiskit-1.4.0.dist-info}/top_level.txt +0 -0
qiskit/VERSION.txt CHANGED
@@ -1 +1 @@
1
- 1.3.2
1
+ 1.4.0
qiskit/__init__.py CHANGED
@@ -110,6 +110,7 @@ sys.modules["qiskit._accelerate.filter_op_nodes"] = _accelerate.filter_op_nodes
110
110
  sys.modules["qiskit._accelerate.twirling"] = _accelerate.twirling
111
111
  sys.modules["qiskit._accelerate.high_level_synthesis"] = _accelerate.high_level_synthesis
112
112
  sys.modules["qiskit._accelerate.remove_identity_equiv"] = _accelerate.remove_identity_equiv
113
+ sys.modules["qiskit._accelerate.circuit_duration"] = _accelerate.circuit_duration
113
114
 
114
115
  from qiskit.exceptions import QiskitError, MissingOptionalLibraryError
115
116
 
qiskit/_accelerate.pyd CHANGED
Binary file
@@ -294,6 +294,7 @@ main related classes are:
294
294
  * :class:`Parameter`, the atom of compile-time expressions
295
295
  * :class:`ParameterExpression`, a symbolic calculation on parameters
296
296
  * :class:`ParameterVector`, a convenience collection of many :class:`Parameter`\ s
297
+ * :class:`ParameterVectorElement`, a subclass of :class:`Parameter` used by :class:`ParameterVector`
297
298
 
298
299
  The :mod:`qiskit.circuit` module also exposes some calculation classes that work with circuits to
299
300
  assist compilation workflows. These include:
@@ -667,12 +668,14 @@ execution. You can do this assignment using :meth:`QuantumCircuit.assign_parame
667
668
 
668
669
  You may want to use many parameters that are related to each other. To make this easier (and to
669
670
  avoid you needing to come up with many names), you can use the convenience constructor
670
- :class:`ParameterVector`. The elements of the vector are all valid :class:`Parameter` instances.
671
+ :class:`ParameterVector`. The elements of the vector are all valid :class:`Parameter` instances, of
672
+ a special subclass :class:`ParameterVectorElement`.
671
673
 
672
674
  .. autosummary::
673
675
  :toctree: ../stubs/
674
676
 
675
677
  ParameterVector
678
+ ParameterVectorElement
676
679
 
677
680
  .. _circuit-control-flow-repr:
678
681
 
@@ -1289,7 +1292,7 @@ from .measure import Measure
1289
1292
  from .reset import Reset
1290
1293
  from .store import Store
1291
1294
  from .parameter import Parameter
1292
- from .parametervector import ParameterVector
1295
+ from .parametervector import ParameterVector, ParameterVectorElement
1293
1296
  from .parameterexpression import ParameterExpression
1294
1297
  from .quantumcircuitdata import CircuitInstruction
1295
1298
  from .equivalence import EquivalenceLibrary
qiskit/circuit/bit.py CHANGED
@@ -14,6 +14,7 @@
14
14
  Quantum bit and Classical bit objects.
15
15
  """
16
16
  import copy
17
+ import warnings
17
18
 
18
19
  from qiskit.circuit.exceptions import CircuitError
19
20
 
@@ -57,6 +58,17 @@ class Bit:
57
58
  self._hash = hash((self._register, self._index))
58
59
  self._repr = f"{self.__class__.__name__}({self._register}, {self._index})"
59
60
 
61
+ def __init_subclass__(cls):
62
+ # In Qiskit 2.0, `Bit` and `Register` will move to Rust space, and the allowable types of
63
+ # them will be fixed, similar to if the classes had been marked as `final`.
64
+ if cls.__module__.split(".", 2)[0] != __name__.split(".", 2)[0]:
65
+ warnings.warn(
66
+ "subclassing 'Bit' is not supported, and may not be possible in Qiskit 2.0",
67
+ category=DeprecationWarning,
68
+ stacklevel=2,
69
+ )
70
+ return cls
71
+
60
72
  def __repr__(self):
61
73
  """Return the official string representing the bit."""
62
74
  if (self._register, self._index) == (None, None):
@@ -20,6 +20,10 @@ ClassicalFunction compiler (:mod:`qiskit.circuit.classicalfunction`)
20
20
  Overview
21
21
  ========
22
22
 
23
+ .. warning::
24
+
25
+ This module is deprecated as of Qiskit 1.4.0. It will be removed in the Qiskit 2.0 release.
26
+
23
27
  The classical function compiler provides the necessary tools to map a classical
24
28
  potentially irreversible functions into quantum circuits. Below is a simple example of
25
29
  how to synthesize a simple boolean function defined using Python into a
@@ -111,7 +115,7 @@ Exceptions
111
115
  ClassicalFunctionCompilerTypeError
112
116
 
113
117
  """
114
-
118
+ from qiskit.utils.deprecation import deprecate_func
115
119
  from .classicalfunction import ClassicalFunction
116
120
  from .exceptions import (
117
121
  ClassicalFunctionParseError,
@@ -121,6 +125,14 @@ from .exceptions import (
121
125
  from .boolean_expression import BooleanExpression
122
126
 
123
127
 
128
+ @deprecate_func(
129
+ since="1.4",
130
+ removal_timeline="in Qiskit 2.0",
131
+ additional_msg="Use `PhaseOracle` instead, which can be turned into a "
132
+ "bit-flip oracle by applying Hadamard gates on the target "
133
+ "qubit before and after the instruction, and conditioning."
134
+ "the instruction on the target qubit.",
135
+ )
124
136
  def classical_function(func):
125
137
  """
126
138
  Parses and type checks the callable ``func`` to compile it into an ``ClassicalFunction``
@@ -15,15 +15,24 @@
15
15
  from os.path import basename, isfile
16
16
  from typing import Callable, Optional
17
17
 
18
+ from qiskit.utils.deprecation import deprecate_func
18
19
  from qiskit.circuit import QuantumCircuit
19
20
  from qiskit.utils.optionals import HAS_TWEEDLEDUM
20
21
  from .classical_element import ClassicalElement
21
22
 
22
23
 
23
- @HAS_TWEEDLEDUM.require_in_instance
24
24
  class BooleanExpression(ClassicalElement):
25
25
  """The Boolean Expression gate."""
26
26
 
27
+ @HAS_TWEEDLEDUM.require_in_instance
28
+ @deprecate_func(
29
+ since="1.4",
30
+ removal_timeline="in Qiskit 2.0",
31
+ additional_msg="Use `PhaseOracle` instead, which can be turned into a "
32
+ "bit-flip oracle by applying Hadamard gates on the target "
33
+ "qubit before and after the instruction, and conditioning."
34
+ "the instruction on the target qubit.",
35
+ )
27
36
  def __init__(self, expression: str, name: str = None, var_order: list = None) -> None:
28
37
  """
29
38
  Args:
@@ -15,6 +15,7 @@
15
15
  import ast
16
16
  from typing import Callable, Optional
17
17
 
18
+ from qiskit.utils.deprecation import deprecate_func
18
19
  from qiskit.circuit import QuantumCircuit, QuantumRegister
19
20
  from qiskit.exceptions import QiskitError
20
21
  from qiskit.utils.optionals import HAS_TWEEDLEDUM
@@ -23,10 +24,18 @@ from .classical_function_visitor import ClassicalFunctionVisitor
23
24
  from .utils import tweedledum2qiskit
24
25
 
25
26
 
26
- @HAS_TWEEDLEDUM.require_in_instance
27
27
  class ClassicalFunction(ClassicalElement):
28
28
  """Represent a classical function and its logic network."""
29
29
 
30
+ @HAS_TWEEDLEDUM.require_in_instance
31
+ @deprecate_func(
32
+ since="1.4",
33
+ removal_timeline="in Qiskit 2.0",
34
+ additional_msg="Use `PhaseOracle` instead, which can be turned into a "
35
+ "bit-flip oracle by applying Hadamard gates on the target "
36
+ "qubit before and after the instruction, and conditioning."
37
+ "the instruction on the target qubit.",
38
+ )
30
39
  def __init__(self, source, name=None):
31
40
  """Creates a ``ClassicalFunction`` from Python source code in ``source``.
32
41
 
@@ -10,7 +10,13 @@
10
10
  # copyright notice, and modified files need to carry a notice indicating
11
11
  # that they have been altered from the originals.
12
12
 
13
- """Exceptions for ClassicalFunction compiler"""
13
+ """Exceptions for ClassicalFunction compiler
14
+
15
+ .. warning::
16
+
17
+ This module is deprecated as of qiskit 1.4.0 version. It will be removed in the Qiskit 2.0 release.
18
+
19
+ """
14
20
 
15
21
  from qiskit.exceptions import QiskitError
16
22
 
qiskit/circuit/delay.py CHANGED
@@ -81,6 +81,11 @@ class Delay(Instruction):
81
81
  """
82
82
  return self.__array__(dtype=complex)
83
83
 
84
+ def __eq__(self, other):
85
+ return (
86
+ isinstance(other, Delay) and self.unit == other.unit and self._compare_parameters(other)
87
+ )
88
+
84
89
  def __repr__(self):
85
90
  """Return the official string representing the delay."""
86
91
  return f"{self.__class__.__name__}(duration={self.params[0]}[unit={self.unit}])"
@@ -49,7 +49,7 @@ class MCMT(QuantumCircuit):
49
49
  :class:`~qiskit.circuit.library.MCMTVChain`.
50
50
  """
51
51
 
52
- @deprecate_func(since="1.3", additional_msg="Use MCMTGate instead.", pending=True)
52
+ @deprecate_func(since="1.4", additional_msg="Use MCMTGate instead.")
53
53
  def __init__(
54
54
  self,
55
55
  gate: Gate | Callable[[QuantumCircuit, circuit.Qubit, circuit.Qubit], circuit.Instruction],
@@ -76,7 +76,7 @@ class MCMT(QuantumCircuit):
76
76
  warnings.warn(
77
77
  "Passing a callable to MCMT is pending deprecation since Qiskit 1.3. Pass a "
78
78
  "gate instance or the gate name instead, e.g. pass 'h' instead of QuantumCircuit.h.",
79
- category=PendingDeprecationWarning,
79
+ category=DeprecationWarning,
80
80
  stacklevel=2,
81
81
  )
82
82
  gate = gate.__name__
@@ -84,7 +84,7 @@ class MCMT(QuantumCircuit):
84
84
  warnings.warn(
85
85
  "Passing a QuantumCircuit is pending deprecation since Qiskit 1.3. Pass a gate "
86
86
  "or turn the circuit into a gate using the ``to_gate`` method, instead.",
87
- category=PendingDeprecationWarning,
87
+ category=DeprecationWarning,
88
88
  stacklevel=2,
89
89
  )
90
90
  gate = gate.to_gate()
@@ -158,9 +158,8 @@ class MCMTVChain(MCMT):
158
158
  """
159
159
 
160
160
  @deprecate_func(
161
- since="1.3",
161
+ since="1.4",
162
162
  additional_msg="Use MCMTGate with the V-chain synthesis plugin instead.",
163
- pending=True,
164
163
  )
165
164
  def __init__(
166
165
  self,
@@ -277,7 +276,7 @@ class MCMTGate(ControlledGate):
277
276
  warnings.warn(
278
277
  "Passing a controlled gate to MCMT is pending deprecation since Qiskit 1.3. Pass a "
279
278
  "single-qubit gate instance or the gate name instead, e.g. pass 'h' instead of 'ch'.",
280
- category=PendingDeprecationWarning,
279
+ category=DeprecationWarning,
281
280
  stacklevel=2,
282
281
  )
283
282
  base_gate = gate.base_gate
@@ -63,31 +63,38 @@ class PhaseOracle(QuantumCircuit):
63
63
  var_order(list): A list with the order in which variables will be created.
64
64
  (default: by appearance)
65
65
  """
66
- from qiskit.circuit.classicalfunction.boolean_expression import BooleanExpression
67
- from qiskit.circuit.classicalfunction.classical_element import ClassicalElement
66
+ # ignore deprecation warning for BooleanExpression; implementation is changing in 2.0
67
+ import warnings
68
+
69
+ with warnings.catch_warnings():
70
+ warnings.simplefilter("ignore", DeprecationWarning)
71
+ from qiskit.circuit.classicalfunction.boolean_expression import BooleanExpression
72
+ from qiskit.circuit.classicalfunction.classical_element import ClassicalElement
68
73
 
69
- if not isinstance(expression, ClassicalElement):
70
- expression = BooleanExpression(expression, var_order=var_order)
74
+ if not isinstance(expression, ClassicalElement):
75
+ expression = BooleanExpression(expression, var_order=var_order)
71
76
 
72
- self.boolean_expression = expression
77
+ self.boolean_expression = expression
73
78
 
74
- if synthesizer is None:
79
+ if synthesizer is None:
75
80
 
76
- def synthesizer(boolean_expression):
77
- from tweedledum.synthesis import pkrm_synth # pylint: disable=import-error
78
- from qiskit.circuit.classicalfunction.utils import tweedledum2qiskit
81
+ def synthesizer(boolean_expression):
82
+ from tweedledum.synthesis import pkrm_synth # pylint: disable=import-error
83
+ from qiskit.circuit.classicalfunction.utils import tweedledum2qiskit
79
84
 
80
- truth_table = boolean_expression._tweedledum_bool_expression.truth_table(
81
- output_bit=0
82
- )
83
- tweedledum_circuit = pkrm_synth(truth_table, {"pkrm_synth": {"phase_esop": True}})
84
- return tweedledum2qiskit(tweedledum_circuit)
85
+ truth_table = boolean_expression._tweedledum_bool_expression.truth_table(
86
+ output_bit=0
87
+ )
88
+ tweedledum_circuit = pkrm_synth(
89
+ truth_table, {"pkrm_synth": {"phase_esop": True}}
90
+ )
91
+ return tweedledum2qiskit(tweedledum_circuit)
85
92
 
86
- oracle = expression.synth(synthesizer=synthesizer)
93
+ oracle = expression.synth(synthesizer=synthesizer)
87
94
 
88
- super().__init__(oracle.num_qubits, name="Phase Oracle")
95
+ super().__init__(oracle.num_qubits, name="Phase Oracle")
89
96
 
90
- self.compose(oracle, inplace=True, copy=False)
97
+ self.compose(oracle, inplace=True, copy=False)
91
98
 
92
99
  def evaluate_bitstring(self, bitstring: str) -> bool:
93
100
  """Evaluate the oracle on a bitstring.
@@ -37,17 +37,17 @@ class RZGate(Gate):
37
37
  .. code-block:: text
38
38
 
39
39
  ┌───────┐
40
- q_0: ┤ Rz(λ) ├
40
+ q_0: ┤ Rz(φ) ├
41
41
  └───────┘
42
42
 
43
43
  **Matrix Representation:**
44
44
 
45
45
  .. math::
46
46
 
47
- RZ(\lambda) = \exp\left(-i\frac{\lambda}{2}Z\right) =
47
+ RZ(\phi) = \exp\left(-i\frac{\phi}{2}Z\right) =
48
48
  \begin{pmatrix}
49
- e^{-i\frac{\lambda}{2}} & 0 \\
50
- 0 & e^{i\frac{\lambda}{2}}
49
+ e^{-i\frac{\phi}{2}} & 0 \\
50
+ 0 & e^{i\frac{\phi}{2}}
51
51
  \end{pmatrix}
52
52
 
53
53
  .. seealso::
@@ -57,7 +57,7 @@ class RZGate(Gate):
57
57
 
58
58
  .. math::
59
59
 
60
- U1(\lambda) = e^{i{\lambda}/2}RZ(\lambda)
60
+ U1(\theta=\phi) = e^{i{\phi}/2}RZ(\phi)
61
61
 
62
62
  Reference for virtual Z gate implementation:
63
63
  `1612.00858 <https://arxiv.org/abs/1612.00858>`_
@@ -186,10 +186,10 @@ class CRZGate(ControlledGate):
186
186
  .. math::
187
187
 
188
188
  CRZ(\theta)\ q_0, q_1 =
189
- I \otimes |0\rangle\langle 0| + RZ(\theta) \otimes |1\rangle\langle 1| =
189
+ I \otimes |0\rangle\langle 0| + RZ(\phi=\theta) \otimes |1\rangle\langle 1| =
190
190
  \begin{pmatrix}
191
191
  1 & 0 & 0 & 0 \\
192
- 0 & e^{-i\frac{\lambda}{2}} & 0 & 0 \\
192
+ 0 & e^{-i\frac{\theta}{2}} & 0 & 0 \\
193
193
  0 & 0 & 1 & 0 \\
194
194
  0 & 0 & 0 & e^{i\frac{\theta}{2}}
195
195
  \end{pmatrix}
@@ -63,36 +63,6 @@ class XXMinusYYGate(Gate):
63
63
  0 & 0 & 1 & 0 \\
64
64
  -i\sin\left(\rotationangle\right)e^{i\beta} & 0 & 0 & \cos\left(\rotationangle\right)
65
65
  \end{pmatrix}
66
-
67
- .. note::
68
-
69
- In Qiskit's convention, higher qubit indices are more significant
70
- (little endian convention). In the above example we apply the gate
71
- on (q_0, q_1) which results in adding the (optional) phase defined
72
- by :math:`\beta` on q_1. Instead, if we apply it on (q_1, q_0), the
73
- phase is added on q_0. If :math:`\beta` is set to its default value
74
- of :math:`0`, the gate is equivalent in big and little endian.
75
-
76
- .. code-block:: text
77
-
78
- ┌───────────────┐
79
- q_0: ┤1 ├
80
- │ (XX-YY)(θ,β) │
81
- q_1: ┤0 ├
82
- └───────────────┘
83
-
84
- .. math::
85
-
86
- \newcommand{\rotationangle}{\frac{\theta}{2}}
87
-
88
- R_{XX-YY}(\theta, \beta) q_1, q_0 =
89
- RZ_0(\beta) \cdot \exp\left(-i \frac{\theta}{2} \frac{XX-YY}{2}\right) \cdot RZ_0(-\beta) =
90
- \begin{pmatrix}
91
- \cos\left(\rotationangle\right) & 0 & 0 & -i\sin\left(\rotationangle\right)e^{i\beta} \\
92
- 0 & 1 & 0 & 0 \\
93
- 0 & 0 & 1 & 0 \\
94
- -i\sin\left(\rotationangle\right)e^{-i\beta} & 0 & 0 & \cos\left(\rotationangle\right)
95
- \end{pmatrix}
96
66
  """
97
67
 
98
68
  _standard_gate = StandardGate.XXMinusYYGate
@@ -18,7 +18,12 @@ from .parameter import Parameter
18
18
 
19
19
 
20
20
  class ParameterVectorElement(Parameter):
21
- """An element of a ParameterVector."""
21
+ """An element of a :class:`ParameterVector`.
22
+
23
+ .. note::
24
+ There is very little reason to ever construct this class directly. Objects of this type are
25
+ automatically constructed efficiently as part of creating a :class:`ParameterVector`.
26
+ """
22
27
 
23
28
  ___slots__ = ("_vector", "_index")
24
29
 
@@ -48,7 +53,18 @@ class ParameterVectorElement(Parameter):
48
53
 
49
54
 
50
55
  class ParameterVector:
51
- """ParameterVector class to quickly generate lists of parameters."""
56
+ """A container of many related :class:`Parameter` objects.
57
+
58
+ This class is faster to construct than constructing many :class:`Parameter` objects
59
+ individually, and the individual names of the parameters will all share a common stem (the name
60
+ of the vector). For a vector called ``v`` with length 3, the individual elements will have
61
+ names ``v[0]``, ``v[1]`` and ``v[2]``.
62
+
63
+ The elements of a vector are sorted by the name of the vector, then the numeric value of their
64
+ index.
65
+
66
+ This class fulfill the :class:`collections.abc.Sequence` interface.
67
+ """
52
68
 
53
69
  __slots__ = ("_name", "_params", "_root_uuid")
54
70
 
@@ -62,16 +78,20 @@ class ParameterVector:
62
78
 
63
79
  @property
64
80
  def name(self):
65
- """Returns the name of the ParameterVector."""
81
+ """The name of the :class:`ParameterVector`."""
66
82
  return self._name
67
83
 
68
84
  @property
69
85
  def params(self):
70
- """Returns the list of parameters in the ParameterVector."""
86
+ """A list of the contained :class:`ParameterVectorElement` instances.
87
+
88
+ It is not safe to mutate this list."""
71
89
  return self._params
72
90
 
73
91
  def index(self, value):
74
- """Returns first index of value."""
92
+ """Find the index of a :class:`ParameterVectorElement` within the list.
93
+
94
+ It is typically much faster to use the :attr:`ParameterVectorElement.index` property."""
75
95
  return self._params.index(value)
76
96
 
77
97
  def __getitem__(self, key):
@@ -40,6 +40,7 @@ from typing import (
40
40
  import numpy as np
41
41
  from qiskit._accelerate.circuit import CircuitData
42
42
  from qiskit._accelerate.circuit import StandardGate
43
+ from qiskit._accelerate.circuit_duration import compute_estimated_duration
43
44
  from qiskit.exceptions import QiskitError
44
45
  from qiskit.utils.multiprocessing import is_main_process
45
46
  from qiskit.circuit.instruction import Instruction
@@ -156,6 +157,8 @@ class QuantumCircuit:
156
157
  :attr:`data` List of individual :class:`CircuitInstruction`\\ s that make up the
157
158
  circuit.
158
159
  :attr:`duration` Total duration of the circuit, added by scheduling transpiler passes.
160
+ This attribute is deprecated and :meth:`.estimate_duration` should
161
+ be used instead.
159
162
 
160
163
  :attr:`layout` Hardware layout and routing information added by the transpiler.
161
164
  :attr:`num_ancillas` The number of ancilla qubits in the circuit.
@@ -903,8 +906,9 @@ class QuantumCircuit:
903
906
 
904
907
  If a :class:`QuantumCircuit` has been scheduled as part of a transpilation pipeline, the timing
905
908
  information for individual qubits can be accessed. The whole-circuit timing information is
906
- available through the :attr:`duration`, :attr:`unit` and :attr:`op_start_times` attributes.
909
+ available through the :meth:`estimate_duration` method and :attr:`op_start_times` attribute.
907
910
 
911
+ .. automethod:: estimate_duration
908
912
  .. automethod:: qubit_duration
909
913
  .. automethod:: qubit_start_time
910
914
  .. automethod:: qubit_stop_time
@@ -6646,7 +6650,69 @@ class QuantumCircuit:
6646
6650
  if len(qubits) == len([done for done in dones.values() if done]): # all done
6647
6651
  return max(stop for stop in stops.values())
6648
6652
 
6649
- return 0 # If there are no instructions over bits
6653
+ if len(stops) > 0: # not all but some qubits has instructions
6654
+ return max(stops.values())
6655
+ else:
6656
+ return 0 # If there are no instructions over bits
6657
+
6658
+ def estimate_duration(self, target, unit: str = "s") -> int | float:
6659
+ """Estimate the duration of a scheduled circuit
6660
+
6661
+ This method computes the estimate of the circuit duration by finding
6662
+ the longest duration path in the circuit based on the durations
6663
+ provided by a given target. This method only works for simple circuits
6664
+ that have no control flow or other classical feed-forward operations.
6665
+
6666
+ Args:
6667
+ target (Target): The :class:`.Target` instance that contains durations for
6668
+ the instructions if the target is missing duration data for any of the
6669
+ instructions in the circuit an :class:`.QiskitError` will be raised. This
6670
+ should be the same target object used as the target for transpilation.
6671
+ unit: The unit to return the duration in. This defaults to "s" for seconds
6672
+ but this can be a supported SI prefix for seconds returns. For example
6673
+ setting this to "n" will return in unit of nanoseconds. Supported values
6674
+ of this type are "f", "p", "n", "u", "µ", "m", "k", "M", "G", "T", and
6675
+ "P". Additionally, a value of "dt" is also accepted to output an integer
6676
+ in units of "dt". For this to function "dt" must be specified in the
6677
+ ``target``.
6678
+
6679
+ Returns:
6680
+ The estimated duration for the execution of a single shot of the circuit in
6681
+ the specified unit.
6682
+
6683
+ Raises:
6684
+ QiskitError: If the circuit is not scheduled or contains other
6685
+ details that prevent computing an estimated duration from
6686
+ (such as parameterized delay).
6687
+ """
6688
+ from qiskit.converters import circuit_to_dag
6689
+
6690
+ dur = compute_estimated_duration(circuit_to_dag(self), target)
6691
+ if unit == "s":
6692
+ return dur
6693
+ if unit == "dt":
6694
+ from qiskit.circuit.duration import duration_in_dt # pylint: disable=cyclic-import
6695
+
6696
+ return duration_in_dt(dur, target.dt)
6697
+
6698
+ prefix_dict = {
6699
+ "f": 1e-15,
6700
+ "p": 1e-12,
6701
+ "n": 1e-9,
6702
+ "u": 1e-6,
6703
+ "µ": 1e-6,
6704
+ "m": 1e-3,
6705
+ "k": 1e3,
6706
+ "M": 1e6,
6707
+ "G": 1e9,
6708
+ "T": 1e12,
6709
+ "P": 1e15,
6710
+ }
6711
+ if unit not in prefix_dict:
6712
+ raise QiskitError(
6713
+ f"Specified unit: {unit} is not a valid/supported SI prefix, 's', or 'dt'"
6714
+ )
6715
+ return dur / prefix_dict[unit]
6650
6716
 
6651
6717
 
6652
6718
  class _OuterCircuitScopeInterface(CircuitScopeInterface):
@@ -17,7 +17,9 @@ Base register reference object.
17
17
  """
18
18
 
19
19
  from __future__ import annotations
20
+
20
21
  import itertools
22
+ import warnings
21
23
  import numpy as np
22
24
 
23
25
  from qiskit.circuit.exceptions import CircuitError
@@ -125,6 +127,17 @@ class Register:
125
127
  # until first access.
126
128
  self._bit_indices = None
127
129
 
130
+ def __init_subclass__(cls):
131
+ # In Qiskit 2.0, `Bit` and `Register` will move to Rust space, and the allowable types of
132
+ # them will be fixed, similar to if the classes had been marked as `final`.
133
+ if cls.__module__.split(".", 2)[0] != __name__.split(".", 2)[0]:
134
+ warnings.warn(
135
+ "subclassing 'Register' is not supported, and may not be possible in Qiskit 2.0",
136
+ category=DeprecationWarning,
137
+ stacklevel=2,
138
+ )
139
+ return cls
140
+
128
141
  @property
129
142
  def name(self):
130
143
  """Get the register name."""
@@ -261,14 +261,22 @@ def _assemble(
261
261
 
262
262
  # assemble either circuits or schedules
263
263
  if all(isinstance(exp, QuantumCircuit) for exp in experiments):
264
- run_config = _parse_circuit_args(
265
- parameter_binds,
266
- backend,
267
- meas_level,
268
- meas_return,
269
- parametric_pulses,
270
- **run_config_common_dict,
271
- )
264
+ with warnings.catch_warnings():
265
+ # Internally calls deprecated BasicSimulator.configuration()`
266
+ warnings.filterwarnings(
267
+ "ignore",
268
+ category=DeprecationWarning,
269
+ message=r".+\.basic_provider\.basic_simulator\.BasicSimulator\.configuration.+",
270
+ module="qiskit",
271
+ )
272
+ run_config = _parse_circuit_args(
273
+ parameter_binds,
274
+ backend,
275
+ meas_level,
276
+ meas_return,
277
+ parametric_pulses,
278
+ **run_config_common_dict,
279
+ )
272
280
 
273
281
  # If circuits are parameterized, bind parameters and remove from run_config
274
282
  bound_experiments, run_config = _expand_parameters(
@@ -191,7 +191,7 @@ def transpile( # pylint: disable=too-many-return-statements
191
191
  This can also be the external plugin name to use for the ``routing`` stage.
192
192
  You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
193
193
  ``"routing"`` for the ``stage_name`` argument.
194
- translation_method: Name of translation pass ('unroller', 'translator', 'synthesis')
194
+ translation_method: Name of translation pass (``"translator"`` or ``"synthesis"``)
195
195
  This can also be the external plugin name to use for the ``translation`` stage.
196
196
  You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
197
197
  ``"translation"`` for the ``stage_name`` argument.
@@ -13,6 +13,7 @@
13
13
  """_DAGDependencyV2 class for representing non-commutativity in a circuit.
14
14
  """
15
15
 
16
+ import itertools
16
17
  import math
17
18
  from collections import OrderedDict, defaultdict, namedtuple
18
19
  from typing import Dict, List, Generator, Any
@@ -344,7 +345,6 @@ class _DAGDependencyV2:
344
345
  op=operation,
345
346
  qargs=qargs,
346
347
  cargs=cargs,
347
- dag=self,
348
348
  )
349
349
  new_node._node_id = self._multi_graph.add_node(new_node)
350
350
  self._update_edges()
@@ -459,7 +459,9 @@ class _DAGDependencyV2:
459
459
  """
460
460
 
461
461
  def _key(x):
462
- return x.sort_key
462
+ return ",".join(
463
+ f"{self.find_bit(q).index:04d}" for q in itertools.chain(x.qargs, x.cargs)
464
+ )
463
465
 
464
466
  if key is None:
465
467
  key = _key