diff --git a/qiskit/circuit/instruction.py b/qiskit/circuit/instruction.py index 557d7df21ee1..cbb0ebd19faa 100644 --- a/qiskit/circuit/instruction.py +++ b/qiskit/circuit/instruction.py @@ -341,6 +341,7 @@ def add_decomposition(self, decomposition): sel.add_equivalence(self, decomposition) @property + @deprecate_func(since="1.3.0", removal_timeline="in Qiskit 2.0.0", is_property=True) def duration(self): """Get the duration.""" return self._duration @@ -351,6 +352,7 @@ def duration(self, duration): self._duration = duration @property + @deprecate_func(since="1.3.0", removal_timeline="in Qiskit 2.0.0", is_property=True) def unit(self): """Get the time unit of duration.""" return self._unit diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 780efba5faf1..0a151a8476e3 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -1145,17 +1145,35 @@ def __init__( for var, initial in declarations: self.add_var(var, initial) - self.duration: int | float | None = None - """The total duration of the circuit, set by a scheduling transpiler pass. Its unit is - specified by :attr:`unit`.""" - self.unit = "dt" - """The unit that :attr:`duration` is specified in.""" + self._duration = None + self._unit = "dt" self.metadata = {} if metadata is None else metadata """Arbitrary user-defined metadata for the circuit. - + Qiskit will not examine the content of this mapping, but it will pass it through the transpiler and reattach it to the output, so you can track your own metadata.""" + @property + @deprecate_func(since="1.3.0", removal_timeline="in Qiskit 2.0.0", is_property=True) + def duration(self): + """The total duration of the circuit, set by a scheduling transpiler pass. Its unit is + specified by :attr:`unit`.""" + return self._duration + + @duration.setter + def duration(self, value: int | float | None): + self._duration = value + + @property + @deprecate_func(since="1.3.0", removal_timeline="in Qiskit 2.0.0", is_property=True) + def unit(self): + """The unit that :attr:`duration` is specified in.""" + return self._unit + + @unit.setter + def unit(self, value): + self._unit = value + @classmethod def _from_circuit_data(cls, data: CircuitData, add_regs: bool = False) -> typing.Self: """A private constructor from rust space circuit data.""" diff --git a/releasenotes/notes/deprecate-unit-duration-48b76c957bac5691.yaml b/releasenotes/notes/deprecate-unit-duration-48b76c957bac5691.yaml new file mode 100644 index 000000000000..15c205c5a850 --- /dev/null +++ b/releasenotes/notes/deprecate-unit-duration-48b76c957bac5691.yaml @@ -0,0 +1,25 @@ +--- +deprecations_circuits: + - | + The :attr:`.QuantumCircuit.unit` and :attr:`.QuantumCircuit.duration` + attributes have been deprecated and will be removed in Qiskit 2.0.0. These + attributes were used to track the estimated duration and unit of that + duration to execute on the circuit. However, the values of these attributes + were always limited, as they would only be properly populated if the + transpiler were run with the correct settings. The duration was also only a + guess based on the longest path on the sum of the duration of + :class:`.DAGCircuit` and wouldn't ever correctly account for control flow + or conditionals in the circuit. + - | + The :attr:`.Instruction.duration` and :attr:`.Instruction.unit` attributes + have been deprecated and will be removed in Qiskit 2.0.0. These attributes + were used to attach a custom execution duration and unit for that duration + to an individual instruction. However, the source of truth of the duration + of a gate is the :class:`.BackendV2` :class:`.Target` which contains + the duration for each instruction supported on the backend. The duration of + an instruction is not something that's typically user adjustable and is + an immutable property of the backend. If you were previously using this + capability to experiment with different durations for gates you can + mutate the :attr:`.InstructionProperties.duration` field in a given + :class:`.Target` to set a custom duration for an instruction on a backend + (the unit is always in seconds in the :class:`.Target`). diff --git a/test/utils/base.py b/test/utils/base.py index 0038f7772ebf..7645aca04ee5 100644 --- a/test/utils/base.py +++ b/test/utils/base.py @@ -156,6 +156,28 @@ def setUpClass(cls): module="qiskit_aer", ) + # Remove these four filters in Qiskit 2.0.0 when we remove unit and duration + warnings.filterwarnings( + "ignore", + category=DeprecationWarning, + message=r".*The property.*qiskit.circuit.instruction.Instruction.unit.*", + ) + warnings.filterwarnings( + "ignore", + category=DeprecationWarning, + message=r".*The property.*qiskit.circuit.instruction.Instruction.duration.*", + ) + warnings.filterwarnings( + "ignore", + category=DeprecationWarning, + message=r".*The property.*qiskit.circuit.quantumcircuit.QuantumCircuit.unit.*", + ) + warnings.filterwarnings( + "ignore", + category=DeprecationWarning, + message=r".*The property.*qiskit.circuit.quantumcircuit.QuantumCircuit.duration.*", + ) + # Safe to remove once `FakeBackend` is removed (2.0) warnings.filterwarnings( "ignore", # If "default", it floods the CI output