diff --git a/.ado/stages/build.yaml b/.ado/stages/build.yaml index b7732e0a..1ca9503f 100644 --- a/.ado/stages/build.yaml +++ b/.ado/stages/build.yaml @@ -82,40 +82,11 @@ stages: toolchainFeed: $(toolchainFeed) displayName: Install Rust toolchain - - script: cargo build --release --all-features - displayName: Build all crates - env: - RUSTFLAGS: "-C target-cpu=native" - - - script: cargo test --release - displayName: Test all crates + - script: cargo test --release --all-targets + displayName: Build and test all crates env: RUSTFLAGS: "-C target-cpu=native" - - bash: | - python3 -m venv .venv - source .venv/bin/activate - pip install --upgrade pip - pip install maturin - cd binar/bindings/python - maturin develop --release - cd ../../.. - python -c "import binar; print('binar imported successfully')" - displayName: Test binar Python bindings (Unix) - condition: ne(variables['Agent.OS'], 'Windows_NT') - - - pwsh: | - python -m venv .venv - .\.venv\Scripts\Activate.ps1 - pip install --upgrade pip - pip install maturin - cd binar\bindings\python - maturin develop --release - cd ..\..\.. - python -c "import binar; print('binar imported successfully')" - displayName: Test binar Python bindings (Windows) - condition: eq(variables['Agent.OS'], 'Windows_NT') - - bash: | mkdir -p target/wheels @@ -126,13 +97,20 @@ stages: export RUSTFLAGS="-C target-cpu=x86-64-v3" fi + python3 -m venv .venv source .venv/bin/activate + pip install --upgrade pip maturin + cd binar/bindings/python maturin build --release --strip --out ../../../target/wheels cd ../../.. + cd paulimer/bindings/python + maturin build --release --strip --out ../../../target/wheels + cd ../../.. + ls -la target/wheels/ - displayName: Build wheels (Unix) + displayName: Build Python wheels (Unix) condition: ne(variables['Agent.OS'], 'Windows_NT') - pwsh: | @@ -145,11 +123,18 @@ stages: $env:RUSTFLAGS = "-C target-cpu=x86-64-v3" } + python -m venv .venv .\.venv\Scripts\Activate.ps1 + pip install --upgrade pip maturin + cd binar\bindings\python maturin build --release --strip --out ..\..\..\target\wheels cd ..\..\.. + cd paulimer\bindings\python + maturin build --release --strip --out ..\..\..\target\wheels + cd ..\..\.. + dir target\wheels - displayName: Build wheels (Windows) + displayName: Build Python wheels (Windows) condition: eq(variables['Agent.OS'], 'Windows_NT') diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b1c24214..58d2635e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -60,13 +60,16 @@ jobs: python-version: "3.11" cache: 'pip' + - name: Install just + uses: extractions/setup-just@v2 + - name: Create Python virtual environment and install dependencies (Linux/Mac) if: runner.os != 'Windows' run: | python -m venv qdk_env source qdk_env/bin/activate python -m pip install --upgrade pip - pip install maturin pytest hypothesis more-itertools + pip install maturin - name: Create Python virtual environment and install dependencies (Windows) if: runner.os == 'Windows' @@ -75,70 +78,22 @@ jobs: python -m venv qdk_env call qdk_env\Scripts\activate.bat python -m pip install --upgrade pip - pip install maturin pytest hypothesis more-itertools + pip install maturin - - name: Build binar Python bindings (Linux/Mac) - if: runner.os != 'Windows' - working-directory: binar/bindings/python - env: - RUSTFLAGS: "-C target-cpu=x86-64-v3" + - name: Run CI checks (Linux/Mac) + if: matrix.toolchain == 'stable' && runner.os != 'Windows' run: | - source ../../../qdk_env/bin/activate - maturin develop --release - - - name: Build binar Python bindings (Windows) - if: runner.os == 'Windows' - shell: cmd - working-directory: binar/bindings/python + source qdk_env/bin/activate + just ci env: - RUSTFLAGS: "-C target-cpu=x86-64-v3" - run: | - call ..\..\..\qdk_env\Scripts\activate.bat - maturin develop --release + RUSTFLAGS: -C target-cpu=native - - name: Build paulimer Python bindings (Linux/Mac) - if: runner.os != 'Windows' - working-directory: paulimer/bindings/python - env: - RUSTFLAGS: "-C target-cpu=x86-64-v3" + - name: Run CI checks (Windows) + if: matrix.toolchain == 'stable' && runner.os == 'Windows' + shell: bash run: | - source ../../../qdk_env/bin/activate - maturin develop --release - - - name: Build paulimer Python bindings (Windows) - if: runner.os == 'Windows' - shell: cmd - working-directory: paulimer/bindings/python + source qdk_env/Scripts/activate + just ci env: - RUSTFLAGS: "-C target-cpu=x86-64-v3" - run: | - call ..\..\..\qdk_env\Scripts\activate.bat - maturin develop --release - - - name: Run tests (Linux/Mac) - if: runner.os != 'Windows' - run: | - source qdk_env/bin/activate - cargo test --all --all-features --release - - - name: Run tests (Windows) - if: runner.os == 'Windows' - shell: cmd - run: | - call qdk_env\Scripts\activate.bat - cargo test --all --all-features --release - - - name: Check clippy (stable only) - if: matrix.toolchain == 'stable' - run: | - cargo clippy-all - - - name: Check formatting (stable only) - if: matrix.toolchain == 'stable' - run: cargo fmt --all -- --check - - - name: Build benchmarks (stable only) - if: matrix.toolchain == 'stable' - run: | - cargo bench --package binar --no-run - cargo bench --package paulimer --no-run + RUSTFLAGS: -C target-cpu=native -C linker=rust-lld + diff --git a/binar/bindings/python/pyproject.toml b/binar/bindings/python/pyproject.toml index f74c2d62..e3da8e97 100644 --- a/binar/bindings/python/pyproject.toml +++ b/binar/bindings/python/pyproject.toml @@ -34,6 +34,12 @@ Homepage = "https://github.com/microsoft/qdk-ec" Repository = "https://github.com/microsoft/qdk-ec" "Bug Tracker" = "https://github.com/microsoft/qdk-ec/issues" +[project.optional-dependencies] +dev = [ + "pytest>=7.0", + "hypothesis>=6.0", +] + [tool.maturin] features = ["pyo3/extension-module"] diff --git a/justfile b/justfile new file mode 100644 index 00000000..bea1168d --- /dev/null +++ b/justfile @@ -0,0 +1,29 @@ +# Run all CI checks +ci: fmt build clippy test bindings + +# Check code formatting +fmt: + cargo fmt --all -- --check + +# Build all targets +build: + cargo build --workspace --exclude binar-python --exclude paulimer-bindings --all-features --all-targets --release + +# Run clippy lints +clippy: + cargo clippy --all --all-features --all-targets --release + +# Run tests +test: + cargo test --workspace --exclude binar-python --exclude paulimer-bindings --all-features --all-targets --release + +# Build and test Python bindings +bindings: binar-bindings paulimer-bindings + +# Build and test binar Python bindings +binar-bindings: + cd binar/bindings/python && maturin develop --release --extras dev && pytest tests/ -v + +# Build and test paulimer Python bindings +paulimer-bindings: + cd paulimer/bindings/python && maturin develop --release --extras dev && pytest tests/ -v diff --git a/paulimer/Cargo.toml b/paulimer/Cargo.toml index 1ef0a35c..1f37ec31 100644 --- a/paulimer/Cargo.toml +++ b/paulimer/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "paulimer" version = "0.1.1" -edition = "2021" +edition = "2024" publish = true license = "MIT" description = "Pauli and Clifford algebra for quantum computing" diff --git a/paulimer/benches/pauli_benchmark.rs b/paulimer/benches/pauli_benchmark.rs index e816a1d9..f573819a 100644 --- a/paulimer/benches/pauli_benchmark.rs +++ b/paulimer/benches/pauli_benchmark.rs @@ -1,6 +1,6 @@ extern crate criterion; use binar::BitVec; -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use criterion::{BatchSize, BenchmarkId, Criterion, criterion_group, criterion_main}; use paulimer::pauli::PauliUnitary; use rand::prelude::*; @@ -22,7 +22,7 @@ criterion_group!(benches, multiply_benchmark); criterion_main!(benches); fn random_pauli(dimension: usize) -> PauliUnitary { - let x_bits = std::iter::from_fn(move || Some(thread_rng().gen::())).take(dimension); - let z_bits = std::iter::from_fn(move || Some(thread_rng().gen::())).take(dimension); + let x_bits = std::iter::from_fn(move || Some(thread_rng().r#gen::())).take(dimension); + let z_bits = std::iter::from_fn(move || Some(thread_rng().r#gen::())).take(dimension); PauliUnitary::from_bits(x_bits.collect(), z_bits.collect(), 0u8) } diff --git a/paulimer/benches/symplectic_form_benchmark.rs b/paulimer/benches/symplectic_form_benchmark.rs index 328b66aa..13d49501 100644 --- a/paulimer/benches/symplectic_form_benchmark.rs +++ b/paulimer/benches/symplectic_form_benchmark.rs @@ -1,6 +1,6 @@ extern crate criterion; use binar::{BitwiseMut, IndexSet}; -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use criterion::{BatchSize, BenchmarkId, Criterion, criterion_group, criterion_main}; use paulimer::pauli::{Pauli, SparsePauli}; use paulimer::pauli_group::symplectic_form_of; use rand::prelude::*; @@ -119,7 +119,7 @@ fn generate_permuted_basis_paulis(count: usize) -> Vec { for pauli in &mut selected { let x_bits = pauli.x_bits().clone(); let z_bits = pauli.z_bits().clone(); - let new_pauli = SparsePauli::from_bits(x_bits, z_bits, rng.gen::() % 4); + let new_pauli = SparsePauli::from_bits(x_bits, z_bits, rng.r#gen::() % 4); *pauli = new_pauli; } diff --git a/paulimer/bindings/python/pyproject.toml b/paulimer/bindings/python/pyproject.toml index 7170cf5e..561ea8a9 100644 --- a/paulimer/bindings/python/pyproject.toml +++ b/paulimer/bindings/python/pyproject.toml @@ -40,6 +40,7 @@ dev = [ "pytest>=7.0", "hypothesis>=6.0", "numpy>=1.20", + "more-itertools>=8.0", ] [tool.maturin] diff --git a/paulimer/src/clifford.rs b/paulimer/src/clifford.rs index e25e690e..1715eab5 100644 --- a/paulimer/src/clifford.rs +++ b/paulimer/src/clifford.rs @@ -1,6 +1,6 @@ -use crate::pauli::{Pauli, PauliBinaryOps, PauliMutable}; use crate::UnitaryOp; -use binar::{matrix::AlignedBitMatrix, Bitwise}; +use crate::pauli::{Pauli, PauliBinaryOps, PauliMutable}; +use binar::{Bitwise, matrix::AlignedBitMatrix}; use derive_more::{TryFrom, TryInto}; #[derive(Clone, Copy, Debug, PartialEq, Eq, TryInto, TryFrom)] diff --git a/paulimer/src/clifford/clifford_impl.rs b/paulimer/src/clifford/clifford_impl.rs index 7d318f95..3ce6e646 100644 --- a/paulimer/src/clifford/clifford_impl.rs +++ b/paulimer/src/clifford/clifford_impl.rs @@ -1,6 +1,6 @@ -use crate::core::{y, Axis}; -use sorted_iter::assume::AssumeSortedByItemExt; +use crate::core::{Axis, y}; use sorted_iter::SortedIterator; +use sorted_iter::assume::AssumeSortedByItemExt; use super::generic_algos::support_restricted_z_images_from_support_complement; use super::{ @@ -10,22 +10,22 @@ use super::{ use crate::pauli::generic::PhaseExponent; use crate::pauli::{ - apply_pauli_exponent, apply_root_x, are_mutually_commuting, dense_from, remapped_sparse, DensePauli, - DensePauliProjective, Pauli, PauliBinaryOps, PauliBits, PauliMutable, PauliUnitary, PauliUnitaryProjective, - SparsePauli, SparsePauliProjective, + DensePauli, DensePauliProjective, Pauli, PauliBinaryOps, PauliBits, PauliMutable, PauliUnitary, + PauliUnitaryProjective, SparsePauli, SparsePauliProjective, apply_pauli_exponent, apply_root_x, + are_mutually_commuting, dense_from, remapped_sparse, }; use crate::traits::NeutralElement; -use crate::{assert_1q_gate, assert_2q_gate, UnitaryOp}; -use crate::{subscript_digits, Tuple2x2, Tuple4, Tuple4x2, Tuple8}; +use crate::{Tuple2x2, Tuple4, Tuple4x2, Tuple8, subscript_digits}; +use crate::{UnitaryOp, assert_1q_gate, assert_2q_gate}; +use binar::IndexSet; use binar::matrix::{AlignedBitMatrix, Column}; use binar::vec::{AlignedBitVec, AlignedBitView, AlignedBitViewMut}; -use binar::IndexSet; use binar::{BitVec, Bitwise, BitwiseMut, BitwisePairMut}; use core::fmt; use std::collections::BTreeSet; use std::fmt::{Debug, Display}; -use std::iter::{zip, IntoIterator}; +use std::iter::{IntoIterator, zip}; use std::ops::Mul; use std::str::FromStr; use std::vec; @@ -33,7 +33,7 @@ use std::vec; // Utils fn concat2(ab: Tuple2x2) -> Tuple4 { - (ab.0 .0, ab.0 .1, ab.1 .0, ab.1 .1) + (ab.0.0, ab.0.1, ab.1.0, ab.1.1) } fn split2(ab: Tuple4) -> Tuple2x2 { @@ -41,7 +41,7 @@ fn split2(ab: Tuple4) -> Tuple2x2 { } fn concat4(a: Tuple4x2) -> Tuple8 { - (a.0 .0, a.0 .1, a.1 .0, a.1 .1, a.2 .0, a.2 .1, a.3 .0, a.3 .1) + (a.0.0, a.0.1, a.1.0, a.1.1, a.2.0, a.2.1, a.3.0, a.3.1) } fn split4(abcd: Tuple8) -> Tuple4x2 { @@ -1282,17 +1282,17 @@ impl Default for CliffordModP unsafe fn get_pair_mut_unsafe(v: &mut [T; 4], i: usize) -> (&mut T, &mut T) { let ptr = v as *mut [T; 4]; - (&mut (*ptr)[i], &mut (*ptr)[i + 1]) + unsafe { (&mut (*ptr)[i], &mut (*ptr)[i + 1]) } } unsafe fn get_quad_mut_unsafe(v: &mut [T; 4]) -> (&mut T, &mut T, &mut T, &mut T) { let ptr = v as *mut [T; 4]; - (&mut (*ptr)[0], &mut (*ptr)[1], &mut (*ptr)[2], &mut (*ptr)[3]) + unsafe { (&mut (*ptr)[0], &mut (*ptr)[1], &mut (*ptr)[2], &mut (*ptr)[3]) } } unsafe fn get_tuple_mut_unsafe(v: &mut [T; SIZE], i: (usize, usize)) -> (&mut T, &mut T) { let ptr = v as *mut [T; SIZE]; - (&mut (*ptr)[i.0], &mut (*ptr)[i.1]) + unsafe { (&mut (*ptr)[i.0], &mut (*ptr)[i.1]) } } impl MutablePreImages diff --git a/paulimer/src/clifford/generic_algos.rs b/paulimer/src/clifford/generic_algos.rs index d13f23db..301a6f21 100644 --- a/paulimer/src/clifford/generic_algos.rs +++ b/paulimer/src/clifford/generic_algos.rs @@ -1,11 +1,11 @@ use super::{Clifford, CliffordMutable, MutablePreImages, PreimageViews}; -use crate::pauli::{anti_commutes_with, commutes_with, Pauli, PauliBinaryOps, PauliBits}; +use crate::pauli::{Pauli, PauliBinaryOps, PauliBits, anti_commutes_with, commutes_with}; use crate::pauli::{PauliMutable, PauliMutableBits, PauliNeutralElement}; use crate::setwise::complement; use crate::traits::NeutralElement; use binar::{ - matrix::{kernel_basis_matrix, AlignedBitMatrix, MutableRow}, Bitwise, BitwisePairMut, + matrix::{AlignedBitMatrix, MutableRow, kernel_basis_matrix}, }; pub fn mul_assign_right_clifford_preimage_x_bits<'life, Target, PreImageUnder: PreimageViews>( diff --git a/paulimer/src/lib.rs b/paulimer/src/lib.rs index 3e41012d..18083378 100644 --- a/paulimer/src/lib.rs +++ b/paulimer/src/lib.rs @@ -147,7 +147,7 @@ pub mod traits; pub use clifford::{Clifford, CliffordMutable, CliffordUnitary}; pub use operations::UnitaryOp; pub use pauli::{ - anti_commutes_with, commutes_with, DensePauli, Pauli, PauliBinaryOps, PauliMutable, Phase, SparsePauli, + DensePauli, Pauli, PauliBinaryOps, PauliMutable, Phase, SparsePauli, anti_commutes_with, commutes_with, }; pub use pauli_group::PauliGroup; diff --git a/paulimer/src/operations.rs b/paulimer/src/operations.rs index de71f90c..9b5acecf 100644 --- a/paulimer/src/operations.rs +++ b/paulimer/src/operations.rs @@ -66,8 +66,8 @@ pub fn symmetric_two_qubit_operations(qubit_count: usize, qubit_op: UnitaryOp) - let mut res = Vec::new(); for qubit1 in 0..qubit_count { for qubit2 in 0..qubit1 { - let gen = (qubit_op, vec![qubit1, qubit2]); - res.push(gen); + let generator = (qubit_op, vec![qubit1, qubit2]); + res.push(generator); } } res diff --git a/paulimer/src/pauli.rs b/paulimer/src/pauli.rs index 4edb854b..c47a09ba 100644 --- a/paulimer/src/pauli.rs +++ b/paulimer/src/pauli.rs @@ -1,15 +1,15 @@ pub mod generic; -pub use generic::{add_assign_bits, pauli_random, pauli_random_order_two, PauliUnitary, PauliUnitaryProjective}; +pub use generic::{PauliUnitary, PauliUnitaryProjective, add_assign_bits, pauli_random, pauli_random_order_two}; pub mod operators; pub use operators::Phase; mod dense; -pub use dense::{condense_from, dense_from, DensePauli, DensePauliProjective}; +pub use dense::{DensePauli, DensePauliProjective, condense_from, dense_from}; use sorted_iter::SortedIterator; mod sparse; -pub use sparse::{as_sparse, as_sparse_projective, remapped_sparse, SparsePauli, SparsePauliProjective}; +pub use sparse::{SparsePauli, SparsePauliProjective, as_sparse, as_sparse_projective, remapped_sparse}; mod algorithms; pub use algorithms::{ diff --git a/paulimer/src/pauli/algorithms.rs b/paulimer/src/pauli/algorithms.rs index f044f148..6af14f96 100644 --- a/paulimer/src/pauli/algorithms.rs +++ b/paulimer/src/pauli/algorithms.rs @@ -1,4 +1,4 @@ -use super::{anti_commutes_with, DensePauli, Pauli, PauliBinaryOps}; +use super::{DensePauli, Pauli, PauliBinaryOps, anti_commutes_with}; use crate::setwise::complement; use crate::traits::NeutralElement; use binar::{BitMatrix, Bitwise}; diff --git a/paulimer/src/pauli/dense.rs b/paulimer/src/pauli/dense.rs index a634eb4d..171782c3 100644 --- a/paulimer/src/pauli/dense.rs +++ b/paulimer/src/pauli/dense.rs @@ -1,6 +1,6 @@ use super::{PauliUnitaryProjective, SparsePauli}; -use crate::pauli::{generic::PauliUnitary, NeutralElement, Pauli, PauliBinaryOps}; -use binar::{vec::AlignedBitVec, Bitwise, BitwiseMut}; +use crate::pauli::{NeutralElement, Pauli, PauliBinaryOps, generic::PauliUnitary}; +use binar::{Bitwise, BitwiseMut, vec::AlignedBitVec}; /// Dense representation of a Pauli operator using bit vectors. /// diff --git a/paulimer/src/pauli/generic.rs b/paulimer/src/pauli/generic.rs index 4449435c..85de7715 100644 --- a/paulimer/src/pauli/generic.rs +++ b/paulimer/src/pauli/generic.rs @@ -3,9 +3,8 @@ use crate::core::PositionedPauliObservable; use crate::subscript_digits; use crate::traits::{BitwiseNeutralElement, NeutralElement}; use binar::{ - self, + self, IndexSet, vec::{AlignedBitVec, AlignedBitView}, - IndexSet, }; use binar::{Bitwise, BitwiseMut, BitwisePair, BitwisePairMut, FromBits}; @@ -96,7 +95,7 @@ impl PhaseExponentMutable for u8 { } fn set_random(&mut self, random_number_generator: &mut impl rand::Rng) { - *self = random_number_generator.gen::(); + *self = random_number_generator.r#gen::(); } } @@ -110,7 +109,7 @@ impl PhaseExponentMutable for &mut u8 { } fn set_random(&mut self, random_number_generator: &mut impl rand::Rng) { - **self = random_number_generator.gen::(); + **self = random_number_generator.r#gen::(); } } @@ -981,11 +980,11 @@ where } impl< - BitsFrom: PauliBits, - Bits: PauliBits, - PhaseFrom: PhaseExponent, - Phase: PhaseExponentMutable + NeutralElement, - > FromBits> for PauliUnitary + BitsFrom: PauliBits, + Bits: PauliBits, + PhaseFrom: PhaseExponent, + Phase: PhaseExponentMutable + NeutralElement, +> FromBits> for PauliUnitary where Self: PauliNeutralElement, Bits: FromBits, diff --git a/paulimer/src/pauli/operators.rs b/paulimer/src/pauli/operators.rs index d1321e33..ebff6354 100644 --- a/paulimer/src/pauli/operators.rs +++ b/paulimer/src/pauli/operators.rs @@ -10,8 +10,8 @@ use std::ops::{Mul, MulAssign, Neg}; use crate::traits::NeutralElement; use super::{ - generic::{PhaseExponent, PhaseExponentMutable}, Pauli, PauliBinaryOps, PauliBits, PauliMutable, PauliNeutralElement, PauliUnitary, PauliUnitaryProjective, + generic::{PhaseExponent, PhaseExponentMutable}, }; impl> MulAssign<&PauliRight> diff --git a/paulimer/src/pauli_group.rs b/paulimer/src/pauli_group.rs index 4235c490..012130c0 100644 --- a/paulimer/src/pauli_group.rs +++ b/paulimer/src/pauli_group.rs @@ -1,17 +1,17 @@ use crate::pauli::generic::PhaseExponent; use crate::pauli::{ - anti_commutes_with, condense_from, remapped_sparse, DensePauli, Pauli, PauliBinaryOps, PauliMutable, SparsePauli, + DensePauli, Pauli, PauliBinaryOps, PauliMutable, SparsePauli, anti_commutes_with, condense_from, remapped_sparse, }; use crate::traits::NeutralElement; -use binar::matrix::{kernel_basis_matrix, row_stacked, AlignedBitMatrix, AlignedEchelonForm as EchelonForm}; -use binar::vec::AlignedBitView; use binar::IndexSet; +use binar::matrix::{AlignedBitMatrix, AlignedEchelonForm as EchelonForm, kernel_basis_matrix, row_stacked}; +use binar::vec::AlignedBitView; use binar::{Bitwise, BitwiseMut}; use once_cell::sync::OnceCell; -use sorted_iter::assume::AssumeSortedByItemExt; use sorted_iter::SortedIterator; -use std::cmp::{min, Ordering, PartialOrd}; +use sorted_iter::assume::AssumeSortedByItemExt; +use std::cmp::{Ordering, PartialOrd, min}; use std::collections::{HashMap, HashSet}; use std::fmt::Display; use std::iter::Iterator; diff --git a/paulimer/src/python.rs b/paulimer/src/python.rs index 649f4953..842e18d9 100644 --- a/paulimer/src/python.rs +++ b/paulimer/src/python.rs @@ -1,8 +1,8 @@ +use crate::UnitaryOp; use crate::clifford::CliffordUnitary; use crate::pauli::{DensePauli, Pauli, SparsePauli}; use crate::pauli_group::PauliGroup; -use crate::UnitaryOp; -use binar::{vec::AlignedBitVec, IndexSet}; +use binar::{IndexSet, vec::AlignedBitVec}; use pyo3::conversion::IntoPyObject; use pyo3::prelude::*; diff --git a/paulimer/src/schemars.rs b/paulimer/src/schemars.rs index d9693110..c36c2f25 100644 --- a/paulimer/src/schemars.rs +++ b/paulimer/src/schemars.rs @@ -1,5 +1,5 @@ -use schemars::json_schema; use schemars::JsonSchema; +use schemars::json_schema; use crate::clifford::{CliffordUnitary, CliffordUnitaryModPauli}; use crate::pauli::{SparsePauli, SparsePauliProjective}; diff --git a/paulimer/src/serde.rs b/paulimer/src/serde.rs index 13d72244..7bd8b287 100644 --- a/paulimer/src/serde.rs +++ b/paulimer/src/serde.rs @@ -1,4 +1,4 @@ -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use crate::clifford::CliffordUnitary; use crate::clifford::CliffordUnitaryModPauli; diff --git a/paulimer/src/setwise.rs b/paulimer/src/setwise.rs index 7d05ca3d..85b13b4d 100644 --- a/paulimer/src/setwise.rs +++ b/paulimer/src/setwise.rs @@ -1,4 +1,4 @@ -use sorted_iter::{assume::AssumeSortedByItemExt, SortedIterator}; +use sorted_iter::{SortedIterator, assume::AssumeSortedByItemExt}; use std::borrow::Borrow; #[must_use] diff --git a/paulimer/tests/clifford_test.rs b/paulimer/tests/clifford_test.rs index 3b23d226..dcd4df43 100644 --- a/paulimer/tests/clifford_test.rs +++ b/paulimer/tests/clifford_test.rs @@ -1,21 +1,21 @@ -use binar::{matrix::AlignedBitMatrix as BitMatrix, vec::AlignedBitVec as BitVec, Bitwise, BitwiseMut, IndexSet}; +use binar::{Bitwise, BitwiseMut, IndexSet, matrix::AlignedBitMatrix as BitMatrix, vec::AlignedBitVec as BitVec}; use paulimer::clifford::generic_algos::{clifford_from_images, clifford_to_prepare_bell_states}; use paulimer::clifford::{ + Clifford, CliffordMutable, CliffordStringParsingError, MutablePreImages, PreimageViews, XOrZ, apply_qubit_clifford_by_axis, group_encoding_clifford_of, prepare_all_plus, prepare_all_zero, random_clifford_via_operations_sampling, split_clifford_encoder_mod_pauli, split_phased_css, - split_qubit_cliffords_and_css, split_qubit_tensor_product_encoder, Clifford, CliffordMutable, - CliffordStringParsingError, MutablePreImages, PreimageViews, XOrZ, + split_qubit_cliffords_and_css, split_qubit_tensor_product_encoder, }; type CliffordUnitary = paulimer::clifford::CliffordUnitary; type CliffordUnitaryModPauli = paulimer::clifford::CliffordUnitaryModPauli; use paulimer::pauli::{ - anti_commutes_with, apply_pauli_exponent, apply_root_x, apply_root_y, apply_root_z, pauli_random, - pauli_random_order_two, DensePauli, DensePauliProjective, PauliMutable, SparsePauliProjective, + DensePauli, DensePauliProjective, PauliMutable, SparsePauliProjective, anti_commutes_with, apply_pauli_exponent, + apply_root_x, apply_root_y, apply_root_z, pauli_random, pauli_random_order_two, }; -use paulimer::pauli::{commutes_with, Pauli, PauliBinaryOps, PauliUnitary, Phase, SparsePauli}; +use paulimer::pauli::{Pauli, PauliBinaryOps, PauliUnitary, Phase, SparsePauli, commutes_with}; -use paulimer::core::{x, y, z, PositionedPauliObservable}; +use paulimer::core::{PositionedPauliObservable, x, y, z}; use paulimer::operations::{css_operations, diagonal_operations}; use proptest::prelude::*; use rand::prelude::*; @@ -1144,7 +1144,7 @@ fn are_bits_equal_to_col(bitstring: &impl Bitwise, matrix: &BitMatrix, col: usiz /// Will panic pub fn random_bitmatrix(row_count: usize, column_count: usize) -> BitMatrix { let mut matrix = BitMatrix::with_shape(row_count, column_count); - let mut bits = std::iter::from_fn(move || Some(rand::Rng::gen::(&mut thread_rng()))); + let mut bits = std::iter::from_fn(move || Some(rand::Rng::r#gen::(&mut thread_rng()))); for row_index in 0..row_count { for column_index in 0..column_count { matrix.set((row_index, column_index), bits.next().expect("boom")); diff --git a/paulimer/tests/core_test.rs b/paulimer/tests/core_test.rs index c5d1f8cb..8108bc73 100644 --- a/paulimer/tests/core_test.rs +++ b/paulimer/tests/core_test.rs @@ -1,5 +1,5 @@ use itertools::iproduct; -use paulimer::core::{id, x, y, z, All, Axis, DirectedAxis, PauliMatrix, PauliObservable}; +use paulimer::core::{All, Axis, DirectedAxis, PauliMatrix, PauliObservable, id, x, y, z}; #[test] fn iter_and_print_test() { diff --git a/paulimer/tests/pauli_group_test.rs b/paulimer/tests/pauli_group_test.rs index a165d4a3..8f49e8b4 100644 --- a/paulimer/tests/pauli_group_test.rs +++ b/paulimer/tests/pauli_group_test.rs @@ -1,7 +1,7 @@ use binar::{Bitwise, BitwiseMut, IndexSet}; use itertools::Itertools; -use paulimer::pauli::{commutes_with, Pauli, PauliMutable, SparsePauli}; -use paulimer::pauli_group::{centralizer_of, symplectic_form_of, PauliGroup}; +use paulimer::pauli::{Pauli, PauliMutable, SparsePauli, commutes_with}; +use paulimer::pauli_group::{PauliGroup, centralizer_of, symplectic_form_of}; use paulimer::traits::NeutralElement; use proptest::collection::vec; use proptest::prelude::*; diff --git a/paulimer/tests/pauli_test.rs b/paulimer/tests/pauli_test.rs index 5167ca9b..4f1d7d4a 100644 --- a/paulimer/tests/pauli_test.rs +++ b/paulimer/tests/pauli_test.rs @@ -5,8 +5,8 @@ use std::str::FromStr; use binar::vec::AlignedBitViewMut as MutableBitView; use paulimer::core::{x, y, z}; use paulimer::pauli::{ - commutes_with, generic::PhaseExponent, DensePauli, DensePauliProjective, Pauli, PauliBinaryOps, PauliMutable, - PauliUnitary, Phase, SparsePauli, SparsePauliProjective, + DensePauli, DensePauliProjective, Pauli, PauliBinaryOps, PauliMutable, PauliUnitary, Phase, SparsePauli, + SparsePauliProjective, commutes_with, generic::PhaseExponent, }; use proptest::prelude::*; use rand::thread_rng; diff --git a/pauliverse/Cargo.toml b/pauliverse/Cargo.toml index 5d99e87a..8313c35c 100644 --- a/pauliverse/Cargo.toml +++ b/pauliverse/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pauliverse" version = "0.1.0" -edition = "2021" +edition = "2024" publish = true license = "MIT" description = "Fast stabilizer simulation" diff --git a/pauliverse/benches/simulation_benchmark.rs b/pauliverse/benches/simulation_benchmark.rs index 5a0ad177..659716d8 100644 --- a/pauliverse/benches/simulation_benchmark.rs +++ b/pauliverse/benches/simulation_benchmark.rs @@ -1,12 +1,12 @@ //! Criterion benchmarks for `FaultySimulation`. -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main}; use paulimer::pauli::{Pauli, SparsePauli}; +use pauliverse::Simulation; use pauliverse::faulty_simulation::FaultySimulation; use pauliverse::noise::PauliFault; -use pauliverse::Simulation; -use rand::rngs::SmallRng; use rand::SeedableRng; +use rand::rngs::SmallRng; use std::str::FromStr; const SEED: u64 = 42; diff --git a/pauliverse/src/circuit.rs b/pauliverse/src/circuit.rs index d57a4df9..da44330e 100644 --- a/pauliverse/src/circuit.rs +++ b/pauliverse/src/circuit.rs @@ -1,6 +1,6 @@ +use paulimer::UnitaryOp; use paulimer::clifford::CliffordUnitary; use paulimer::pauli::{Pauli, SparsePauli}; -use paulimer::UnitaryOp; use crate::noise::PauliFault; @@ -225,8 +225,8 @@ mod tests { use super::*; use paulimer::pauli::SparsePauli; use proptest::prelude::*; - use rand::seq::SliceRandom; use rand::Rng; + use rand::seq::SliceRandom; use std::str::FromStr; /// Configuration for circuit generation. diff --git a/pauliverse/src/faulty_simulation.rs b/pauliverse/src/faulty_simulation.rs index f88a1132..8f2e55bc 100644 --- a/pauliverse/src/faulty_simulation.rs +++ b/pauliverse/src/faulty_simulation.rs @@ -4,17 +4,17 @@ //! sampling with [`FramePropagator`] for O(n\_gates × n\_qubits) noisy simulation. use binar::BitMatrix; +use paulimer::UnitaryOp; use paulimer::clifford::CliffordUnitary; use paulimer::pauli::SparsePauli; -use paulimer::UnitaryOp; use rand::rngs::SmallRng; use rand::{Rng, SeedableRng}; +use crate::Simulation; use crate::circuit::{Circuit, Instruction}; use crate::frame_propagator::FramePropagator; use crate::noise::PauliFault; use crate::outcome_complete_simulation::OutcomeCompleteSimulation; -use crate::Simulation; /// Noisy stabilizer simulation. /// @@ -145,7 +145,7 @@ impl FaultySimulation { /// /// Useful for reproducible simulations with seeded random number generation. pub fn sample_with_rng(&self, shots: usize, rng: &mut R) -> BitMatrix { - let base_seed: u64 = rng.gen(); + let base_seed: u64 = rng.r#gen(); let mut outcomes = self.noiseless.sample_with_rng(shots, rng); let deltas = self.simulate_circuit(shots, &outcomes, base_seed, rng); diff --git a/pauliverse/src/frame_propagator.rs b/pauliverse/src/frame_propagator.rs index ffea829f..c0048e65 100644 --- a/pauliverse/src/frame_propagator.rs +++ b/pauliverse/src/frame_propagator.rs @@ -21,14 +21,14 @@ use binar::matrix::AlignedBitMatrix; use binar::vec::AlignedBitVec; use binar::{BitMatrix, Bitwise, BitwisePairMut}; +use paulimer::UnitaryOp; use paulimer::clifford::CliffordUnitary; use paulimer::pauli::Pauli; -use paulimer::UnitaryOp; use rand::rngs::SmallRng; use rand::{Rng, SeedableRng}; use crate::circuit::{Instruction, OutcomeId, QubitId}; -use crate::noise::{sample_non_identity_pauli_bits, PauliFault}; +use crate::noise::{PauliFault, sample_non_identity_pauli_bits}; use crate::sampling::GeometricSampler; /// Pauli error frame propagator for batched multi-shot simulation. @@ -537,12 +537,12 @@ impl FramePropagator { mod tests { use super::*; use crate::statistical_testing::{ - assert_rate_within_tolerance, assert_uniform_distribution, TOLERANCE_HIGH_SAMPLES, TOLERANCE_LOW_SAMPLES, + TOLERANCE_HIGH_SAMPLES, TOLERANCE_LOW_SAMPLES, assert_rate_within_tolerance, assert_uniform_distribution, }; use paulimer::clifford::{Clifford, CliffordMutable, CliffordUnitary}; use paulimer::pauli::SparsePauli; - use rand::rngs::SmallRng; use rand::SeedableRng; + use rand::rngs::SmallRng; use smallvec::smallvec; use std::str::FromStr; diff --git a/pauliverse/src/noise.rs b/pauliverse/src/noise.rs index 720d4ee1..bdd63a67 100644 --- a/pauliverse/src/noise.rs +++ b/pauliverse/src/noise.rs @@ -116,7 +116,7 @@ impl PauliDistribution { } Self::Weighted { paulis, cdf } => { - let u: f64 = rng.gen(); + let u: f64 = rng.r#gen(); let idx = cdf.partition_point(|&c| c < u); paulis[idx.min(paulis.len() - 1)].clone() } @@ -259,7 +259,7 @@ pub(crate) fn sample_non_identity_pauli_bits(qubit_count: usize, rng: &m let limit = u64::MAX - (u64::MAX % pauli_count); loop { - let sample = rng.gen::(); + let sample = rng.r#gen::(); if sample < limit { let index = sample % pauli_count; return index + 1; @@ -380,12 +380,12 @@ impl PauliFault { mod tests { use super::*; use crate::statistical_testing::{ - assert_uniform_distribution, two_qubit_pauli_to_bit_index, TOLERANCE_HIGH_SAMPLES, + TOLERANCE_HIGH_SAMPLES, assert_uniform_distribution, two_qubit_pauli_to_bit_index, }; use binar::Bitwise; use paulimer::pauli::Pauli; - use rand::rngs::{mock::StepRng, SmallRng}; use rand::SeedableRng; + use rand::rngs::{SmallRng, mock::StepRng}; use std::collections::HashSet; use std::str::FromStr; diff --git a/pauliverse/src/outcome_complete_simulation.rs b/pauliverse/src/outcome_complete_simulation.rs index a0ad33ef..77009867 100644 --- a/pauliverse/src/outcome_complete_simulation.rs +++ b/pauliverse/src/outcome_complete_simulation.rs @@ -1,12 +1,12 @@ -use crate::outcome_free_simulation::{max_pair_support, max_support}; use crate::Simulation; -use binar::{matrix::AlignedBitMatrix, vec::AlignedBitVec, Bitwise, BitwiseMut, BitwisePair, BitwisePairMut, IndexSet}; +use crate::outcome_free_simulation::{max_pair_support, max_support}; use binar::{BitMatrix, BitVec}; +use binar::{Bitwise, BitwiseMut, BitwisePair, BitwisePairMut, IndexSet, matrix::AlignedBitMatrix, vec::AlignedBitVec}; use paulimer::clifford::{Clifford, CliffordMutable, CliffordUnitary}; -use paulimer::pauli::{anti_commutes_with, generic::PhaseExponent, Pauli, PauliBits, PauliUnitary}; +use paulimer::pauli::{Pauli, PauliBits, PauliUnitary, anti_commutes_with, generic::PhaseExponent}; use paulimer::pauli::{PauliBinaryOps, PauliMutable}; -use paulimer::{UnitaryOp, CLIFFORD_BIT_ALIGNMENT}; -use rand::{thread_rng, Rng}; +use paulimer::{CLIFFORD_BIT_ALIGNMENT, UnitaryOp}; +use rand::{Rng, thread_rng}; use std::borrow::Borrow; type SparsePauli = paulimer::pauli::SparsePauli; diff --git a/pauliverse/src/outcome_free_simulation.rs b/pauliverse/src/outcome_free_simulation.rs index a3c5ce76..4b643711 100644 --- a/pauliverse/src/outcome_free_simulation.rs +++ b/pauliverse/src/outcome_free_simulation.rs @@ -1,7 +1,7 @@ use binar::Bitwise; use paulimer::{ clifford::{Clifford, CliffordMutable, CliffordUnitaryModPauli}, - pauli::{anti_commutes_with, Pauli, PauliBinaryOps, PauliBits, PauliUnitaryProjective, SparsePauliProjective}, + pauli::{Pauli, PauliBinaryOps, PauliBits, PauliUnitaryProjective, SparsePauliProjective, anti_commutes_with}, }; use crate::Simulation; diff --git a/pauliverse/src/outcome_specific_simulation.rs b/pauliverse/src/outcome_specific_simulation.rs index c158944d..eeb2ff0b 100644 --- a/pauliverse/src/outcome_specific_simulation.rs +++ b/pauliverse/src/outcome_specific_simulation.rs @@ -1,11 +1,11 @@ use crate::outcome_free_simulation::{max_pair_support, max_support}; use crate::{OutcomeId, Simulation}; use binar::Bitwise; +use paulimer::UnitaryOp; use paulimer::clifford::{Clifford, CliffordMutable, CliffordUnitary}; -use paulimer::pauli::{anti_commutes_with, generic::PhaseExponent, Pauli, PauliBits, PauliUnitary}; +use paulimer::pauli::{Pauli, PauliBits, PauliUnitary, anti_commutes_with, generic::PhaseExponent}; use paulimer::pauli::{PauliBinaryOps, PauliMutable}; -use paulimer::UnitaryOp; -use rand::{rngs::StdRng, thread_rng, Rng, SeedableRng}; +use rand::{Rng, SeedableRng, rngs::StdRng, thread_rng}; type SparsePauli = paulimer::pauli::SparsePauli; @@ -138,7 +138,7 @@ impl OutcomeSpecificSimulation { /// /// This is the standard constructor for Monte Carlo sampling. pub fn new_with_random_outcomes(num_qubits: usize) -> Self { - Self::new_with_bit_source(num_qubits, SeededRandomBitIterator::new(rand::thread_rng().gen())) + Self::new_with_bit_source(num_qubits, SeededRandomBitIterator::new(rand::thread_rng().r#gen())) } /// Create a simulation with seeded random number generation. @@ -180,7 +180,7 @@ impl OutcomeSpecificSimulation { pub fn with_capacity(num_qubits: usize, num_outcomes: usize, _num_random_outcomes: usize) -> Self { Self::with_bit_source_and_capacity( num_qubits, - SeededRandomBitIterator::new(rand::thread_rng().gen()), + SeededRandomBitIterator::new(rand::thread_rng().r#gen()), num_outcomes, ) } @@ -367,7 +367,7 @@ impl Iterator for RandomBitIterator { type Item = bool; fn next(&mut self) -> Option { - Some(self.rng.gen::()) + Some(self.rng.r#gen::()) } } @@ -388,7 +388,7 @@ impl Iterator for SeededRandomBitIterator { type Item = bool; fn next(&mut self) -> Option { - Some(self.rng.gen::()) + Some(self.rng.r#gen::()) } } diff --git a/pauliverse/src/sampling.rs b/pauliverse/src/sampling.rs index 058ed123..06bfc194 100644 --- a/pauliverse/src/sampling.rs +++ b/pauliverse/src/sampling.rs @@ -50,7 +50,7 @@ impl GeometricSampler { #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] fn refill_buffers(&mut self, rng: &mut R) { for value in &mut self.random_buffer { - *value = rng.gen(); + *value = rng.r#gen(); } for (skip, &uniform) in self.skip_buffer.iter_mut().zip(self.random_buffer.iter()) { *skip = (uniform.ln() / self.log_one_minus_p).floor() as usize; @@ -62,9 +62,9 @@ impl GeometricSampler { #[cfg(test)] mod tests { use super::*; - use crate::statistical_testing::{assert_rate_within_tolerance, TOLERANCE_HIGH_SAMPLES, TOLERANCE_LOW_SAMPLES}; - use rand::rngs::SmallRng; + use crate::statistical_testing::{TOLERANCE_HIGH_SAMPLES, TOLERANCE_LOW_SAMPLES, assert_rate_within_tolerance}; use rand::SeedableRng; + use rand::rngs::SmallRng; fn count_geometric_events(sampler: &mut GeometricSampler, rng: &mut SmallRng, total_trials: usize) -> usize { let mut event_count = 0; diff --git a/pauliverse/tests/faulty_simulation_test.rs b/pauliverse/tests/faulty_simulation_test.rs index 2e491bc8..4c558a4d 100644 --- a/pauliverse/tests/faulty_simulation_test.rs +++ b/pauliverse/tests/faulty_simulation_test.rs @@ -1,14 +1,14 @@ //! Tests for `FaultySimulation` using only the public API. use binar::Bitwise; +use paulimer::UnitaryOp; use paulimer::clifford::{Clifford, CliffordMutable, CliffordUnitary}; use paulimer::pauli::SparsePauli; -use paulimer::UnitaryOp; +use pauliverse::Simulation; use pauliverse::faulty_simulation::FaultySimulation; use pauliverse::noise::{PauliDistribution, PauliFault}; -use pauliverse::Simulation; -use rand::rngs::SmallRng; use rand::SeedableRng; +use rand::rngs::SmallRng; use std::str::FromStr; /// Create a Bell state simulation: H(0), CNOT(0,1), measure ZZ and XX. diff --git a/pauliverse/tests/simulation_test.rs b/pauliverse/tests/simulation_test.rs index 11baa123..de016c9c 100644 --- a/pauliverse/tests/simulation_test.rs +++ b/pauliverse/tests/simulation_test.rs @@ -1,15 +1,15 @@ use std::borrow::Borrow; use binar::{BitMatrix, BitView, Bitwise, BitwisePairMut, IndexSet}; -use paulimer::core::{x, z, PositionedPauliObservable}; +use paulimer::core::{PositionedPauliObservable, x, z}; use paulimer::{ clifford::{Clifford, CliffordMutable, CliffordUnitary}, operations::UnitaryOp, pauli::{Pauli, SparsePauli}, }; use pauliverse::{ - outcome_complete_simulation::OutcomeCompleteSimulation, outcome_free_simulation::OutcomeFreeSimulation, - outcome_specific_simulation::OutcomeSpecificSimulation, Simulation, + Simulation, outcome_complete_simulation::OutcomeCompleteSimulation, outcome_free_simulation::OutcomeFreeSimulation, + outcome_specific_simulation::OutcomeSpecificSimulation, }; trait SimulationForTest: Simulation + Default { @@ -112,7 +112,7 @@ fn random_and_deterministic_outcome_sequence( sim.measure_o(&[z(0)]); // 6: random o2 |0b10 sim.apply_pauli_o(&[x(1)]); sim.measure_o(&[z(1)]); // 7: deterministic 1 |0b0 - // outcome shift : 0b_1000_1000 + // outcome shift : 0b_1000_1000 } fn cx_cz_test() {