Skip to content

Commit 3942c9c

Browse files
debasmita2102Shelly GarionAlexander IvriiShellyGarion
authored
Support commutation check between Pauli-based gates and standard gates (Qiskit#15488)
* Transpiler: implement exact Pauli generators for LightCone in Rust This PR adds exact Pauli generator expansions for the following gates: - single-qubit: H (X+Z) - 2-qubit: CX, CY, CZ, ECR, Swap, iSwap, CSX, CS, CSdg - parametric: CRX, CRY, CRZ, CPhase, RXX, RYY, RZZ, RZX, XXPlusYY, XXMinusYY - 3-qubit: CCX, CSwap This enables high-performance bitwise commutation checks in the LightCone pass, avoiding slow matrix-multiplication fallbacks. Parametric gates are scaled dynamically in Rust using the input parameters. Co-authored-by: Shelly Garion <shelly.garion@ibm.com> Co-authored-by: Alexander Ivrii <alexander.ivrii@ibm.com> * Lint: apply cargo fmt and fix clippy::map_clone in split_2q_unitaries.rs * Expose generator_observable to Python Following feedback from Alexander Ivrii, this commit exposes the Rust generator_observable function and the StandardGate enum to Python under the qiskit._accelerate.standard_generators submodule. This allows developers to verify the mathematical generators directly from Python and reuse the logic for other purposes like PauliEvolutionGate verification. The Rust-internal API is maintained via a dedicated generator_observable function that accepts slices. * Refactor generator logic to use qiskit_circuit::StandardGate * Update generator_observable with expansions for CCX/CCZ/CSwap * Fix generator fallback for unsupported gates and update docs * Narrow PR scope: remove split_2q_unitaries and pyext python wrapper * Add generator support for CS, CSdg, CSX, CCX, CCZ; add commutation tests * style: run black on test_commutation_checker.py * style: run rustfmt on standard_generators.rs * lint: fix license headers and pylint warnings * style: remove decorative unicode lines and add operator equivalence tests * fix: ensure strict Operator equivalence for all supported generators * style: fix pylint reimport and missing variables in test_commutation_checker.py * Add generic generator equivalence test, fix matrix conversion, and optimize gate generators * Format python tests * Update copyright year in standard_generators.rs * Clarify docstring for multi-qubit generators context * Fix XXPlusYY and XXMinusYY generator validation and test cases * Move test imports to top of file * Use ddt data parameterization for gate generator testing tests * Refactor test_clifford_gates_have_generators to use ddt * Add CPhase, CRX, CRY, CRZ to generator tests * Update test_all_gates_operator_equivalence_ddt docstring to be more accurate * Move all inline imports to the top of the file * Reorganize test data to group related gates logically * Add tests for unsupported gates and parameters in generator logic * Rename test helper to _commute to reflect that it uses either generator or matrix paths * Clarify parameter handling in generator_observable docstring * Comprehensive audit: Add Identity support and register all missing gates in SUPPORTED_OP * Fix: Correct gate generator expansions and resolve UnsortedIndices layout panic * pose generator engine, restore overflow logic, expand tests, and centralize constants * Update crates/circuit/src/util.rs Co-authored-by: Shelly Garion <46566946+ShellyGarion@users.noreply.github.com> * Update releasenotes/notes/pauli-evolution-commutation-8f7caab8.yaml Co-authored-by: Shelly Garion <46566946+ShellyGarion@users.noreply.github.com> * Update releasenotes/notes/pauli-evolution-commutation-8f7caab8.yaml Co-authored-by: Shelly Garion <46566946+ShellyGarion@users.noreply.github.com> * added missing gate, added test, copyright year, doc explaining * restore negative constants to util.rs for generator expansions * fix lint errors in regression test and move imports to top * Final PR fixes: address remaining lint issues and update copyright headers * Remove accidental temporary files from PR * Restore original copyright years for existing files (only PR-created files keep 2026) * Permanently delete bicycle-architecture-compiler from branch --------- Co-authored-by: Shelly Garion <shelly.garion@ibm.com> Co-authored-by: Alexander Ivrii <alexander.ivrii@ibm.com> Co-authored-by: Shelly Garion <46566946+ShellyGarion@users.noreply.github.com>
1 parent b2d4c87 commit 3942c9c

9 files changed

Lines changed: 900 additions & 13 deletions

File tree

crates/circuit/src/util.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,12 @@ pub const C_ONE: Complex64 = c64(1., 0.);
4747
pub const C_M_ONE: Complex64 = c64(-1., 0.);
4848
pub const IM: Complex64 = c64(0., 1.);
4949
pub const M_IM: Complex64 = c64(0., -1.);
50+
51+
use std::f64::consts::{FRAC_PI_2, FRAC_PI_4, FRAC_PI_8, SQRT_2};
52+
pub const C_FRAC_PI_2: Complex64 = c64(FRAC_PI_2, 0.0);
53+
pub const C_FRAC_PI_4: Complex64 = c64(FRAC_PI_4, 0.0);
54+
pub const C_FRAC_PI_8: Complex64 = c64(FRAC_PI_8, 0.0);
55+
pub const C_FRAC_PI_2_SQRT_2: Complex64 = c64(FRAC_PI_2 / SQRT_2, 0.0);
56+
pub const C_M_FRAC_PI_4: Complex64 = c64(-FRAC_PI_4, 0.0);
57+
pub const C_M_FRAC_PI_8: Complex64 = c64(-FRAC_PI_8, 0.0);
58+
pub const C_M_FRAC_PI_2_SQRT_2: Complex64 = c64(-FRAC_PI_2 / SQRT_2, 0.0);

crates/pyext/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ fn _accelerate(m: &Bound<PyModule>) -> PyResult<()> {
7272
add_submodule(m, ::qiskit_transpiler::passes::sabre::sabre, "sabre")?;
7373
add_submodule(m, ::qiskit_accelerate::sampled_exp_val::sampled_exp_val, "sampled_exp_val")?;
7474
add_submodule(m, ::qiskit_quantum_info::sparse_observable::sparse_observable, "sparse_observable")?;
75+
add_submodule(m, ::qiskit_quantum_info::sparse_observable::standard_generators::standard_generators, "standard_generators")?;
7576
add_submodule(m, ::qiskit_quantum_info::sparse_pauli_op::sparse_pauli_op, "sparse_pauli_op")?;
7677
add_submodule(m, ::qiskit_transpiler::passes::scheduling_mod, "scheduling")?;
7778
add_submodule(m, ::qiskit_quantum_info::unitary_sim::unitary_sim, "unitary_sim")?;

crates/quantum_info/src/sparse_observable/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
// copyright notice, and modified files need to carry a notice indicating
1111
// that they have been altered from the originals.
1212

13+
pub mod standard_generators;
14+
1315
mod lookup;
1416

1517
use hashbrown::HashSet;
@@ -4484,8 +4486,19 @@ fn coerce_to_observable<'py>(
44844486
}
44854487
}
44864488
}
4489+
#[pyfunction(name = "_generator_observable")]
4490+
#[pyo3(signature = (gate, params = None))]
4491+
pub fn generator_observable_py(
4492+
gate: qiskit_circuit::operations::StandardGate,
4493+
params: Option<Vec<qiskit_circuit::operations::Param>>,
4494+
) -> Option<SparseObservable> {
4495+
let params = params.unwrap_or_default();
4496+
standard_generators::generator_observable(gate, &params)
4497+
}
4498+
44874499
pub fn sparse_observable(m: &Bound<PyModule>) -> PyResult<()> {
44884500
m.add_class::<PySparseObservable>()?;
4501+
m.add_function(wrap_pyfunction!(generator_observable_py, m)?)?;
44894502
Ok(())
44904503
}
44914504

0 commit comments

Comments
 (0)