mirror of https://github.com/Qiskit/qiskit.git
Add rust-native `apply_operation` methods (#13143)
* Initial: Add rust-native `apply_operation_front` and `apply_operation_back methods. - These methods allow rust users to add an operation to either the front or the back of the circuit without needing to have valid interned indices for the Qargs/Qargs of said operations. - Leverage the new methods in the existing python variants of them. * Fix: Remove extra blank space * Fix: Revert changes to python `apply_op` methods. - To avoid an ownership issue, usage of the new methods from the Python variants has been removed. - As requested, the insertion check in the rust `apply_op` has been removed. * Fix: Adapt to new `ExtraInstructionProperties` infrastructure. * Format: Change redundant iteration statement for params
This commit is contained in:
parent
87836411a8
commit
c68e80329c
|
@ -13,6 +13,7 @@
|
|||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use ahash::RandomState;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::bit_data::BitData;
|
||||
use crate::circuit_data::CircuitData;
|
||||
|
@ -26,7 +27,7 @@ use crate::error::DAGCircuitError;
|
|||
use crate::imports;
|
||||
use crate::interner::{Interned, Interner};
|
||||
use crate::operations::{Operation, OperationRef, Param, PyInstruction, StandardGate};
|
||||
use crate::packed_instruction::PackedInstruction;
|
||||
use crate::packed_instruction::{PackedInstruction, PackedOperation};
|
||||
use crate::rustworkx_core_vnext::isomorphism;
|
||||
use crate::{BitType, Clbit, Qubit, TupleLikeArg};
|
||||
|
||||
|
@ -5192,6 +5193,114 @@ impl DAGCircuit {
|
|||
Ok(new_node)
|
||||
}
|
||||
|
||||
/// Apply a [PackedOperation] to the back of the circuit.
|
||||
pub fn apply_operation_back(
|
||||
&mut self,
|
||||
py: Python,
|
||||
op: PackedOperation,
|
||||
qargs: &[Qubit],
|
||||
cargs: &[Clbit],
|
||||
params: Option<SmallVec<[Param; 3]>>,
|
||||
extra_attrs: ExtraInstructionAttributes,
|
||||
#[cfg(feature = "cache_pygates")] py_op: Option<PyObject>,
|
||||
) -> PyResult<NodeIndex> {
|
||||
self.inner_apply_op(
|
||||
py,
|
||||
op,
|
||||
qargs,
|
||||
cargs,
|
||||
params,
|
||||
extra_attrs,
|
||||
#[cfg(feature = "cache_pygates")]
|
||||
py_op,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
/// Apply a [PackedOperation] to the front of the circuit.
|
||||
pub fn apply_operation_front(
|
||||
&mut self,
|
||||
py: Python,
|
||||
op: PackedOperation,
|
||||
qargs: &[Qubit],
|
||||
cargs: &[Clbit],
|
||||
params: Option<SmallVec<[Param; 3]>>,
|
||||
extra_attrs: ExtraInstructionAttributes,
|
||||
#[cfg(feature = "cache_pygates")] py_op: Option<PyObject>,
|
||||
) -> PyResult<NodeIndex> {
|
||||
self.inner_apply_op(
|
||||
py,
|
||||
op,
|
||||
qargs,
|
||||
cargs,
|
||||
params,
|
||||
extra_attrs,
|
||||
#[cfg(feature = "cache_pygates")]
|
||||
py_op,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn inner_apply_op(
|
||||
&mut self,
|
||||
py: Python,
|
||||
op: PackedOperation,
|
||||
qargs: &[Qubit],
|
||||
cargs: &[Clbit],
|
||||
params: Option<SmallVec<[Param; 3]>>,
|
||||
extra_attrs: ExtraInstructionAttributes,
|
||||
#[cfg(feature = "cache_pygates")] py_op: Option<PyObject>,
|
||||
front: bool,
|
||||
) -> PyResult<NodeIndex> {
|
||||
// Check that all qargs are within an acceptable range
|
||||
qargs.iter().try_for_each(|qarg| {
|
||||
if qarg.0 as usize >= self.num_qubits() {
|
||||
return Err(PyValueError::new_err(format!(
|
||||
"Qubit index {} is out of range. This DAGCircuit currently has only {} qubits.",
|
||||
qarg.0,
|
||||
self.num_qubits()
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// Check that all cargs are within an acceptable range
|
||||
cargs.iter().try_for_each(|carg| {
|
||||
if carg.0 as usize >= self.num_clbits() {
|
||||
return Err(PyValueError::new_err(format!(
|
||||
"Clbit index {} is out of range. This DAGCircuit currently has only {} clbits.",
|
||||
carg.0,
|
||||
self.num_clbits()
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
#[cfg(feature = "cache_pygates")]
|
||||
let py_op = if let Some(py_op) = py_op {
|
||||
py_op.into()
|
||||
} else {
|
||||
OnceCell::new()
|
||||
};
|
||||
let packed_instruction = PackedInstruction {
|
||||
op,
|
||||
qubits: self.qargs_interner.insert(qargs),
|
||||
clbits: self.cargs_interner.insert(cargs),
|
||||
params: params.map(Box::new),
|
||||
extra_attrs,
|
||||
#[cfg(feature = "cache_pygates")]
|
||||
py_op,
|
||||
};
|
||||
|
||||
if front {
|
||||
self.push_front(py, packed_instruction)
|
||||
} else {
|
||||
self.push_back(py, packed_instruction)
|
||||
}
|
||||
}
|
||||
|
||||
fn sort_key(&self, node: NodeIndex) -> SortKeyType {
|
||||
match &self.dag[node] {
|
||||
NodeType::Operation(packed) => (
|
||||
|
|
Loading…
Reference in New Issue