Skip to content

Commit

Permalink
Refactor: Rename example_gates to gate_param_counts
Browse files Browse the repository at this point in the history
- Remove `CircuitFromPython` and re-use original instance from `EquivalenceLibrary` after Qiskit#12585 merged.
  • Loading branch information
raynelfss committed Sep 27, 2024
1 parent 98cebda commit dbdc6a9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 38 deletions.
31 changes: 7 additions & 24 deletions crates/accelerate/src/basis/basis_translator/compose_transforms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// that they have been altered from the originals.

use hashbrown::{HashMap, HashSet};
use pyo3::{exceptions::PyTypeError, prelude::*};
use pyo3::prelude::*;
use qiskit_circuit::circuit_instruction::OperationFromPython;
use qiskit_circuit::imports::{GATE, PARAMETER_VECTOR, QUANTUM_CIRCUIT, QUANTUM_REGISTER};
use qiskit_circuit::imports::{GATE, PARAMETER_VECTOR, QUANTUM_REGISTER};
use qiskit_circuit::parameter_table::ParameterUuid;
use qiskit_circuit::Qubit;
use qiskit_circuit::{
Expand All @@ -23,29 +23,12 @@ use qiskit_circuit::{
};
use smallvec::SmallVec;

use crate::equivalence::CircuitFromPython;

// Custom types
pub type GateIdentifier = (String, u32);
pub type BasisTransformIn = (SmallVec<[Param; 3]>, CircuitFromPython);
pub type BasisTransformOut = (SmallVec<[Param; 3]>, DAGCircuit);
// TODO: Remove these and use the version from `EquivalenceLibrary`

/// Representation of QuantumCircuit which the original circuit object + an
/// instance of `CircuitData`.
#[derive(Debug, Clone)]
pub struct CircuitFromPython(pub CircuitData);

impl FromPyObject<'_> for CircuitFromPython {
fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
if ob.is_instance(QUANTUM_CIRCUIT.get_bound(ob.py()))? {
let data: CircuitData = ob.getattr("_data")?.extract()?;
Ok(Self(data))
} else {
Err(PyTypeError::new_err(
"Provided object was not an instance of QuantumCircuit",
))
}
}
}

#[pyfunction(name = "compose_transforms")]
pub(super) fn py_compose_transforms(
Expand All @@ -63,12 +46,12 @@ pub(super) fn compose_transforms<'a>(
source_basis: &'a HashSet<GateIdentifier>,
source_dag: &'a DAGCircuit,
) -> PyResult<HashMap<GateIdentifier, BasisTransformOut>> {
let mut example_gates: HashMap<GateIdentifier, usize> = HashMap::default();
get_gates_num_params(source_dag, &mut example_gates)?;
let mut gate_param_counts: HashMap<GateIdentifier, usize> = HashMap::default();
get_gates_num_params(source_dag, &mut gate_param_counts)?;
let mut mapped_instructions: HashMap<GateIdentifier, BasisTransformOut> = HashMap::new();

for (gate_name, gate_num_qubits) in source_basis.iter().cloned() {
let num_params = example_gates[&(gate_name.clone(), gate_num_qubits)];
let num_params = gate_param_counts[&(gate_name.clone(), gate_num_qubits)];

let placeholder_params: SmallVec<[Param; 3]> = PARAMETER_VECTOR
.get_bound(py)
Expand Down
39 changes: 25 additions & 14 deletions crates/accelerate/src/equivalence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@ pub struct Equivalence {
#[pyo3(get)]
pub params: SmallVec<[Param; 3]>,
#[pyo3(get)]
pub circuit: CircuitRep,
pub circuit: CircuitFromPython,
}

#[pymethods]
impl Equivalence {
#[new]
#[pyo3(signature = (params, circuit))]
fn new(params: SmallVec<[Param; 3]>, circuit: CircuitRep) -> Self {
fn new(params: SmallVec<[Param; 3]>, circuit: CircuitFromPython) -> Self {
Self { circuit, params }
}

Expand Down Expand Up @@ -295,15 +295,17 @@ impl<'py> FromPyObject<'py> for GateOper {
}
}

/// Representation of QuantumCircuit by using an instance of `CircuitData`.]
/// Used to extract an instance of [CircuitData] from a `QuantumCircuit`.
/// It also ensures seamless conversion back to `QuantumCircuit` once sent
/// back to Python.
///
/// TODO: Remove this implementation once the `EquivalenceLibrary` is no longer
/// called from Python, or once the API is able to seamlessly accept instances
/// of `CircuitData`.
/// of [CircuitData].
#[derive(Debug, Clone)]
pub struct CircuitRep(pub CircuitData);
pub struct CircuitFromPython(pub CircuitData);

impl FromPyObject<'_> for CircuitRep {
impl FromPyObject<'_> for CircuitFromPython {
fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
if ob.is_instance(QUANTUM_CIRCUIT.get_bound(ob.py()))? {
let data: Bound<PyAny> = ob.getattr("_data")?;
Expand All @@ -318,7 +320,7 @@ impl FromPyObject<'_> for CircuitRep {
}
}

impl IntoPy<PyObject> for CircuitRep {
impl IntoPy<PyObject> for CircuitFromPython {
fn into_py(self, py: Python<'_>) -> PyObject {
QUANTUM_CIRCUIT
.get_bound(py)
Expand All @@ -328,7 +330,7 @@ impl IntoPy<PyObject> for CircuitRep {
}
}

impl ToPyObject for CircuitRep {
impl ToPyObject for CircuitFromPython {
fn to_object(&self, py: Python<'_>) -> PyObject {
self.clone().into_py(py)
}
Expand Down Expand Up @@ -395,7 +397,7 @@ impl EquivalenceLibrary {
&mut self,
py: Python,
gate: GateOper,
equivalent_circuit: CircuitRep,
equivalent_circuit: CircuitFromPython,
) -> PyResult<()> {
self.add_equivalence(py, &gate.operation, &gate.params, equivalent_circuit)
}
Expand Down Expand Up @@ -425,7 +427,12 @@ impl EquivalenceLibrary {
/// entry (List['QuantumCircuit']) : A list of QuantumCircuits, each
/// equivalently implementing the given Gate.
#[pyo3(name = "set_entry")]
fn py_set_entry(&mut self, py: Python, gate: GateOper, entry: Vec<CircuitRep>) -> PyResult<()> {
fn py_set_entry(
&mut self,
py: Python,
gate: GateOper,
entry: Vec<CircuitFromPython>,
) -> PyResult<()> {
self.set_entry(py, &gate.operation, &gate.params, entry)
}

Expand Down Expand Up @@ -567,7 +574,7 @@ impl EquivalenceLibrary {
py: Python,
gate: &PackedOperation,
params: &[Param],
equivalent_circuit: CircuitRep,
equivalent_circuit: CircuitFromPython,
) -> PyResult<()> {
raise_if_shape_mismatch(gate, &equivalent_circuit)?;
raise_if_param_mismatch(py, params, equivalent_circuit.0.unsorted_parameters(py)?)?;
Expand Down Expand Up @@ -614,7 +621,7 @@ impl EquivalenceLibrary {
py: Python,
gate: &PackedOperation,
params: &[Param],
entry: Vec<CircuitRep>,
entry: Vec<CircuitFromPython>,
) -> PyResult<()> {
for equiv in entry.iter() {
raise_if_shape_mismatch(gate, equiv)?;
Expand Down Expand Up @@ -714,7 +721,7 @@ fn raise_if_param_mismatch(
Ok(())
}

fn raise_if_shape_mismatch(gate: &PackedOperation, circuit: &CircuitRep) -> PyResult<()> {
fn raise_if_shape_mismatch(gate: &PackedOperation, circuit: &CircuitFromPython) -> PyResult<()> {
let op_ref = gate.view();
if op_ref.num_qubits() != circuit.0.num_qubits() as u32
|| op_ref.num_clbits() != circuit.0.num_clbits() as u32
Expand All @@ -732,7 +739,11 @@ fn raise_if_shape_mismatch(gate: &PackedOperation, circuit: &CircuitRep) -> PyRe
Ok(())
}

fn rebind_equiv(py: Python, equiv: Equivalence, query_params: &[Param]) -> PyResult<CircuitRep> {
fn rebind_equiv(
py: Python,
equiv: Equivalence,
query_params: &[Param],
) -> PyResult<CircuitFromPython> {
let (equiv_params, mut equiv_circuit) = (equiv.params, equiv.circuit);
let param_mapping: PyResult<IndexMap<ParameterUuid, &Param>> = equiv_params
.iter()
Expand Down

0 comments on commit dbdc6a9

Please sign in to comment.