Skip to content

Commit

Permalink
Merge branch 'main' into extend-params
Browse files Browse the repository at this point in the history
  • Loading branch information
raynelfss authored Jul 1, 2024
2 parents 8598628 + 5deed7a commit d5db780
Show file tree
Hide file tree
Showing 65 changed files with 2,277 additions and 1,067 deletions.
44 changes: 19 additions & 25 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ num-complex = "0.4"
ndarray = "^0.15.6"
numpy = "0.21.0"
smallvec = "1.13"
thiserror = "1.0"

# Most of the crates don't need the feature `extension-module`, since only `qiskit-pyext` builds an
# actual C extension (the feature disables linking in `libpython`, which is forbidden in Python
Expand Down
3 changes: 2 additions & 1 deletion crates/accelerate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ ahash = "0.8.11"
num-traits = "0.2"
num-complex.workspace = true
num-bigint = "0.4"
rustworkx-core = "0.14"
rustworkx-core = "0.15"
faer = "0.19.1"
itertools = "0.13.0"
qiskit-circuit.workspace = true
thiserror.workspace = true

[dependencies.smallvec]
workspace = true
Expand Down
5 changes: 1 addition & 4 deletions crates/accelerate/src/convert_2q_block_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ use numpy::ndarray::{aview2, Array2, ArrayView2};
use numpy::{IntoPyArray, PyArray2, PyReadonlyArray2};
use smallvec::SmallVec;

static ONE_QUBIT_IDENTITY: [[Complex64; 2]; 2] = [
[Complex64::new(1., 0.), Complex64::new(0., 0.)],
[Complex64::new(0., 0.), Complex64::new(1., 0.)],
];
use qiskit_circuit::gate_matrix::ONE_QUBIT_IDENTITY;

/// Return the matrix Operator resulting from a block of Instructions.
#[pyfunction]
Expand Down
2 changes: 1 addition & 1 deletion crates/accelerate/src/dense_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ pub fn best_subset_inner(
SubsetResult {
count: 0,
map: Vec::new(),
error: std::f64::INFINITY,
error: f64::INFINITY,
subgraph: Vec::new(),
}
};
Expand Down
66 changes: 18 additions & 48 deletions crates/accelerate/src/euler_one_qubit_decomposer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ use std::f64::consts::PI;
use std::ops::Deref;
use std::str::FromStr;

use pyo3::exceptions::{PyIndexError, PyValueError};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::PyString;
use pyo3::types::{PyList, PyString};
use pyo3::wrap_pyfunction;
use pyo3::Python;

use ndarray::prelude::*;
use numpy::PyReadonlyArray2;
use pyo3::pybacked::PyBackedStr;

use qiskit_circuit::SliceOrInt;
use qiskit_circuit::slice::{PySequenceIndex, SequenceIndex};
use qiskit_circuit::util::c64;

pub const ANGLE_ZERO_EPSILON: f64 = 1e-12;

Expand Down Expand Up @@ -96,46 +97,15 @@ impl OneQubitGateSequence {
Ok(self.gates.len())
}

fn __getitem__(&self, py: Python, idx: SliceOrInt) -> PyResult<PyObject> {
match idx {
SliceOrInt::Slice(slc) => {
let len = self.gates.len().try_into().unwrap();
let indices = slc.indices(len)?;
let mut out_vec: Vec<(String, SmallVec<[f64; 3]>)> = Vec::new();
// Start and stop will always be positive the slice api converts
// negatives to the index for example:
// list(range(5))[-1:-3:-1]
// will return start=4, stop=2, and step=-1
let mut pos: isize = indices.start;
let mut cond = if indices.step < 0 {
pos > indices.stop
} else {
pos < indices.stop
};
while cond {
if pos < len as isize {
out_vec.push(self.gates[pos as usize].clone());
}
pos += indices.step;
if indices.step < 0 {
cond = pos > indices.stop;
} else {
cond = pos < indices.stop;
}
}
Ok(out_vec.into_py(py))
}
SliceOrInt::Int(idx) => {
let len = self.gates.len() as isize;
if idx >= len || idx < -len {
Err(PyIndexError::new_err(format!("Invalid index, {idx}")))
} else if idx < 0 {
let len = self.gates.len();
Ok(self.gates[len - idx.unsigned_abs()].to_object(py))
} else {
Ok(self.gates[idx as usize].to_object(py))
}
}
fn __getitem__(&self, py: Python, idx: PySequenceIndex) -> PyResult<PyObject> {
match idx.with_len(self.gates.len())? {
SequenceIndex::Int(idx) => Ok(self.gates[idx].to_object(py)),
indices => Ok(PyList::new_bound(
py,
indices.iter().map(|pos| self.gates[pos].to_object(py)),
)
.into_any()
.unbind()),
}
}
}
Expand Down Expand Up @@ -855,16 +825,16 @@ pub fn params_xyx(unitary: PyReadonlyArray2<Complex64>) -> [f64; 4] {

fn params_xzx_inner(umat: ArrayView2<Complex64>) -> [f64; 4] {
let det = det_one_qubit(umat);
let phase = (Complex64::new(0., -1.) * det.ln()).re / 2.;
let phase = det.ln().im / 2.;
let sqrt_det = det.sqrt();
let mat_zyz = arr2(&[
[
Complex64::new((umat[[0, 0]] / sqrt_det).re, (umat[[1, 0]] / sqrt_det).im),
Complex64::new((umat[[1, 0]] / sqrt_det).re, (umat[[0, 0]] / sqrt_det).im),
c64((umat[[0, 0]] / sqrt_det).re, (umat[[1, 0]] / sqrt_det).im),
c64((umat[[1, 0]] / sqrt_det).re, (umat[[0, 0]] / sqrt_det).im),
],
[
Complex64::new(-(umat[[1, 0]] / sqrt_det).re, (umat[[0, 0]] / sqrt_det).im),
Complex64::new((umat[[0, 0]] / sqrt_det).re, -(umat[[1, 0]] / sqrt_det).im),
c64(-(umat[[1, 0]] / sqrt_det).re, (umat[[0, 0]] / sqrt_det).im),
c64((umat[[0, 0]] / sqrt_det).re, -(umat[[1, 0]] / sqrt_det).im),
],
]);
let [theta, phi, lam, phase_zxz] = params_zxz_inner(mat_zyz.view());
Expand Down
7 changes: 2 additions & 5 deletions crates/accelerate/src/isometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use ndarray::prelude::*;
use numpy::{IntoPyArray, PyReadonlyArray1, PyReadonlyArray2};

use qiskit_circuit::gate_matrix::ONE_QUBIT_IDENTITY;
use qiskit_circuit::util::C_ZERO;

/// Find special unitary matrix that maps [c0,c1] to [r,0] or [0,r] if basis_state=0 or
/// basis_state=1 respectively
Expand Down Expand Up @@ -315,11 +316,7 @@ pub fn merge_ucgate_and_diag(
.enumerate()
.map(|(i, raw_gate)| {
let gate = raw_gate.as_array();
let res = aview2(&[
[diag[2 * i], Complex64::new(0., 0.)],
[Complex64::new(0., 0.), diag[2 * i + 1]],
])
.dot(&gate);
let res = aview2(&[[diag[2 * i], C_ZERO], [C_ZERO, diag[2 * i + 1]]]).dot(&gate);
res.into_pyarray_bound(py).into()
})
.collect()
Expand Down
6 changes: 3 additions & 3 deletions crates/accelerate/src/nlayout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ impl NLayout {
physical_qubits: usize,
) -> Self {
let mut res = NLayout {
virt_to_phys: vec![PhysicalQubit(std::u32::MAX); virtual_qubits],
phys_to_virt: vec![VirtualQubit(std::u32::MAX); physical_qubits],
virt_to_phys: vec![PhysicalQubit(u32::MAX); virtual_qubits],
phys_to_virt: vec![VirtualQubit(u32::MAX); physical_qubits],
};
for (virt, phys) in qubit_indices {
res.virt_to_phys[virt.index()] = phys;
Expand Down Expand Up @@ -184,7 +184,7 @@ impl NLayout {

#[staticmethod]
pub fn from_virtual_to_physical(virt_to_phys: Vec<PhysicalQubit>) -> PyResult<Self> {
let mut phys_to_virt = vec![VirtualQubit(std::u32::MAX); virt_to_phys.len()];
let mut phys_to_virt = vec![VirtualQubit(u32::MAX); virt_to_phys.len()];
for (virt, phys) in virt_to_phys.iter().enumerate() {
phys_to_virt[phys.index()] = VirtualQubit(virt.try_into()?);
}
Expand Down
5 changes: 3 additions & 2 deletions crates/accelerate/src/pauli_exp_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use pyo3::wrap_pyfunction;
use rayon::prelude::*;

use crate::getenv_use_multiple_threads;
use qiskit_circuit::util::c64;

const PARALLEL_THRESHOLD: usize = 19;

Expand Down Expand Up @@ -88,15 +89,15 @@ pub fn expval_pauli_with_x(
let index_0 = ((i << 1) & mask_u) | (i & mask_l);
let index_1 = index_0 ^ x_mask;
let val_0 = (phase
* Complex64::new(
* c64(
data_arr[index_1].re * data_arr[index_0].re
+ data_arr[index_1].im * data_arr[index_0].im,
data_arr[index_1].im * data_arr[index_0].re
- data_arr[index_1].re * data_arr[index_0].im,
))
.re;
let val_1 = (phase
* Complex64::new(
* c64(
data_arr[index_0].re * data_arr[index_1].re
+ data_arr[index_0].im * data_arr[index_1].im,
data_arr[index_0].im * data_arr[index_1].re
Expand Down
3 changes: 2 additions & 1 deletion crates/accelerate/src/sampled_exp_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

use crate::pauli_exp_val::fast_sum;
use qiskit_circuit::util::c64;

const OPER_TABLE_SIZE: usize = (b'Z' as usize) + 1;
const fn generate_oper_table() -> [[f64; 2]; OPER_TABLE_SIZE] {
Expand Down Expand Up @@ -81,7 +82,7 @@ pub fn sampled_expval_complex(
let out: Complex64 = oper_strs
.into_iter()
.enumerate()
.map(|(idx, string)| coeff_arr[idx] * Complex64::new(bitstring_expval(&dist, string), 0.))
.map(|(idx, string)| coeff_arr[idx] * c64(bitstring_expval(&dist, string), 0.))
.sum();
Ok(out.re)
}
Expand Down
Loading

0 comments on commit d5db780

Please sign in to comment.