Skip to content

Commit 859c425

Browse files
authored
Use bytemuck to cast u32 to Qubit. (#16013)
- Derive the `AnyBitPattern` trait for `Qubit` and `Clbit` to allow bytemuck to easily cast from `u32` which also enables us to cast from and to their respective slice types. - Implemented said cases in the `ListinskiTransformation` pass.
1 parent 7346eb8 commit 859c425

4 files changed

Lines changed: 8 additions & 7 deletions

File tree

crates/circuit/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ qiskit-quantum-info.workspace = true
1818
rayon.workspace = true
1919
ahash.workspace = true
2020
rustworkx-core.workspace = true
21-
bytemuck.workspace = true
21+
bytemuck = {workspace = true, features = ["derive"]}
2222
bitfield-struct.workspace = true
2323
num-complex.workspace = true
2424
num-bigint.workspace = true

crates/circuit/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ pub mod var_stretch_container;
4040
mod variable_mapper;
4141
pub mod vf2;
4242

43+
use bytemuck::AnyBitPattern;
4344
use pyo3::exceptions::{PyRuntimeError, PyValueError};
4445
use pyo3::prelude::*;
4546
use pyo3::types::{PySequence, PyString, PyTuple};
4647

47-
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq, FromPyObject)]
48+
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq, FromPyObject, AnyBitPattern)]
4849
#[repr(transparent)]
4950
pub struct Qubit(pub u32);
5051

51-
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq, FromPyObject)]
52+
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq, FromPyObject, AnyBitPattern)]
5253
#[repr(transparent)]
5354
pub struct Clbit(pub u32);
5455

crates/quantum_info/src/clifford.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl Clifford {
290290

291291
/// Evolving the single-qubit Pauli-Z with Z on qubit qbit.
292292
/// Returns the evolved Pauli in the a sparse ZX format: (sign, z, x, indices).
293-
pub fn get_inverse_z(&self, qbit: usize) -> (bool, Vec<bool>, Vec<bool>, Vec<usize>) {
293+
pub fn get_inverse_z(&self, qbit: usize) -> (bool, Vec<bool>, Vec<bool>, Vec<u32>) {
294294
let mut z = Vec::with_capacity(self.num_qubits);
295295
let mut x = Vec::with_capacity(self.num_qubits);
296296
let mut indices = Vec::with_capacity(self.num_qubits);
@@ -303,7 +303,7 @@ impl Clifford {
303303
if z_bit || x_bit {
304304
z.push(z_bit);
305305
x.push(x_bit);
306-
indices.push(i);
306+
indices.push(i as u32);
307307
if x_bit {
308308
pauli_indices.push(i);
309309
}

crates/transpiler/src/passes/litinski_transformation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub fn run_litinski_transformation(
254254
let (sign, z, x, indices) =
255255
clifford.get_inverse_z(dag.get_qargs(inst.qubits)[0].index());
256256
qargs.clear();
257-
qargs.extend(indices.iter().map(|i| Qubit::new(*i)));
257+
qargs.extend(bytemuck::cast_slice(&indices));
258258

259259
// In the legacy path, we add PauliEvolutionGate as rotation gates, otherwise
260260
// we add PauliProductRotation. The new path should not call Python at any
@@ -309,7 +309,7 @@ pub fn run_litinski_transformation(
309309
let (sign, z, x, indices) =
310310
clifford.get_inverse_z(dag.get_qargs(inst.qubits)[0].index());
311311
qargs.clear();
312-
qargs.extend(indices.iter().map(|i| Qubit::new(*i)));
312+
qargs.extend(bytemuck::cast_slice(&indices));
313313

314314
let ppm = PauliProductMeasurement { z, x, neg: sign };
315315

0 commit comments

Comments
 (0)