Skip to content
Draft
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
51 changes: 18 additions & 33 deletions .ado/stages/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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: |
Expand All @@ -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')
79 changes: 17 additions & 62 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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

6 changes: 6 additions & 0 deletions binar/bindings/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
29 changes: 29 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion paulimer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
6 changes: 3 additions & 3 deletions paulimer/benches/pauli_benchmark.rs
Original file line number Diff line number Diff line change
@@ -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::*;

Expand All @@ -22,7 +22,7 @@ criterion_group!(benches, multiply_benchmark);
criterion_main!(benches);

fn random_pauli(dimension: usize) -> PauliUnitary<BitVec, u8> {
let x_bits = std::iter::from_fn(move || Some(thread_rng().gen::<bool>())).take(dimension);
let z_bits = std::iter::from_fn(move || Some(thread_rng().gen::<bool>())).take(dimension);
let x_bits = std::iter::from_fn(move || Some(thread_rng().r#gen::<bool>())).take(dimension);
let z_bits = std::iter::from_fn(move || Some(thread_rng().r#gen::<bool>())).take(dimension);
PauliUnitary::from_bits(x_bits.collect(), z_bits.collect(), 0u8)
}
4 changes: 2 additions & 2 deletions paulimer/benches/symplectic_form_benchmark.rs
Original file line number Diff line number Diff line change
@@ -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::*;
Expand Down Expand Up @@ -119,7 +119,7 @@ fn generate_permuted_basis_paulis(count: usize) -> Vec<SparsePauli> {
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::<u8>() % 4);
let new_pauli = SparsePauli::from_bits(x_bits, z_bits, rng.r#gen::<u8>() % 4);
*pauli = new_pauli;
}

Expand Down
1 change: 1 addition & 0 deletions paulimer/bindings/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dev = [
"pytest>=7.0",
"hypothesis>=6.0",
"numpy>=1.20",
"more-itertools>=8.0",
]

[tool.maturin]
Expand Down
4 changes: 2 additions & 2 deletions paulimer/src/clifford.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down
28 changes: 14 additions & 14 deletions paulimer/src/clifford/clifford_impl.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand All @@ -10,38 +10,38 @@ 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;

// Utils

fn concat2<T>(ab: Tuple2x2<T>) -> Tuple4<T> {
(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<T>(ab: Tuple4<T>) -> Tuple2x2<T> {
((ab.0, ab.1), (ab.2, ab.3))
}

fn concat4<T>(a: Tuple4x2<T>) -> Tuple8<T> {
(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<T>(abcd: Tuple8<T>) -> Tuple4x2<T> {
Expand Down Expand Up @@ -1282,17 +1282,17 @@ impl<const WORD_COUNT: usize, const QUBIT_COUNT: usize> Default for CliffordModP

unsafe fn get_pair_mut_unsafe<T>(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<T>(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<T, const SIZE: usize>(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<const WORD_COUNT: usize, const QUBIT_COUNT: usize> MutablePreImages
Expand Down
4 changes: 2 additions & 2 deletions paulimer/src/clifford/generic_algos.rs
Original file line number Diff line number Diff line change
@@ -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>(
Expand Down
2 changes: 1 addition & 1 deletion paulimer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading