Skip to content

Commit

Permalink
Oxidize UnitarySynthesis pass (#13141)
Browse files Browse the repository at this point in the history
* Inital attempt at oxidizing unitary synthesis.

* Add cacache pygates feature to accelerate

* Use sabre target to speed up preferred_direction

* Adapt code to changes in PackedInstruction

* Use target in preferred_direction

* Some cleanup

* More cleanup

* Apply inline suggestions from  Matt's code review

Co-authored-by: Matthew Treinish <[email protected]>

* Apply remaining review suggestions:

 * Fix details after applying inline suggestions
 * Keep TwoQubitWeilDecomposition attributes private. Add getter.
 * Initialize new_blocks using size hint
 * Remove basis_set as it's not used if there is a target.
 * Use ref_qubits ([PhysicalQubit; 2]) instead of wire_map (IndexMap<Qubit, Physicalqubit>)
 * Define static GOODBYE_SET as suggested
 * Use ImportOnceCell for XXDecomposer and XXEmbodiments to avoid importing in a loop.
 * Set preferred_direction without making it mutable.
 * Fix check_goodbye
 * Privatize assets
 * Use the add_global_phase method instead of the private function.
 * Add qs_decomposition to imports
 * Simplify flip_bits
 * Use NormalOperation to pass around decomposer gate and params info
 * First attempt at attaching synth circuits directly
 * Second attempt at attaching synth circuits directly
 * Use edge set for coupling map
 * Avoid exposing internals from NullableIndexMap
 * Use unitary_to_gate_sequence_inner instead of optimize_1q_gates_decomposition.
 * Use concat! in long error message.

* Use dag.apply_operation_back in 1q case. Additional cleanup.

* Don't return ref to float in two qubit decomposer.

* Use PyList as input type for coupling_edges (previous approach was innefficient)

* Avoid using UnitarySynthesisReturn type, avoid intermediate dag creation in all cases except XXDecomposer.

* Refactor appending to out_dag, remove unnecesary clones.

* Cosmetic changes. Reduce indentation.

* Squash bug

* Fix clippy

* Add qsd test

* Avoid making unnecessary variables public

* Use OperationRef instead of exposing discriminant

* Rename DAGCircuit::substitue_node to py_substitute_node

Co-authored-by: Raynel Sanchez <[email protected]>

* Restore name in Python world

* Rewrite using flatten

Co-authored-by: Raynel Sanchez <[email protected]>

* Apply suggestions from Ray's code review

Co-authored-by: Raynel Sanchez <[email protected]>

* Adjust suggestions from code review. Apply remaining feedback:

* Use circuit_to_dag from crates/circuit/converters.rs

* Simplify iteration over coupling edges

* Replace cumbersome call_method_bound with call_bound

* Apply ownership suggestion from Ray

Co-authored-by: Raynel Sanchez <[email protected]>

* Finish applying ownership suggestion from Ray

* Changes to synth_error function: remove error that wasn't handled, deal with new panic calling operation_from_name

* Undo flatten

* Fix style

* Add getters and setters for TwoQubitGateSequence, expose new, keep struct attributes private.

* Apply Ray's suggestion to use unwrap_operation

Co-authored-by: Raynel Sanchez <[email protected]>

* Use ExtraInstructionAttributes::default()

* Apply suggestion to avoid intermediate collection

* Use target::contains_key

* Apply suggestion to use iter() instead of keys()

Co-authored-by: Raynel Sanchez <[email protected]>

* Final touches

* Final touches

* Replace panics with unreachable

* Format

* Apply suggestions from Matt's code review

Co-authored-by: Matthew Treinish <[email protected]>

* Fix suggestions from Matt's code review

* Apply remaining suggestions

* Apply final suggestions from code review

* Lint: Use `unwrap_or_default()`.

---------

Co-authored-by: Matthew Treinish <[email protected]>
Co-authored-by: Raynel Sanchez <[email protected]>
  • Loading branch information
3 people authored Oct 18, 2024
1 parent 68a1eca commit a9b8f4a
Show file tree
Hide file tree
Showing 10 changed files with 1,176 additions and 12 deletions.
4 changes: 2 additions & 2 deletions crates/accelerate/src/euler_one_qubit_decomposer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ pub fn generate_circuit(

const EULER_BASIS_SIZE: usize = 12;

static EULER_BASES: [&[&str]; EULER_BASIS_SIZE] = [
pub static EULER_BASES: [&[&str]; EULER_BASIS_SIZE] = [
&["u3"],
&["u3", "u2", "u1"],
&["u"],
Expand All @@ -595,7 +595,7 @@ static EULER_BASES: [&[&str]; EULER_BASIS_SIZE] = [
&["rz", "sx", "x"],
&["rz", "sx"],
];
static EULER_BASIS_NAMES: [EulerBasis; EULER_BASIS_SIZE] = [
pub static EULER_BASIS_NAMES: [EulerBasis; EULER_BASIS_SIZE] = [
EulerBasis::U3,
EulerBasis::U321,
EulerBasis::U,
Expand Down
1 change: 1 addition & 0 deletions crates/accelerate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub mod synthesis;
pub mod target_transpiler;
pub mod two_qubit_decompose;
pub mod uc_gate;
pub mod unitary_synthesis;
pub mod utils;
pub mod vf2_layout;

Expand Down
39 changes: 36 additions & 3 deletions crates/accelerate/src/two_qubit_decompose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,15 @@ pub struct TwoQubitWeylDecomposition {
}

impl TwoQubitWeylDecomposition {
pub fn a(&self) -> f64 {
self.a
}
pub fn b(&self) -> f64 {
self.b
}
pub fn c(&self) -> f64 {
self.c
}
fn weyl_gate(
&self,
simplify: bool,
Expand Down Expand Up @@ -1231,17 +1240,39 @@ impl TwoQubitWeylDecomposition {

type TwoQubitSequenceVec = Vec<(Option<StandardGate>, SmallVec<[f64; 3]>, SmallVec<[u8; 2]>)>;

#[derive(Clone, Debug)]
#[pyclass(sequence)]
pub struct TwoQubitGateSequence {
gates: TwoQubitSequenceVec,
#[pyo3(get)]
global_phase: f64,
}

impl TwoQubitGateSequence {
pub fn gates(&self) -> &TwoQubitSequenceVec {
&self.gates
}

pub fn global_phase(&self) -> f64 {
self.global_phase
}

pub fn set_state(&mut self, state: (TwoQubitSequenceVec, f64)) {
self.gates = state.0;
self.global_phase = state.1;
}
}

impl Default for TwoQubitGateSequence {
fn default() -> Self {
Self::new()
}
}

#[pymethods]
impl TwoQubitGateSequence {
#[new]
fn new() -> Self {
pub fn new() -> Self {
TwoQubitGateSequence {
gates: Vec::new(),
global_phase: 0.,
Expand Down Expand Up @@ -1273,6 +1304,8 @@ impl TwoQubitGateSequence {
}
}
}

#[derive(Clone, Debug)]
#[allow(non_snake_case)]
#[pyclass(module = "qiskit._accelerate.two_qubit_decompose", subclass)]
pub struct TwoQubitBasisDecomposer {
Expand Down Expand Up @@ -1660,7 +1693,7 @@ impl TwoQubitBasisDecomposer {
Ok(res)
}

fn new_inner(
pub fn new_inner(
gate: String,
gate_matrix: ArrayView2<Complex64>,
basis_fidelity: f64,
Expand Down Expand Up @@ -1798,7 +1831,7 @@ impl TwoQubitBasisDecomposer {
})
}

fn call_inner(
pub fn call_inner(
&self,
unitary: ArrayView2<Complex64>,
basis_fidelity: Option<f64>,
Expand Down
Loading

0 comments on commit a9b8f4a

Please sign in to comment.