Skip to content

Commit

Permalink
Initial: Move the rest of the BasisTranslator to Rust.
Browse files Browse the repository at this point in the history
Fixes Port `BasisTranslator` to Rust Qiskit#12246

This is the final act of the efforts to move the `BasisTranslator` transpiler pass into Rust. With many of the parts of this pass already living in Rust, the following commits attempt to bring in the final changes to allow complete operation of this pass in the Rust space (with of course some interaction with Python.)

Methodology:
The way this works is by keeping the original `BasisTranslator` python class, and have it store the rust-space counterpart (now called `CoreBasisTranslator`) which will perform all of the operations leveraging the existent Rust API's available for the `Target` (Qiskit#12292), `EquivalenceLibrary`(Qiskit#12585) and the `BasisTranslator` methods `basis_search` (Qiskit#12811) and `compose_transforms`(Qiskit#13137).

All of the inner methods will have private visibility and will not be accessible to `Python` as they're intended to be internal by design.

By removing the extra layers of conversion we should be seeing a considerable speed-up, alongside all of the other incremental improvements we have made.

Changes:

- Add the pyo3 class/struct `BasisTranslator` that will contain allof the main data used by the transpiler pass to perform its operation.
- Convert the `target_basis` into a set manually from python before sending it into the Rust space.
- Remove the exposure of `basis_search` and `compose_transforms` to python.
- Change `basis_search` so that it accepts references to `HashSet` instances instead of accepting a `HashSet<&str>` instance.
- Change inner method's visibility for `basis_search` and `compose_transform` modules in rust.
- Expose the exception imports from `Target` to the `accelerate` crate.
- Expose `DAGCircuit::copy_empty_like` to the rest of the crates.
- Remove all of the unused imports in the Python-side `BasisTranslator`.

Blockers:
- [ ] Qiskit#12811
  • Loading branch information
raynelfss committed Sep 27, 2024
1 parent b2dc941 commit 14efd38
Show file tree
Hide file tree
Showing 6 changed files with 917 additions and 379 deletions.
35 changes: 2 additions & 33 deletions crates/accelerate/src/basis/basis_translator/basis_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use std::cell::RefCell;

use hashbrown::{HashMap, HashSet};
use pyo3::prelude::*;

use crate::equivalence::{EdgeData, Equivalence, EquivalenceLibrary, Key, NodeData};
use qiskit_circuit::operations::Operation;
Expand All @@ -23,36 +22,6 @@ use rustworkx_core::traversal::{dijkstra_search, DijkstraEvent};

use super::compose_transforms::{BasisTransformIn, GateIdentifier};

#[pyfunction]
#[pyo3(name = "basis_search")]
/// Search for a set of transformations from source_basis to target_basis.
/// Args:
/// equiv_lib (EquivalenceLibrary): Source of valid translations
/// source_basis (Set[Tuple[gate_name: str, gate_num_qubits: int]]): Starting basis.
/// target_basis (Set[gate_name: str]): Target basis.
///
/// Returns:
/// Optional[List[Tuple[gate, equiv_params, equiv_circuit]]]: List of (gate,
/// equiv_params, equiv_circuit) tuples tuples which, if applied in order
/// will map from source_basis to target_basis. Returns None if no path
/// was found.
pub(crate) fn py_basis_search(
py: Python,
equiv_lib: &mut EquivalenceLibrary,
source_basis: HashSet<GateIdentifier>,
target_basis: HashSet<String>,
) -> PyObject {
basis_search(
equiv_lib,
source_basis
.iter()
.map(|(name, num_qubits)| (name.as_str(), *num_qubits))
.collect(),
target_basis.iter().map(|name| name.as_str()).collect(),
)
.into_py(py)
}

type BasisTransforms = Vec<(GateIdentifier, BasisTransformIn)>;
/// Search for a set of transformations from source_basis to target_basis.
///
Expand All @@ -64,8 +33,8 @@ type BasisTransforms = Vec<(GateIdentifier, BasisTransformIn)>;
/// basis` are reached.
pub(crate) fn basis_search(
equiv_lib: &mut EquivalenceLibrary,
source_basis: HashSet<(&str, u32)>,
target_basis: HashSet<&str>,
source_basis: &HashSet<GateIdentifier>,
target_basis: &HashSet<String>,
) -> Option<BasisTransforms> {
// Build the visitor attributes:
let mut num_gates_remaining_for_rule: HashMap<usize, usize> = HashMap::default();
Expand Down
10 changes: 0 additions & 10 deletions crates/accelerate/src/basis/basis_translator/compose_transforms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ pub type GateIdentifier = (String, u32);
pub type BasisTransformIn = (SmallVec<[Param; 3]>, CircuitFromPython);
pub type BasisTransformOut = (SmallVec<[Param; 3]>, DAGCircuit);

#[pyfunction(name = "compose_transforms")]
pub(super) fn py_compose_transforms(
py: Python,
basis_transforms: Vec<(GateIdentifier, BasisTransformIn)>,
source_basis: HashSet<GateIdentifier>,
source_dag: &DAGCircuit,
) -> PyResult<HashMap<GateIdentifier, BasisTransformOut>> {
compose_transforms(py, &basis_transforms, &source_basis, source_dag)
}

pub(super) fn compose_transforms<'a>(
py: Python,
basis_transforms: &'a [(GateIdentifier, BasisTransformIn)],
Expand Down
Loading

0 comments on commit 14efd38

Please sign in to comment.