Skip to content

Commit

Permalink
Merge branch 'main' into remove-deprecated-bit-properties
Browse files Browse the repository at this point in the history
  • Loading branch information
raynelfss authored Oct 23, 2024
2 parents 42bf002 + 2284f19 commit 26834dd
Show file tree
Hide file tree
Showing 146 changed files with 3,211 additions and 1,919 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion crates/circuit/src/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ impl<'py> FromPyObject<'py> for QuantumCircuitData<'py> {
Ok(QuantumCircuitData {
data: data_borrowed,
name: ob.getattr(intern!(py, "name")).ok(),
calibrations: ob.getattr(intern!(py, "calibrations"))?.extract().ok(),
calibrations: ob
.getattr(intern!(py, "_calibrations_prop"))?
.extract()
.ok(),
metadata: ob.getattr(intern!(py, "metadata")).ok(),
qregs: ob
.getattr(intern!(py, "qregs"))
Expand Down
72 changes: 68 additions & 4 deletions crates/circuit/src/dag_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ impl DAGCircuit {
let out_dict = PyDict::new_bound(py);
out_dict.set_item("name", self.name.as_ref().map(|x| x.clone_ref(py)))?;
out_dict.set_item("metadata", self.metadata.as_ref().map(|x| x.clone_ref(py)))?;
out_dict.set_item("calibrations", self.calibrations.clone())?;
out_dict.set_item("_calibrations_prop", self.calibrations.clone())?;
out_dict.set_item("qregs", self.qregs.clone_ref(py))?;
out_dict.set_item("cregs", self.cregs.clone_ref(py))?;
out_dict.set_item("global_phase", self.global_phase.clone())?;
Expand Down Expand Up @@ -648,7 +648,10 @@ impl DAGCircuit {
let dict_state = state.downcast_bound::<PyDict>(py)?;
self.name = dict_state.get_item("name")?.unwrap().extract()?;
self.metadata = dict_state.get_item("metadata")?.unwrap().extract()?;
self.calibrations = dict_state.get_item("calibrations")?.unwrap().extract()?;
self.calibrations = dict_state
.get_item("_calibrations_prop")?
.unwrap()
.extract()?;
self.qregs = dict_state.get_item("qregs")?.unwrap().extract()?;
self.cregs = dict_state.get_item("cregs")?.unwrap().extract()?;
self.global_phase = dict_state.get_item("global_phase")?.unwrap().extract()?;
Expand Down Expand Up @@ -864,8 +867,15 @@ impl DAGCircuit {
///
/// The custom pulse definition of a given gate is of the form
/// {'gate_name': {(qubits, params): schedule}}
///
/// DEPRECATED since Qiskit 1.3.0 and will be removed in Qiskit 2.0.0
#[getter]
fn get_calibrations(&self) -> HashMap<String, Py<PyDict>> {
fn get_calibrations(&self, py: Python) -> HashMap<String, Py<PyDict>> {
emit_pulse_dependency_deprecation(
py,
"property ``qiskit.dagcircuit.dagcircuit.DAGCircuit.calibrations``",
);

self.calibrations.clone()
}

Expand All @@ -874,8 +884,29 @@ impl DAGCircuit {
/// Args:
/// calibrations (dict): A dictionary of input in the format
/// {'gate_name': {(qubits, gate_params): schedule}}
///
/// DEPRECATED since Qiskit 1.3.0 and will be removed in Qiskit 2.0.0
#[setter]
fn set_calibrations(&mut self, calibrations: HashMap<String, Py<PyDict>>) {
fn set_calibrations(&mut self, py: Python, calibrations: HashMap<String, Py<PyDict>>) {
emit_pulse_dependency_deprecation(
py,
"property ``qiskit.dagcircuit.dagcircuit.DAGCircuit.calibrations``",
);

self.calibrations = calibrations;
}

// This is an alternative and Python-private path to 'get_calibration' to avoid
// deprecation warnings
#[getter(_calibrations_prop)]
fn get_calibrations_prop(&self) -> HashMap<String, Py<PyDict>> {
self.calibrations.clone()
}

// This is an alternative and Python-private path to 'set_calibration' to avoid
// deprecation warnings
#[setter(_calibrations_prop)]
fn set_calibrations_prop(&mut self, calibrations: HashMap<String, Py<PyDict>>) {
self.calibrations = calibrations;
}

Expand All @@ -898,6 +929,11 @@ impl DAGCircuit {
schedule: Py<PyAny>,
mut params: Option<Bound<'py, PyAny>>,
) -> PyResult<()> {
emit_pulse_dependency_deprecation(
py,
"method ``qiskit.dagcircuit.dagcircuit.DAGCircuit.add_calibration``",
);

if gate.is_instance(imports::GATE.get_bound(py))? {
params = Some(gate.getattr(intern!(py, "params"))?);
gate = gate.getattr(intern!(py, "name"))?;
Expand Down Expand Up @@ -955,7 +991,18 @@ def _format(operand):

/// Return True if the dag has a calibration defined for the node operation. In this
/// case, the operation does not need to be translated to the device basis.
///
/// DEPRECATED since Qiskit 1.3.0 and will be removed in Qiskit 2.0.0
fn has_calibration_for(&self, py: Python, node: PyRef<DAGOpNode>) -> PyResult<bool> {
emit_pulse_dependency_deprecation(
py,
"method ``qiskit.dagcircuit.dagcircuit.DAGCircuit.has_calibration_for``",
);

self._has_calibration_for(py, node)
}

fn _has_calibration_for(&self, py: Python, node: PyRef<DAGOpNode>) -> PyResult<bool> {
if !self
.calibrations
.contains_key(node.instruction.operation.name())
Expand Down Expand Up @@ -6960,3 +7007,20 @@ fn add_global_phase(py: Python, phase: &Param, other: &Param) -> PyResult<Param>
}

type SortKeyType<'a> = (&'a [Qubit], &'a [Clbit]);

/// Emit a Python `DeprecationWarning` for pulse-related dependencies.
fn emit_pulse_dependency_deprecation(py: Python, msg: &str) {
let _ = imports::WARNINGS_WARN.get_bound(py).call1((
PyString::new_bound(
py,
&format!(
"The {} is deprecated as of qiskit 1.3.0. It will be removed in Qiskit 2.0.0. \
The entire Qiskit Pulse package is being deprecated \
and this is a dependency on the package.",
msg
),
),
py.get_type_bound::<PyDeprecationWarning>(),
1,
));
}
2 changes: 2 additions & 0 deletions qiskit/assembler/assemble_schedules.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
from qiskit.pulse import instructions, transforms, library, schedule, channels
from qiskit.qobj import utils as qobj_utils, converters
from qiskit.qobj.converters.pulse_instruction import ParametricPulseShapes
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency


@deprecate_pulse_dependency
def assemble_schedules(
schedules: List[
Union[
Expand Down
32 changes: 28 additions & 4 deletions qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from qiskit.circuit.parameter import Parameter
from qiskit.circuit.exceptions import CircuitError
from qiskit.utils import deprecate_func
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
from . import _classical_resource_map
from .controlflow import ControlFlowOp, _builder_utils
from .controlflow.builder import CircuitScopeInterface, ControlFlowBuilderBlock
Expand All @@ -70,6 +71,7 @@
from .delay import Delay
from .store import Store


if typing.TYPE_CHECKING:
import qiskit # pylint: disable=cyclic-import
from qiskit.transpiler.layout import TranspileLayout # pylint: disable=cyclic-import
Expand Down Expand Up @@ -1339,34 +1341,55 @@ def op_start_times(self) -> list[int]:
return self._op_start_times

@property
@deprecate_pulse_dependency(is_property=True)
def calibrations(self) -> dict:
"""Return calibration dictionary.
The custom pulse definition of a given gate is of the form
``{'gate_name': {(qubits, params): schedule}}``
"""
return dict(self._calibrations)
return self._calibrations_prop

@calibrations.setter
@deprecate_pulse_dependency(is_property=True)
def calibrations(self, calibrations: dict):
"""Set the circuit calibration data from a dictionary of calibration definition.
Args:
calibrations (dict): A dictionary of input in the format
``{'gate_name': {(qubits, gate_params): schedule}}``
"""
self._calibrations_prop = calibrations

@property
def _calibrations_prop(self) -> dict:
"""An alternative private path to the `calibrations` property for
avoiding deprecation warnings."""
return dict(self._calibrations)

@_calibrations_prop.setter
def _calibrations_prop(self, calibrations: dict):
"""An alternative private path to the `calibrations` property for
avoiding deprecation warnings."""
self._calibrations = defaultdict(dict, calibrations)

@deprecate_pulse_dependency
def has_calibration_for(self, instruction: CircuitInstruction | tuple):
"""Return True if the circuit has a calibration defined for the instruction context. In this
case, the operation does not need to be translated to the device basis.
"""

return self._has_calibration_for(instruction)

def _has_calibration_for(self, instruction: CircuitInstruction | tuple):
"""An alternative private path to the `has_calibration_for` method for
avoiding deprecation warnings."""
if isinstance(instruction, CircuitInstruction):
operation = instruction.operation
qubits = instruction.qubits
else:
operation, qubits, _ = instruction
if not self.calibrations or operation.name not in self.calibrations:
if not self._calibrations_prop or operation.name not in self._calibrations_prop:
return False
qubits = tuple(self.qubits.index(qubit) for qubit in qubits)
params = []
Expand All @@ -1376,7 +1399,7 @@ def has_calibration_for(self, instruction: CircuitInstruction | tuple):
else:
params.append(p)
params = tuple(params)
return (qubits, params) in self.calibrations[operation.name]
return (qubits, params) in self._calibrations_prop[operation.name]

@property
def metadata(self) -> dict:
Expand Down Expand Up @@ -2017,7 +2040,7 @@ def replace_var(var: expr.Var, cache: Mapping[expr.Var, expr.Var]) -> expr.Var:
)
edge_map.update(zip(other.clbits, dest._cbit_argument_conversion(clbits)))

for gate, cals in other.calibrations.items():
for gate, cals in other._calibrations_prop.items():
dest._calibrations[gate].update(cals)

dest.duration = None
Expand Down Expand Up @@ -6477,6 +6500,7 @@ def continue_loop(self) -> InstructionSet:
ContinueLoopOp(self.num_qubits, self.num_clbits), self.qubits, self.clbits, copy=False
)

@deprecate_pulse_dependency
def add_calibration(
self,
gate: Union[Gate, str],
Expand Down
2 changes: 2 additions & 0 deletions qiskit/compiler/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from qiskit.scheduler.config import ScheduleConfig
from qiskit.scheduler.schedule_circuit import schedule_circuit
from qiskit.utils.parallel import parallel_map
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency

logger = logging.getLogger(__name__)

Expand All @@ -35,6 +36,7 @@ def _log_schedule_time(start_time, end_time):
logger.info(log_msg)


@deprecate_pulse_dependency(moving_to_dynamics=True)
def schedule(
circuits: Union[QuantumCircuit, List[QuantumCircuit]],
backend: Optional[Backend] = None,
Expand Down
2 changes: 2 additions & 0 deletions qiskit/compiler/sequencer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
from qiskit.pulse import InstructionScheduleMap, Schedule
from qiskit.scheduler import ScheduleConfig
from qiskit.scheduler.sequence import sequence as _sequence
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency


@deprecate_pulse_dependency(moving_to_dynamics=True)
def sequence(
scheduled_circuits: Union[QuantumCircuit, List[QuantumCircuit]],
backend: Optional[Backend] = None,
Expand Down
4 changes: 3 additions & 1 deletion qiskit/compiler/transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.target import Target
from qiskit.utils.deprecate_pulse import deprecate_pulse_arg

logger = logging.getLogger(__name__)

_CircuitT = TypeVar("_CircuitT", bound=Union[QuantumCircuit, List[QuantumCircuit]])


@deprecate_pulse_arg("inst_map", predicate=lambda inst_map: inst_map is not None)
def transpile( # pylint: disable=too-many-return-statements
circuits: _CircuitT,
backend: Optional[Backend] = None,
Expand Down Expand Up @@ -104,7 +106,7 @@ def transpile( # pylint: disable=too-many-return-statements
will override the backend's.
basis_gates: List of basis gate names to unroll to
(e.g: ``['u1', 'u2', 'u3', 'cx']``). If ``None``, do not unroll.
inst_map: Mapping of unrolled gates to pulse schedules. If this is not provided,
inst_map: DEPRECATED. Mapping of unrolled gates to pulse schedules. If this is not provided,
transpiler tries to get from the backend. If any user defined calibration
is found in the map and this is used in a circuit, transpiler attaches
the custom gate definition to the circuit. This enables one to flexibly
Expand Down
2 changes: 1 addition & 1 deletion qiskit/converters/circuit_to_dagdependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ def circuit_to_dagdependency(circuit, create_preds_and_succs=True):
dagdependency._add_predecessors()
dagdependency._add_successors()

dagdependency.calibrations = circuit.calibrations
dagdependency._calibrations = circuit._calibrations_prop

return dagdependency
2 changes: 1 addition & 1 deletion qiskit/converters/circuit_to_dagdependency_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def _circuit_to_dagdependency_v2(circuit):
dagdependency = _DAGDependencyV2()
dagdependency.name = circuit.name
dagdependency.metadata = circuit.metadata
dagdependency.calibrations = circuit.calibrations
dagdependency._calibrations = circuit._calibrations_prop
dagdependency.global_phase = circuit.global_phase

dagdependency.add_qubits(circuit.qubits)
Expand Down
2 changes: 1 addition & 1 deletion qiskit/converters/dag_to_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def dag_to_circuit(dag, copy_operations=True):
for var in dag.iter_declared_vars():
circuit.add_uninitialized_var(var)
circuit.metadata = dag.metadata
circuit.calibrations = dag.calibrations
circuit._calibrations_prop = dag._calibrations_prop

circuit._data = circuit_data

Expand Down
2 changes: 1 addition & 1 deletion qiskit/converters/dag_to_dagdependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ def dag_to_dagdependency(dag, create_preds_and_succs=True):

# copy metadata
dagdependency.global_phase = dag.global_phase
dagdependency.calibrations = dag.calibrations
dagdependency._calibrations_prop = dag._calibrations_prop

return dagdependency
2 changes: 1 addition & 1 deletion qiskit/converters/dag_to_dagdependency_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def _dag_to_dagdependency_v2(dag):
dagdependency.name = dag.name
dagdependency.metadata = dag.metadata
dagdependency.global_phase = dag.global_phase
dagdependency.calibrations = dag.calibrations
dagdependency.calibrations = dag._calibrations_prop

dagdependency.add_qubits(dag.qubits)
dagdependency.add_clbits(dag.clbits)
Expand Down
6 changes: 5 additions & 1 deletion qiskit/converters/dagdependency_to_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ def dagdependency_to_circuit(dagdependency):
)
circuit.metadata = dagdependency.metadata

circuit.calibrations = dagdependency.calibrations
if hasattr(dagdependency, "_calibrations_prop"):
circuit._calibrations_prop = dagdependency._calibrations_prop
else:
# This can be _DAGDependencyV2
circuit._calibrations_prop = dagdependency.calibrations

for node in dagdependency.topological_nodes():
circuit._append(CircuitInstruction(node.op.copy(), node.qargs, node.cargs))
Expand Down
7 changes: 6 additions & 1 deletion qiskit/converters/dagdependency_to_dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

"""Helper function for converting a dag dependency to a dag circuit"""
from qiskit.dagcircuit.dagcircuit import DAGCircuit
from qiskit.dagcircuit.dagdependency import DAGDependency


def dagdependency_to_dag(dagdependency):
Expand Down Expand Up @@ -44,6 +45,10 @@ def dagdependency_to_dag(dagdependency):

# copy metadata
dagcircuit.global_phase = dagdependency.global_phase
dagcircuit.calibrations = dagdependency.calibrations
if isinstance(dagdependency, DAGDependency):
dagcircuit._calibrations_prop = dagdependency._calibrations_prop
else:
# This can be _DAGDependencyV2
dagcircuit._calibrations_prop = dagdependency.calibrations

return dagcircuit
Loading

0 comments on commit 26834dd

Please sign in to comment.