Skip to content

Commit

Permalink
Resolve _accelerate errors, pt. 1.
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinhartman committed Apr 2, 2024
1 parent fe0bb69 commit ca1ad54
Show file tree
Hide file tree
Showing 16 changed files with 66 additions and 115 deletions.
2 changes: 1 addition & 1 deletion crates/accelerate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn getenv_use_multiple_threads() -> bool {
}

#[pymodule]
fn _accelerate(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
fn _accelerate(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(nlayout::nlayout))?;
m.add_wrapped(wrap_pymodule!(stochastic_swap::stochastic_swap))?;
m.add_wrapped(wrap_pymodule!(sabre_swap::sabre_swap))?;
Expand Down
23 changes: 12 additions & 11 deletions crates/accelerate/src/quantum_circuit/circuit_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

use crate::quantum_circuit::circuit_instruction::CircuitInstruction;
use crate::quantum_circuit::intern_context::{BitType, IndexType, InternContext};
use crate::quantum_circuit::py_ext;
use crate::utils::SliceOrInt;
use hashbrown::HashMap;
use pyo3::exceptions::{PyIndexError, PyKeyError, PyRuntimeError, PyValueError};
Expand Down Expand Up @@ -70,10 +69,10 @@ impl PartialEq for BitAsKey {
self.bit.is(&other.bit)
|| Python::with_gil(|py| {
self.bit
.as_ref(py)
.bind(py)
.repr()
.unwrap()
.eq(other.bit.as_ref(py).repr().unwrap())
.eq(other.bit.bind(py).repr().unwrap())
.unwrap()
})
}
Expand Down Expand Up @@ -172,8 +171,8 @@ impl CircuitData {
clbits_native: Vec::new(),
qubit_indices_native: HashMap::new(),
clbit_indices_native: HashMap::new(),
qubits: PyList::empty(py).into_py(py),
clbits: PyList::empty(py).into_py(py),
qubits: PyList::empty_bound(py).unbind(),
clbits: PyList::empty_bound(py).unbind(),
};
if let Some(qubits) = qubits {
for bit in qubits.iter()? {
Expand Down Expand Up @@ -860,22 +859,24 @@ impl CircuitData {
py,
CircuitInstruction {
operation: inst.op.clone_ref(py),
qubits: py_ext::tuple_new(
qubits: PyTuple::new_bound(
py,
self.intern_context
.lookup(inst.qubits_id)
.iter()
.map(|i| self.qubits_native[*i as usize].clone_ref(py))
.collect(),
),
clbits: py_ext::tuple_new(
.collect::<Vec<_>>(),
)
.unbind(),
clbits: PyTuple::new_bound(
py,
self.intern_context
.lookup(inst.clbits_id)
.iter()
.map(|i| self.clbits_native[*i as usize].clone_ref(py))
.collect(),
),
.collect::<Vec<_>>(),
)
.unbind(),
},
)
}
Expand Down
72 changes: 34 additions & 38 deletions crates/accelerate/src/quantum_circuit/circuit_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.

use crate::quantum_circuit::py_ext;
use pyo3::basic::CompareOp;
use pyo3::prelude::*;
use pyo3::types::{PyList, PyTuple};
Expand Down Expand Up @@ -70,26 +69,27 @@ impl CircuitInstruction {
pub fn new(
py: Python<'_>,
operation: PyObject,
qubits: Option<&PyAny>,
clbits: Option<&PyAny>,
qubits: Option<&Bound<PyAny>>,
clbits: Option<&Bound<PyAny>>,
) -> PyResult<Self> {
fn as_tuple(py: Python<'_>, seq: Option<&PyAny>) -> PyResult<Py<PyTuple>> {
fn as_tuple(py: Python<'_>, seq: Option<&Bound<PyAny>>) -> PyResult<Py<PyTuple>> {
match seq {
None => Ok(py_ext::tuple_new_empty(py)),
None => Ok(PyTuple::empty_bound(py).unbind()),
Some(seq) => {
if seq.is_instance_of::<PyTuple>() {
Ok(seq.downcast_exact::<PyTuple>()?.into_py(py))
} else if seq.is_instance_of::<PyList>() {
let seq = seq.downcast_exact::<PyList>()?;
Ok(py_ext::tuple_from_list(seq))
Ok(seq.to_tuple().unbind())
} else {
// New tuple from iterable.
Ok(py_ext::tuple_new(
Ok(PyTuple::new_bound(
py,
seq.iter()?
.map(|o| Ok(o?.into_py(py)))
.map(|o| Ok(o?.unbind()))
.collect::<PyResult<Vec<PyObject>>>()?,
))
)
.unbind())
}
}
}
Expand Down Expand Up @@ -118,27 +118,27 @@ impl CircuitInstruction {
&self,
py: Python<'_>,
operation: Option<PyObject>,
qubits: Option<&PyAny>,
clbits: Option<&PyAny>,
qubits: Option<&Bound<PyAny>>,
clbits: Option<&Bound<PyAny>>,
) -> PyResult<Self> {
CircuitInstruction::new(
py,
operation.unwrap_or_else(|| self.operation.clone_ref(py)),
Some(qubits.unwrap_or_else(|| self.qubits.as_ref(py))),
Some(clbits.unwrap_or_else(|| self.clbits.as_ref(py))),
Some(qubits.unwrap_or_else(|| self.qubits.bind(py))),
Some(clbits.unwrap_or_else(|| self.clbits.bind(py))),
)
}

fn __getstate__(&self, py: Python<'_>) -> PyObject {
(
self.operation.as_ref(py),
self.qubits.as_ref(py),
self.clbits.as_ref(py),
self.operation.bind(py),
self.qubits.bind(py),
self.clbits.bind(py),
)
.into_py(py)
}

fn __setstate__(&mut self, _py: Python<'_>, state: &PyTuple) -> PyResult<()> {
fn __setstate__(&mut self, _py: Python<'_>, state: &Bound<PyTuple>) -> PyResult<()> {
self.operation = state.get_item(0)?.extract()?;
self.qubits = state.get_item(1)?.extract()?;
self.clbits = state.get_item(2)?.extract()?;
Expand All @@ -154,8 +154,8 @@ impl CircuitInstruction {
.into_py(py))
}

pub fn __repr__(self_: &PyCell<Self>, py: Python<'_>) -> PyResult<String> {
let type_name = self_.get_type().name()?;
pub fn __repr__(self_: &Bound<Self>, py: Python<'_>) -> PyResult<String> {
let type_name = self_.get_type().qualname()?;
let r = self_.try_borrow()?;
Ok(format!(
"{}(\
Expand All @@ -164,9 +164,9 @@ impl CircuitInstruction {
, clbits={}\
)",
type_name,
r.operation.as_ref(py).repr()?,
r.qubits.as_ref(py).repr()?,
r.clbits.as_ref(py).repr()?
r.operation.bind(py).repr()?,
r.qubits.bind(py).repr()?,
r.clbits.bind(py).repr()?
))
}

Expand All @@ -177,7 +177,7 @@ impl CircuitInstruction {
// like that via unpacking or similar. That means that the `parameters` field is completely
// absent, and the qubits and clbits must be converted to lists.
pub fn _legacy_format(&self, py: Python<'_>) -> PyObject {
PyTuple::new(
PyTuple::new_bound(
py,
[
self.operation.as_ref(py),
Expand All @@ -188,12 +188,8 @@ impl CircuitInstruction {
.into_py(py)
}

pub fn __getitem__(&self, py: Python<'_>, key: &PyAny) -> PyResult<PyObject> {
Ok(self
._legacy_format(py)
.as_ref(py)
.get_item(key)?
.into_py(py))
pub fn __getitem__(&self, py: Python<'_>, key: &Bound<PyAny>) -> PyResult<PyObject> {
Ok(self._legacy_format(py).bind(py).get_item(key)?.into_py(py))
}

pub fn __iter__(&self, py: Python<'_>) -> PyResult<PyObject> {
Expand All @@ -205,35 +201,35 @@ impl CircuitInstruction {
}

pub fn __richcmp__(
self_: &PyCell<Self>,
other: &PyAny,
self_: &Bound<Self>,
other: &Bound<PyAny>,
op: CompareOp,
py: Python<'_>,
) -> PyResult<PyObject> {
fn eq(
py: Python<'_>,
self_: &PyCell<CircuitInstruction>,
other: &PyAny,
self_: &Bound<CircuitInstruction>,
other: &Bound<PyAny>,
) -> PyResult<Option<bool>> {
if self_.is(other) {
return Ok(Some(true));
}

let self_ = self_.try_borrow()?;
if other.is_instance_of::<CircuitInstruction>() {
let other: PyResult<&PyCell<CircuitInstruction>> = other.extract();
let other: PyResult<Bound<CircuitInstruction>> = other.extract();
return other.map_or(Ok(Some(false)), |v| {
let v = v.try_borrow()?;
Ok(Some(
self_.clbits.as_ref(py).eq(v.clbits.as_ref(py))?
&& self_.qubits.as_ref(py).eq(v.qubits.as_ref(py))?
&& self_.operation.as_ref(py).eq(v.operation.as_ref(py))?,
self_.clbits.bind(py).eq(v.clbits.bind(py))?
&& self_.qubits.bind(py).eq(v.qubits.bind(py))?
&& self_.operation.bind(py).eq(v.operation.bind(py))?,
))
});
}

if other.is_instance_of::<PyTuple>() {
return Ok(Some(self_._legacy_format(py).as_ref(py).eq(other)?));
return Ok(Some(self_._legacy_format(py).bind(py).eq(other)?));
}

Ok(None)
Expand Down
3 changes: 1 addition & 2 deletions crates/accelerate/src/quantum_circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
pub mod circuit_data;
pub mod circuit_instruction;
pub mod intern_context;
mod py_ext;

use pyo3::prelude::*;

#[pymodule]
pub fn quantum_circuit(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn quantum_circuit(m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<circuit_data::CircuitData>()?;
m.add_class::<circuit_instruction::CircuitInstruction>()?;
Ok(())
Expand Down
45 changes: 0 additions & 45 deletions crates/accelerate/src/quantum_circuit/py_ext.rs

This file was deleted.

2 changes: 1 addition & 1 deletion crates/accelerate/src/results/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pymodule]
pub fn results(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn results(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(marginalization::marginal_counts))?;
m.add_wrapped(wrap_pyfunction!(marginalization::marginal_distribution))?;
m.add_wrapped(wrap_pyfunction!(marginalization::marginal_memory))?;
Expand Down
2 changes: 1 addition & 1 deletion crates/accelerate/src/sabre_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ fn layout_trial(
}

#[pymodule]
pub fn sabre_layout(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn sabre_layout(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sabre_layout_and_routing))?;
Ok(())
}
2 changes: 1 addition & 1 deletion crates/accelerate/src/sabre_swap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ fn choose_best_swap(
}

#[pymodule]
pub fn sabre_swap(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn sabre_swap(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(build_swap_map))?;
m.add_class::<Heuristic>()?;
m.add_class::<NeighborTable>()?;
Expand Down
8 changes: 4 additions & 4 deletions crates/accelerate/src/sabre_swap/neighbor_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,22 @@ impl NeighborTable {
}

fn __getstate__(&self, py: Python<'_>) -> Py<PyList> {
PyList::new(
PyList::new_bound(
py,
self.neighbors
.iter()
.map(|v| PyList::new(py, v.iter()).to_object(py)),
.map(|v| PyList::new_bound(py, v.iter()).to_object(py)),
)
.into()
}

fn __setstate__(&mut self, state: &PyList) -> PyResult<()> {
fn __setstate__(&mut self, state: &Bound<PyList>) -> PyResult<()> {
self.neighbors = state
.iter()
.map(|v| {
v.downcast::<PyList>()?
.iter()
.map(PyAny::extract)
.map(|b| b.extract())
.collect::<PyResult<_>>()
})
.collect::<PyResult<_>>()?;
Expand Down
2 changes: 1 addition & 1 deletion crates/accelerate/src/sampled_exp_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub fn sampled_expval_complex(
}

#[pymodule]
pub fn sampled_exp_val(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn sampled_exp_val(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sampled_expval_float))?;
m.add_wrapped(wrap_pyfunction!(sampled_expval_complex))?;
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/accelerate/src/sparse_pauli_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ fn decompose_dense_inner(
}

#[pymodule]
pub fn sparse_pauli_op(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn sparse_pauli_op(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(unordered_unique))?;
m.add_wrapped(wrap_pyfunction!(decompose_dense))?;
m.add_class::<ZXPaulis>()?;
Expand Down
2 changes: 1 addition & 1 deletion crates/accelerate/src/stochastic_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ pub fn swap_trials(
}

#[pymodule]
pub fn stochastic_swap(_py: Python, m: &PyModule) -> PyResult<()> {
pub fn stochastic_swap(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(swap_trials))?;
m.add_class::<EdgeCollection>()?;
Ok(())
Expand Down
Loading

0 comments on commit ca1ad54

Please sign in to comment.