diff --git a/Cargo.lock b/Cargo.lock index 67bf99d2a083..f973ba5f2a2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2528,6 +2528,7 @@ dependencies = [ "rustworkx-core", "smallvec", "thiserror 2.0.18", + "thread_local", "uuid", ] diff --git a/crates/pyext/src/lib.rs b/crates/pyext/src/lib.rs index 0b70641b36cc..c8e8bcfa71e8 100644 --- a/crates/pyext/src/lib.rs +++ b/crates/pyext/src/lib.rs @@ -76,6 +76,11 @@ fn _accelerate(m: &Bound) -> PyResult<()> { add_submodule(m, ::qiskit_transpiler::passes::high_level_synthesis_mod, "high_level_synthesis")?; add_submodule(m, ::qiskit_transpiler::passes::remove_diagonal_gates_before_measure_mod, "remove_diagonal_gates_before_measure")?; add_submodule(m, ::qiskit_transpiler::passes::remove_identity_equiv_mod, "remove_identity_equiv")?; + add_submodule( + m, + ::qiskit_transpiler::passes::two_qubit_peephole_mod, + "two_qubit_peephole", + )?; add_submodule(m, ::qiskit_accelerate::results::results, "results")?; add_submodule(m, ::qiskit_transpiler::passes::sabre::sabre, "sabre")?; add_submodule(m, ::qiskit_accelerate::sampled_exp_val::sampled_exp_val, "sampled_exp_val")?; diff --git a/crates/synthesis/src/qsd.rs b/crates/synthesis/src/qsd.rs index ce6a3ace9a95..9d2fb688ff35 100644 --- a/crates/synthesis/src/qsd.rs +++ b/crates/synthesis/src/qsd.rs @@ -109,7 +109,7 @@ pub fn quantum_shannon_decomposition( smallvec![], aview2(&qiskit_circuit::gate_matrix::CX_GATE), 1.0, - "U", + EulerBasis::U, None, )?; let one_qubit_decomposer = one_qubit_decomposer_basis_set.unwrap_or(&default_1q_basis); diff --git a/crates/synthesis/src/two_qubit_decompose/basis_decomposer.rs b/crates/synthesis/src/two_qubit_decompose/basis_decomposer.rs index 42db5797fe9a..86220b3955dd 100644 --- a/crates/synthesis/src/two_qubit_decompose/basis_decomposer.rs +++ b/crates/synthesis/src/two_qubit_decompose/basis_decomposer.rs @@ -10,6 +10,8 @@ // copyright notice, and modified files need to carry a notice indicating // that they have been altered from the originals. +use std::str::FromStr; + use approx::{abs_diff_eq, relative_eq}; use num_complex::{Complex64, ComplexFloat}; use num_traits::Zero; @@ -139,6 +141,12 @@ impl TwoQubitBasisDecomposer { __num_basis_gates(self.basis_decomposer.b, self.basis_fidelity, u) } + /// Is the gate super controlled + #[inline] + pub fn super_controlled(&self) -> bool { + self.super_controlled + } + fn decomp1_inner( &self, target: &TwoQubitWeylDecomposition, @@ -524,7 +532,7 @@ impl TwoQubitBasisDecomposer { gate_params: SmallVec<[f64; 3]>, gate_matrix: ArrayView2, basis_fidelity: f64, - euler_basis: &str, + euler_basis: EulerBasis, pulse_optimize: Option, ) -> PyResult { let basis_decomposer = @@ -610,7 +618,7 @@ impl TwoQubitBasisDecomposer { gate, gate_params, basis_fidelity, - euler_basis: EulerBasis::__new__(euler_basis)?, + euler_basis, pulse_optimize, basis_decomposer, super_controlled, @@ -787,7 +795,7 @@ impl TwoQubitBasisDecomposer { gate_params?, gate_matrix.as_array(), basis_fidelity, - euler_basis, + EulerBasis::from_str(euler_basis).map_err(PyValueError::new_err)?, pulse_optimize, ) } @@ -1020,7 +1028,7 @@ pub fn two_qubit_decompose_up_to_diagonal( smallvec![], aview2(&CX_GATE), 1.0, - "U", + EulerBasis::U, None, )?; diff --git a/crates/synthesis/src/two_qubit_decompose/gate_sequence.rs b/crates/synthesis/src/two_qubit_decompose/gate_sequence.rs index cc170d4386a4..8d8d79e4b49b 100644 --- a/crates/synthesis/src/two_qubit_decompose/gate_sequence.rs +++ b/crates/synthesis/src/two_qubit_decompose/gate_sequence.rs @@ -17,8 +17,8 @@ pub(crate) type TwoQubitSequenceVec = Vec<(PackedOperation, SmallVec<[f64; 3]>, #[derive(Clone, Debug)] pub struct TwoQubitGateSequence { - pub(crate) gates: TwoQubitSequenceVec, - pub(crate) global_phase: f64, + pub gates: TwoQubitSequenceVec, + pub global_phase: f64, } impl TwoQubitGateSequence { diff --git a/crates/transpiler/Cargo.toml b/crates/transpiler/Cargo.toml index 6221abb5f06b..f244782059fd 100644 --- a/crates/transpiler/Cargo.toml +++ b/crates/transpiler/Cargo.toml @@ -31,6 +31,7 @@ thiserror.workspace = true bytemuck.workspace = true fixedbitset.workspace = true anyhow.workspace = true +thread_local = "1.1" [dependencies.uuid] workspace = true diff --git a/crates/transpiler/src/passes/consolidate_blocks.rs b/crates/transpiler/src/passes/consolidate_blocks.rs index 50c5b6178a9f..67b9e461ef26 100644 --- a/crates/transpiler/src/passes/consolidate_blocks.rs +++ b/crates/transpiler/src/passes/consolidate_blocks.rs @@ -31,6 +31,7 @@ use qiskit_circuit::interner::Interned; use qiskit_circuit::operations::StandardGate; use qiskit_circuit::operations::{ArrayType, Operation, Param, UnitaryGate}; use qiskit_circuit::packed_instruction::PackedOperation; +use qiskit_synthesis::euler_one_qubit_decomposer::EulerBasis; use qiskit_synthesis::linalg::nalgebra_array_view; use qiskit_synthesis::matrix::two_qubit::{ blocks_to_matrix, get_1q_matrix_from_inst, get_2q_matrix_from_inst, get_matrix_from_inst, @@ -145,7 +146,7 @@ fn get_decomposer_and_basis_gate( SmallVec::default(), get_matrix(&gate), approximation_degree, - "U", + EulerBasis::U, None, ) .unwrap_or_else(|_| { @@ -167,7 +168,7 @@ fn get_decomposer_and_basis_gate( SmallVec::default(), aview2(&CX_GATE), 1.0, - "U", + EulerBasis::U, None, ) .expect("Error while creating TwoQubitBasisDecomposer using a 'cx' gate."), diff --git a/crates/transpiler/src/passes/high_level_synthesis.rs b/crates/transpiler/src/passes/high_level_synthesis.rs index 750d8f890a6d..bab207ada29f 100644 --- a/crates/transpiler/src/passes/high_level_synthesis.rs +++ b/crates/transpiler/src/passes/high_level_synthesis.rs @@ -769,7 +769,7 @@ fn extract_definition(op: &PackedOperation, params: &[Param]) -> PyResult