Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions crates/accelerate/src/circuit_duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

use qiskit_circuit::dag_circuit::{DAGCircuit, NodeType, Wire};
use qiskit_circuit::dag_circuit::{DAGCircuit, NodeType, PyDAGCircuit, Wire};
use qiskit_circuit::operations::{DelayUnit, Operation, OperationRef, Param, StandardInstruction};

use qiskit_transpiler::target::Target;
Expand All @@ -25,7 +25,12 @@ use rustworkx_core::petgraph::stable_graph::StableDiGraph;
use rustworkx_core::petgraph::visit::{EdgeRef, IntoEdgeReferences};

/// Estimate the duration of a scheduled circuit in seconds
#[pyfunction]
#[pyfunction(name = "compute_estimated_duration")]
fn py_compute_estimated_duration(dag: &PyDAGCircuit, target: &Target) -> PyResult<f64> {
compute_estimated_duration(dag.try_read()?, target)
}

/// Estimate the duration of a scheduled circuit in seconds
pub(crate) fn compute_estimated_duration(dag: &DAGCircuit, target: &Target) -> PyResult<f64> {
let dt = target.dt;

Expand Down Expand Up @@ -98,6 +103,6 @@ pub(crate) fn compute_estimated_duration(dag: &DAGCircuit, target: &Target) -> P
}

pub fn compute_duration(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(compute_estimated_duration))?;
m.add_wrapped(wrap_pyfunction!(py_compute_estimated_duration))?;
Ok(())
}
2 changes: 1 addition & 1 deletion crates/accelerate/src/twirling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ fn generate_twirled_circuit(
}
}
if let Some(optimizer_target) = optimizer_target {
let mut dag = DAGCircuit::from_circuit_data(&out_circ, false, None, None, None, None)?;
let mut dag = DAGCircuit::from_circuit_data(&out_circ, false, None, None)?;
let state = Optimize1qGatesDecompositionState::new(
optimizer_target.num_qubits.unwrap_or(0) as usize,
);
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2542,7 +2542,7 @@ pub unsafe extern "C" fn qk_circuit_to_dag(circuit: *const CircuitData) -> *mut
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { const_ptr_as_ref(circuit) };

let dag = DAGCircuit::from_circuit_data(circuit, true, None, None, None, None)
let dag = DAGCircuit::from_circuit_data(circuit, true, None, None)
.expect("Error occurred while converting CircuitData to DAGCircuit");

Box::into_raw(Box::new(dag))
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ pub unsafe extern "C" fn qk_control_flow_switch_case_labels_clear(labels: *mut C
if !labels.labels.is_null() && labels.num_labels > 0 {
drop(unsafe {
// SAFETY: Per document unsafe, label is a valid CSwitchCaseLabels
Box::from_raw(std::slice::from_raw_parts_mut(
Box::from_raw(std::ptr::slice_from_raw_parts_mut(
labels.labels as *mut u64,
labels.num_labels,
))
Expand Down
14 changes: 10 additions & 4 deletions crates/cext/src/dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use smallvec::smallvec;
use crate::exit_codes::ExitCode;
use qiskit_circuit::bit::{ClassicalRegister, QuantumRegister};
use qiskit_circuit::circuit_data::CircuitData;
use qiskit_circuit::dag_circuit::{DAGCircuit, DAGError, NodeIndex, NodeType};
use qiskit_circuit::dag_circuit::{DAGCircuit, DAGError, NodeIndex, NodeType, PyDAGCircuit};
use qiskit_circuit::instruction::Parameters;
use qiskit_circuit::operations::{
ArrayType, Operation, OperationRef, Param, StandardGate, StandardInstruction, UnitaryGate,
Expand Down Expand Up @@ -1867,7 +1867,7 @@ pub unsafe extern "C" fn qk_dag_to_python(dag: *mut DAGCircuit) -> *mut ::pyo3::
let py = unsafe { ::pyo3::Python::assume_attached() };
// SAFETY: per documentation, `dag` points to owned and valid data.
let dag = unsafe { Box::from_raw(dag) };
match ::pyo3::Bound::new(py, *dag) {
match ::pyo3::Bound::new(py, PyDAGCircuit::from(*dag)) {
Ok(ob) => ob.into_ptr(),
Err(e) => {
e.restore(py);
Expand Down Expand Up @@ -1904,7 +1904,13 @@ pub unsafe extern "C" fn qk_dag_borrow_from_python(
) -> *mut DAGCircuit {
// SAFETY: per documentation, we are attached to a Python interpreter, and `ob` points to a
// valid PyObject.
unsafe { crate::py::borrow_mut(::pyo3::Python::assume_attached(), ob) }
unsafe {
crate::py::borrow_map_mut::<PyDAGCircuit, DAGCircuit>(
::pyo3::Python::assume_attached(),
ob,
|_py, dag| dag.try_write(),
)
}
}

/// @ingroup QkDag
Expand Down Expand Up @@ -1938,6 +1944,6 @@ pub unsafe extern "C" fn qk_dag_convert_from_python(
// SAFETY: per documentation, we are attached to a Python interpreter, `object` is a valid
// pointer to a PyObject, and `address` points to enough space to write a pointer.
unsafe {
crate::py::convert_mut::<DAGCircuit>(::pyo3::Python::assume_attached(), object, address)
crate::py::convert_mut::<PyDAGCircuit>(::pyo3::Python::assume_attached(), object, address)
}
}
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/basis_translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_basis_translator(
// SAFETY: Per documentation, the pointer is non-null and aligned.
let target = unsafe { const_ptr_as_ref(target) };

let dag = DAGCircuit::from_circuit_data(circ_from_ptr, false, None, None, None, None)
let dag = DAGCircuit::from_circuit_data(circ_from_ptr, false, None, None)
.expect("Circuit to DAG conversion failed");

let mut equiv_lib = generate_standard_equivalence_library();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_commutative_cancellation(
"Invalid value provided for approximation degree, only NAN or values between 0.0 and 1.0 inclusive are valid"
);
}
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(_) => panic!("Internal circuit -> DAG conversion failed"),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/consolidate_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_consolidate_blocks(
} else {
approximation_degree
};
let mut circ_as_dag = DAGCircuit::from_circuit_data(circuit, true, None, None, None, None)
let mut circ_as_dag = DAGCircuit::from_circuit_data(circuit, true, None, None)
.expect("Error while converting from CircuitData to DAGCircuit.");

// Call the pass
Expand Down
16 changes: 12 additions & 4 deletions crates/cext/src/transpiler/passes/convert_to_pauli_rotations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.

use qiskit_circuit::{circuit_data::CircuitData, dag_circuit::DAGCircuit};
use qiskit_circuit::{
circuit_data::CircuitData,
dag_circuit::{DAGCircuit, PyDAGCircuit},
};
use qiskit_transpiler::passes::py_convert_to_pauli_rotations;

use crate::pointers::mut_ptr_as_ref;
Expand All @@ -35,11 +38,16 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_convert_to_pauli_rotation
) {
// SAFETY: The user guarantees the pointer is safe to read.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(_) => panic!("Internal Circuit -> DAG conversion failed"),
};
let out = py_convert_to_pauli_rotations(&dag).expect("Failed running PBC conversion.");
let as_py_dag: PyDAGCircuit = dag.into();
let out = py_convert_to_pauli_rotations(&as_py_dag).expect("Failed running PBC conversion.");
// If a DAG is returned, the circuit has been modified. Else just leave it as is.
*circuit = CircuitData::from_dag_ref(&out).expect("Internal DAG -> Circuit conversion failed");
*circuit = CircuitData::from_dag_ref(
out.try_read()
.expect("Nothing else should be reading the dag"),
)
.expect("Internal DAG -> Circuit conversion failed");
}
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/elide_permutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_elide_permutations(
) -> *mut TranspileLayout {
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(_e) => panic!("Internal circuit to DAG conversion failed."),
};
Expand Down
4 changes: 2 additions & 2 deletions crates/cext/src/transpiler/passes/gate_direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_check_gate_direction(
let circuit = unsafe { const_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };

let dag = DAGCircuit::from_circuit_data(circuit, false, None, None, None, None)
let dag = DAGCircuit::from_circuit_data(circuit, false, None, None)
.expect("Circuit to DAG conversion failed");

check_direction_target(&dag, target).expect("Unexpected error occurred in CheckGateDirection")
Expand All @@ -64,7 +64,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_gate_direction(
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };

let mut dag = DAGCircuit::from_circuit_data(circuit, false, None, None, None, None)
let mut dag = DAGCircuit::from_circuit_data(circuit, false, None, None)
.expect("Circuit to DAG conversion failed");

fix_direction_target(&mut dag, target).expect("Unexpected error occurred in GateDirection");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_inverse_cancellation(
) {
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(_) => panic!("Internal Circuit -> DAG conversion failed"),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_litinski_transformation(
) {
// SAFETY: The user guarantees the pointer is safe to read.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let dag = DAGCircuit::from_circuit_data(circuit, false, None, None, None, None)
let dag = DAGCircuit::from_circuit_data(circuit, false, None, None)
.expect("Internal Circuit -> DAG conversion failed");

let maybe_out =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_optimize_1q_sequences(
let circuit = unsafe { mut_ptr_as_ref(circuit) };

// Convert the circuit to a DAG.
let mut circuit_as_dag = DAGCircuit::from_circuit_data(circuit, false, None, None, None, None)
let mut circuit_as_dag = DAGCircuit::from_circuit_data(circuit, false, None, None)
.expect("Error while converting the circuit to a dag.");

let state = Optimize1qGatesDecompositionState::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_remove_diagonal_gates_bef
) {
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let mut dag = DAGCircuit::from_circuit_data(circuit, false, None, None, None, None)
let mut dag = DAGCircuit::from_circuit_data(circuit, false, None, None)
.expect("Circuit to DAG conversion failed");
run_remove_diagonal_before_measure(&mut dag);
*circuit = CircuitData::from_dag_ref(&dag).expect("DAG to Circuit conversion failed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_remove_identity_equivalen
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(e) => panic!("{}", e),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/sabre_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_sabre_layout(
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };
let options = unsafe { const_ptr_as_ref(options) };
let mut dag = DAGCircuit::from_circuit_data(circuit, false, None, None, None, None)
let mut dag = DAGCircuit::from_circuit_data(circuit, false, None, None)
.unwrap_or_else(|_| panic!("Internal circuit to DAG conversion failed."));
let heuristic = heuristic::Heuristic::new(
Some(heuristic::BasicHeuristic::new(
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/split_2q_unitaries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_split_2q_unitaries(
) -> *mut TranspileLayout {
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let mut dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(_e) => panic!("Internal circuit -> DAG conversion failed."),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/two_qubit_peephole.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_2q_peephole_optimization(
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(e) => panic!("{}", e),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/cext/src/transpiler/passes/unitary_synthesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_unitary_synthesis(
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { mut_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(e) => panic!("{}", e),
};
Expand Down
4 changes: 2 additions & 2 deletions crates/cext/src/transpiler/passes/vf2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_vf2_layout_average(
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { const_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(e) => panic!("{}", e),
};
Expand Down Expand Up @@ -443,7 +443,7 @@ pub unsafe extern "C" fn qk_transpiler_pass_standalone_vf2_layout_exact(
// SAFETY: Per documentation, the pointer is non-null and aligned.
let circuit = unsafe { const_ptr_as_ref(circuit) };
let target = unsafe { const_ptr_as_ref(target) };
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None, None, None) {
let dag = match DAGCircuit::from_circuit_data(circuit, false, None, None) {
Ok(dag) => dag,
Err(e) => panic!("{}", e),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/circuit/src/circuit_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3493,7 +3493,7 @@ mod test {
let other = qc.clone();
check(&qc, &other);
let roundtrip = py_dag_to_circuit(
&DAGCircuit::from_circuit_data(&qc, false, None, None, None, None)?,
&DAGCircuit::from_circuit_data(&qc, false, None, None)?.into(),
false,
)?;
check(&qc, &roundtrip);
Expand Down
3 changes: 1 addition & 2 deletions crates/circuit/src/circuit_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,7 @@ impl CircuitBlock for CircuitData {
}
impl CircuitBlock for DAGCircuit {
fn extract_py_block(ob: Bound<PyCircuitData>) -> PyResult<Self> {
Self::from_circuit_data(&ob.borrow().inner, false, None, None, None, None)
.map_err(Into::into)
Self::from_circuit_data(&ob.borrow().inner, false, None, None).map_err(Into::into)
}
}
impl CircuitBlock for NoBlocks {
Expand Down
14 changes: 7 additions & 7 deletions crates/circuit/src/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use pyo3::prelude::*;

use crate::bit::{ShareableClbit, ShareableQubit};
use crate::circuit_data::{CircuitData, CircuitDataError, PyCircuitData};
use crate::dag_circuit::DAGCircuit;
use crate::dag_circuit::PyDAGCircuit;
use crate::{Clbit, Qubit};

/// An extractable representation of a QuantumCircuit reserved only for
Expand Down Expand Up @@ -52,7 +52,7 @@ pub fn circuit_to_dag(
copy_operations: bool,
qubit_order: Option<Vec<ShareableQubit>>,
clbit_order: Option<Vec<ShareableClbit>>,
) -> PyResult<DAGCircuit> {
) -> PyResult<PyDAGCircuit> {
// Convert ShareableQubit/ShareableClbit to internal indices
let qubit_indices = qubit_order
.as_ref()
Expand Down Expand Up @@ -96,7 +96,7 @@ pub fn circuit_to_dag(
})
.transpose()?;

DAGCircuit::from_circuit(
PyDAGCircuit::from_circuit(
quantum_circuit,
copy_operations,
qubit_indices,
Expand All @@ -105,20 +105,20 @@ pub fn circuit_to_dag(
.map_err(Into::into)
}

/// Convert a :class:`.DAGCircuit` to a :class:`.PyCircuitData`.
/// Convert a :class:`.DAGCircuit` to a :class:`.CircuitData`.
///
/// `copy_operations` refers to Python-space operations; if set true, we'll attach to a Python
/// interpreter to ensure we can copy any objects. If we're not running in a Python context, pass
/// `false` to that argument (or better, in Rust space, use `CircuitData::from_dag_ref`).
#[pyfunction(name = "dag_to_circuit", signature = (dag, copy_operations = true))]
pub fn py_dag_to_circuit(
dag: &DAGCircuit,
dag: &PyDAGCircuit,
copy_operations: bool,
) -> Result<PyCircuitData, CircuitDataError> {
if copy_operations {
Python::attach(|py| CircuitData::from_dag_ref_deepcopy(py, dag))
Python::attach(|py| CircuitData::from_dag_ref_deepcopy(py, dag.try_read()?))
} else {
CircuitData::from_dag_ref(dag)
CircuitData::from_dag_ref(dag.try_read()?)
}
.map(PyCircuitData::from)
}
Expand Down
Loading