diff --git a/crates/accelerate/src/convert_2q_block_matrix.rs b/crates/accelerate/src/convert_2q_block_matrix.rs index 12146dd9d08..e9f6e343b6b 100644 --- a/crates/accelerate/src/convert_2q_block_matrix.rs +++ b/crates/accelerate/src/convert_2q_block_matrix.rs @@ -145,7 +145,6 @@ pub fn collect_2q_blocks_filter(node: &Bound) -> Option { } } -#[pymodule] pub fn convert_2q_block_matrix(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(blocks_to_matrix))?; m.add_wrapped(wrap_pyfunction!(collect_2q_blocks_filter))?; diff --git a/crates/accelerate/src/dense_layout.rs b/crates/accelerate/src/dense_layout.rs index 9529742d7e6..a7466748417 100644 --- a/crates/accelerate/src/dense_layout.rs +++ b/crates/accelerate/src/dense_layout.rs @@ -244,7 +244,6 @@ pub fn best_subset_inner( [rows, cols, best_map] } -#[pymodule] pub fn dense_layout(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(best_subset))?; Ok(()) diff --git a/crates/accelerate/src/error_map.rs b/crates/accelerate/src/error_map.rs index 8dbd2e4290a..b61733ae151 100644 --- a/crates/accelerate/src/error_map.rs +++ b/crates/accelerate/src/error_map.rs @@ -111,7 +111,6 @@ impl ErrorMap { } } -#[pymodule] pub fn error_map(m: &Bound) -> PyResult<()> { m.add_class::()?; Ok(()) diff --git a/crates/accelerate/src/euler_one_qubit_decomposer.rs b/crates/accelerate/src/euler_one_qubit_decomposer.rs index 7bbb6871db0..7463777af62 100644 --- a/crates/accelerate/src/euler_one_qubit_decomposer.rs +++ b/crates/accelerate/src/euler_one_qubit_decomposer.rs @@ -1059,7 +1059,6 @@ pub fn collect_1q_runs_filter(node: &Bound) -> bool { } } -#[pymodule] pub fn euler_one_qubit_decomposer(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(params_zyz))?; m.add_wrapped(wrap_pyfunction!(params_xyx))?; diff --git a/crates/accelerate/src/isometry.rs b/crates/accelerate/src/isometry.rs index ceaba2946b3..a54116b2b2f 100644 --- a/crates/accelerate/src/isometry.rs +++ b/crates/accelerate/src/isometry.rs @@ -345,7 +345,6 @@ fn b(k: usize, s: usize) -> usize { k - (a(k, s) * 2_usize.pow(s as u32)) } -#[pymodule] pub fn isometry(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(diag_is_identity_up_to_global_phase))?; m.add_wrapped(wrap_pyfunction!(find_squs_for_disentangling))?; diff --git a/crates/accelerate/src/nlayout.rs b/crates/accelerate/src/nlayout.rs index b3709d2804b..e0235e5c954 100644 --- a/crates/accelerate/src/nlayout.rs +++ b/crates/accelerate/src/nlayout.rs @@ -216,7 +216,6 @@ impl NLayout { } } -#[pymodule] pub fn nlayout(m: &Bound) -> PyResult<()> { m.add_class::()?; Ok(()) diff --git a/crates/accelerate/src/optimize_1q_gates.rs b/crates/accelerate/src/optimize_1q_gates.rs index a683604c19e..64924a33913 100644 --- a/crates/accelerate/src/optimize_1q_gates.rs +++ b/crates/accelerate/src/optimize_1q_gates.rs @@ -90,7 +90,6 @@ pub fn compose_u3_rust( out_angles } -#[pymodule] pub fn optimize_1q_gates(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(compose_u3_rust))?; Ok(()) diff --git a/crates/accelerate/src/pauli_exp_val.rs b/crates/accelerate/src/pauli_exp_val.rs index 8ee4b019b3e..bf9569b485e 100644 --- a/crates/accelerate/src/pauli_exp_val.rs +++ b/crates/accelerate/src/pauli_exp_val.rs @@ -193,7 +193,6 @@ pub fn density_expval_pauli_with_x( } } -#[pymodule] pub fn pauli_expval(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(expval_pauli_no_x))?; m.add_wrapped(wrap_pyfunction!(expval_pauli_with_x))?; diff --git a/crates/accelerate/src/results/mod.rs b/crates/accelerate/src/results/mod.rs index 36282a749e6..6d5a7936397 100644 --- a/crates/accelerate/src/results/mod.rs +++ b/crates/accelerate/src/results/mod.rs @@ -16,7 +16,6 @@ pub mod marginalization; use pyo3::prelude::*; use pyo3::wrap_pyfunction; -#[pymodule] pub fn results(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(marginalization::marginal_counts))?; m.add_wrapped(wrap_pyfunction!(marginalization::marginal_distribution))?; diff --git a/crates/accelerate/src/sabre/mod.rs b/crates/accelerate/src/sabre/mod.rs index 287fdd743df..77057b69c27 100644 --- a/crates/accelerate/src/sabre/mod.rs +++ b/crates/accelerate/src/sabre/mod.rs @@ -106,7 +106,6 @@ impl BlockResult { } } -#[pymodule] pub fn sabre(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(route::sabre_routing))?; m.add_wrapped(wrap_pyfunction!(layout::sabre_layout_and_routing))?; diff --git a/crates/accelerate/src/sampled_exp_val.rs b/crates/accelerate/src/sampled_exp_val.rs index 0b8836a9416..3424c12dcdf 100644 --- a/crates/accelerate/src/sampled_exp_val.rs +++ b/crates/accelerate/src/sampled_exp_val.rs @@ -87,7 +87,6 @@ pub fn sampled_expval_complex( Ok(out.re) } -#[pymodule] pub fn sampled_exp_val(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(sampled_expval_float))?; m.add_wrapped(wrap_pyfunction!(sampled_expval_complex))?; diff --git a/crates/accelerate/src/sparse_pauli_op.rs b/crates/accelerate/src/sparse_pauli_op.rs index 8a51d8ee781..73c4ab7a73d 100644 --- a/crates/accelerate/src/sparse_pauli_op.rs +++ b/crates/accelerate/src/sparse_pauli_op.rs @@ -819,7 +819,6 @@ impl_to_matrix_sparse!( u64 ); -#[pymodule] pub fn sparse_pauli_op(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(unordered_unique))?; m.add_wrapped(wrap_pyfunction!(decompose_dense))?; diff --git a/crates/accelerate/src/star_prerouting.rs b/crates/accelerate/src/star_prerouting.rs index fd2156ad201..dc777a84476 100644 --- a/crates/accelerate/src/star_prerouting.rs +++ b/crates/accelerate/src/star_prerouting.rs @@ -207,7 +207,6 @@ fn apply_swap( } } -#[pymodule] pub fn star_prerouting(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(star_preroute))?; Ok(()) diff --git a/crates/accelerate/src/stochastic_swap.rs b/crates/accelerate/src/stochastic_swap.rs index d4e3890b9cc..5260c85b3d4 100644 --- a/crates/accelerate/src/stochastic_swap.rs +++ b/crates/accelerate/src/stochastic_swap.rs @@ -335,7 +335,6 @@ pub fn swap_trials( Ok((best_edges, best_layout, best_depth)) } -#[pymodule] pub fn stochastic_swap(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(swap_trials))?; m.add_class::()?; diff --git a/crates/accelerate/src/synthesis/clifford/mod.rs b/crates/accelerate/src/synthesis/clifford/mod.rs index ac178b56670..4828a566673 100644 --- a/crates/accelerate/src/synthesis/clifford/mod.rs +++ b/crates/accelerate/src/synthesis/clifford/mod.rs @@ -57,7 +57,6 @@ fn synth_clifford_bm(py: Python, clifford: PyReadonlyArray2) -> PyResult) -> PyResult<()> { m.add_function(wrap_pyfunction!(synth_clifford_greedy, m)?)?; m.add_function(wrap_pyfunction!(synth_clifford_bm, m)?)?; diff --git a/crates/accelerate/src/synthesis/linear/mod.rs b/crates/accelerate/src/synthesis/linear/mod.rs index 49dfeefd386..08a0b1e104b 100644 --- a/crates/accelerate/src/synthesis/linear/mod.rs +++ b/crates/accelerate/src/synthesis/linear/mod.rs @@ -175,7 +175,6 @@ fn check_invertible_binary_matrix(py: Python, mat: PyReadonlyArray2) -> Py Ok(out.to_object(py)) } -#[pymodule] pub fn linear(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(gauss_elimination_with_perm))?; m.add_wrapped(wrap_pyfunction!(gauss_elimination))?; diff --git a/crates/accelerate/src/synthesis/mod.rs b/crates/accelerate/src/synthesis/mod.rs index 1b9908ef80c..fae05c6739c 100644 --- a/crates/accelerate/src/synthesis/mod.rs +++ b/crates/accelerate/src/synthesis/mod.rs @@ -15,12 +15,19 @@ pub mod linear; mod permutation; use pyo3::prelude::*; -use pyo3::wrap_pymodule; -#[pymodule] pub fn synthesis(m: &Bound) -> PyResult<()> { - m.add_wrapped(wrap_pymodule!(linear::linear))?; - m.add_wrapped(wrap_pymodule!(permutation::permutation))?; - m.add_wrapped(wrap_pymodule!(clifford::clifford))?; + let linear_mod = PyModule::new_bound(m.py(), "linear")?; + linear::linear(&linear_mod)?; + m.add_submodule(&linear_mod)?; + + let permutation_mod = PyModule::new_bound(m.py(), "permutation")?; + permutation::permutation(&permutation_mod)?; + m.add_submodule(&permutation_mod)?; + + let clifford_mod = PyModule::new_bound(m.py(), "clifford")?; + clifford::clifford(&clifford_mod)?; + m.add_submodule(&clifford_mod)?; + Ok(()) } diff --git a/crates/accelerate/src/synthesis/permutation/mod.rs b/crates/accelerate/src/synthesis/permutation/mod.rs index fccb0cfb972..55dc3efe4a8 100644 --- a/crates/accelerate/src/synthesis/permutation/mod.rs +++ b/crates/accelerate/src/synthesis/permutation/mod.rs @@ -114,7 +114,6 @@ pub fn _synth_permutation_depth_lnn_kms( ) } -#[pymodule] pub fn permutation(m: &Bound) -> PyResult<()> { m.add_function(wrap_pyfunction!(_validate_permutation, m)?)?; m.add_function(wrap_pyfunction!(_inverse_pattern, m)?)?; diff --git a/crates/accelerate/src/target_transpiler/mod.rs b/crates/accelerate/src/target_transpiler/mod.rs index b5c56dc6d09..bb0ec166c07 100644 --- a/crates/accelerate/src/target_transpiler/mod.rs +++ b/crates/accelerate/src/target_transpiler/mod.rs @@ -1254,8 +1254,7 @@ where obj_bound.is_instance(other_obj.bind(py)) } -#[pymodule] -pub fn target(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { +pub fn target(m: &Bound) -> PyResult<()> { m.add_class::()?; m.add_class::()?; Ok(()) diff --git a/crates/accelerate/src/two_qubit_decompose.rs b/crates/accelerate/src/two_qubit_decompose.rs index dfee4c5b0bf..b423b1d6526 100644 --- a/crates/accelerate/src/two_qubit_decompose.rs +++ b/crates/accelerate/src/two_qubit_decompose.rs @@ -2254,7 +2254,6 @@ pub fn local_equivalence(weyl: PyReadonlyArray1) -> PyResult<[f64; 3]> { Ok([g0_equiv + 0., g1_equiv + 0., g2_equiv + 0.]) } -#[pymodule] pub fn two_qubit_decompose(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(_num_basis_gates))?; m.add_wrapped(wrap_pyfunction!(two_qubit_decompose_up_to_diagonal))?; diff --git a/crates/accelerate/src/uc_gate.rs b/crates/accelerate/src/uc_gate.rs index 21fd7fa0465..ec79f4d4d2b 100644 --- a/crates/accelerate/src/uc_gate.rs +++ b/crates/accelerate/src/uc_gate.rs @@ -156,7 +156,6 @@ pub fn dec_ucg_help( ) } -#[pymodule] pub fn uc_gate(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(dec_ucg_help))?; Ok(()) diff --git a/crates/accelerate/src/utils.rs b/crates/accelerate/src/utils.rs index 6df00f7f8b7..598256192f8 100644 --- a/crates/accelerate/src/utils.rs +++ b/crates/accelerate/src/utils.rs @@ -41,7 +41,6 @@ pub fn eigenvalues(py: Python, unitary: PyReadonlyArray2>) -> PyObj .into() } -#[pymodule] pub fn utils(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(eigenvalues))?; Ok(()) diff --git a/crates/accelerate/src/vf2_layout.rs b/crates/accelerate/src/vf2_layout.rs index e84b2bfbfb8..476197397af 100644 --- a/crates/accelerate/src/vf2_layout.rs +++ b/crates/accelerate/src/vf2_layout.rs @@ -106,7 +106,6 @@ pub fn score_layout( Ok(1. - fidelity) } -#[pymodule] pub fn vf2_layout(m: &Bound) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(score_layout))?; m.add_class::()?; diff --git a/crates/circuit/src/lib.rs b/crates/circuit/src/lib.rs index 8a13aab33ce..739bf998a61 100644 --- a/crates/circuit/src/lib.rs +++ b/crates/circuit/src/lib.rs @@ -56,8 +56,7 @@ impl From for BitType { } } -#[pymodule] -pub fn circuit(m: Bound) -> PyResult<()> { +pub fn circuit(m: &Bound) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/crates/pyext/src/lib.rs b/crates/pyext/src/lib.rs index f9711641a93..04b0c060934 100644 --- a/crates/pyext/src/lib.rs +++ b/crates/pyext/src/lib.rs @@ -11,7 +11,6 @@ // that they have been altered from the originals. use pyo3::prelude::*; -use pyo3::wrap_pymodule; use qiskit_accelerate::{ convert_2q_block_matrix::convert_2q_block_matrix, dense_layout::dense_layout, @@ -24,30 +23,41 @@ use qiskit_accelerate::{ vf2_layout::vf2_layout, }; +#[inline(always)] +#[doc(hidden)] +fn add_submodule(m: &Bound, constructor: F, name: &str) -> PyResult<()> +where + F: FnOnce(&Bound) -> PyResult<()>, +{ + let new_mod = PyModule::new_bound(m.py(), name)?; + constructor(&new_mod)?; + m.add_submodule(&new_mod) +} + #[pymodule] fn _accelerate(m: &Bound) -> PyResult<()> { - m.add_wrapped(wrap_pymodule!(qiskit_circuit::circuit))?; - m.add_wrapped(wrap_pymodule!(qiskit_qasm2::qasm2))?; - m.add_wrapped(wrap_pymodule!(qiskit_qasm3::qasm3))?; - m.add_wrapped(wrap_pymodule!(convert_2q_block_matrix))?; - m.add_wrapped(wrap_pymodule!(dense_layout))?; - m.add_wrapped(wrap_pymodule!(error_map))?; - m.add_wrapped(wrap_pymodule!(euler_one_qubit_decomposer))?; - m.add_wrapped(wrap_pymodule!(isometry))?; - m.add_wrapped(wrap_pymodule!(nlayout))?; - m.add_wrapped(wrap_pymodule!(optimize_1q_gates))?; - m.add_wrapped(wrap_pymodule!(pauli_expval))?; - m.add_wrapped(wrap_pymodule!(synthesis))?; - m.add_wrapped(wrap_pymodule!(results))?; - m.add_wrapped(wrap_pymodule!(sabre))?; - m.add_wrapped(wrap_pymodule!(sampled_exp_val))?; - m.add_wrapped(wrap_pymodule!(sparse_pauli_op))?; - m.add_wrapped(wrap_pymodule!(star_prerouting))?; - m.add_wrapped(wrap_pymodule!(stochastic_swap))?; - m.add_wrapped(wrap_pymodule!(target))?; - m.add_wrapped(wrap_pymodule!(two_qubit_decompose))?; - m.add_wrapped(wrap_pymodule!(uc_gate))?; - m.add_wrapped(wrap_pymodule!(utils))?; - m.add_wrapped(wrap_pymodule!(vf2_layout))?; + add_submodule(m, qiskit_circuit::circuit, "circuit")?; + add_submodule(m, qiskit_qasm2::qasm2, "qasm2")?; + add_submodule(m, qiskit_qasm3::qasm3, "qasm3")?; + add_submodule(m, convert_2q_block_matrix, "convert_2q_block_matrix")?; + add_submodule(m, dense_layout, "dense_layout")?; + add_submodule(m, error_map, "error_map")?; + add_submodule(m, euler_one_qubit_decomposer, "euler_one_qubit_decomposer")?; + add_submodule(m, isometry, "isometry")?; + add_submodule(m, nlayout, "nlayout")?; + add_submodule(m, optimize_1q_gates, "optimize_1q_gates")?; + add_submodule(m, pauli_expval, "pauli_expval")?; + add_submodule(m, synthesis, "synthesis")?; + add_submodule(m, results, "results")?; + add_submodule(m, sabre, "sabre")?; + add_submodule(m, sampled_exp_val, "sampled_exp_val")?; + add_submodule(m, sparse_pauli_op, "sparse_pauli_op")?; + add_submodule(m, star_prerouting, "star_prerouting")?; + add_submodule(m, stochastic_swap, "stochastic_swap")?; + add_submodule(m, target, "target")?; + add_submodule(m, two_qubit_decompose, "two_qubit_decompose")?; + add_submodule(m, uc_gate, "uc_gate")?; + add_submodule(m, utils, "utils")?; + add_submodule(m, vf2_layout, "vf2_layout")?; Ok(()) } diff --git a/crates/qasm2/src/lib.rs b/crates/qasm2/src/lib.rs index 7129b17f7fd..beac72674e9 100644 --- a/crates/qasm2/src/lib.rs +++ b/crates/qasm2/src/lib.rs @@ -123,7 +123,6 @@ fn bytecode_from_file( /// An interface to the Rust components of the parser stack, and the types it uses to represent the /// output. The principal entry points for Python are :func:`bytecode_from_string` and /// :func:`bytecode_from_file`, which produce iterables of :class:`Bytecode` objects. -#[pymodule] pub fn qasm2(module: &Bound) -> PyResult<()> { module.add_class::()?; module.add_class::()?; diff --git a/crates/qasm3/src/lib.rs b/crates/qasm3/src/lib.rs index 9a651a5c12e..bca862406f3 100644 --- a/crates/qasm3/src/lib.rs +++ b/crates/qasm3/src/lib.rs @@ -153,7 +153,6 @@ pub fn load( /// Internal module supplying the OpenQASM 3 import capabilities. The entries in it should largely /// be re-exposed directly to public Python space. -#[pymodule] pub fn qasm3(module: &Bound) -> PyResult<()> { module.add_function(wrap_pyfunction!(loads, module)?)?; module.add_function(wrap_pyfunction!(load, module)?)?;