Skip to content

Commit

Permalink
Add: DAGCircuit::from_iter method.
Browse files Browse the repository at this point in the history
- Add `::from_iter()` to generate a `DAGCircuit` instance based on an iterator of `PackedInstructions` and the interner instances from the source.
   - The generated `DAGCircuit` is ensured to have the exact capacity required to store the instructions provided by doing pre-parsing before-hand. After pre-parsing a new `DAGCircuit` is generated by calling `DAGCircuit::with_capacity()` to provide a pre-allocated instance.
  • Loading branch information
raynelfss committed Aug 21, 2024
1 parent 2600f5c commit 36ce038
Showing 1 changed file with 64 additions and 3 deletions.
67 changes: 64 additions & 3 deletions crates/circuit/src/dag_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6322,12 +6322,73 @@ impl DAGCircuit {
Ok(new_nodes)
}

/// Creates an instance of DAGCircuit from an iterator over `PackedInstruction`.
pub fn from_iter<I>(_py: Python, _iter: I) -> PyResult<Self>
/// Creates an instance of DAGCircuit from an iterator over [PackedInstruction].
///
/// # Arguments:
/// - `py`: Python GIL token
/// - `iter`: Sequence of [PackedInstruction]
/// - `qarg_interner`: Reference to the source qubit interner.
/// - `carg_interner`: Reference to the source clbit interner.
pub fn from_iter<I>(
py: Python,
iter: I,
qarg_interner: &IndexedInterner<Vec<Qubit>>,
carg_interner: &IndexedInterner<Vec<Clbit>>,
) -> PyResult<Self>
where
I: IntoIterator<Item = PackedInstruction>,
{
todo!()
// Pre-parse the instructions to obtain metrics

// Collect all the qubits and clbits in use.
let mut qubit_set: HashSet<Qubit> = HashSet::default();
let mut clbit_set: HashSet<Clbit> = HashSet::default();

// Take ownership of the interners by cloning.
let cloned_qarg_interner = qarg_interner.clone();
let cloned_carg_interner = carg_interner.clone();

// Keep track of the necessary number of edges.
let mut num_edges = 0;

// Populate pre-processing fields.
let taken_instructions: Vec<PackedInstruction> = iter
.into_iter()
.map(|inst| {
let qargs = cloned_qarg_interner.intern(inst.qubits);
let cargs = cloned_carg_interner.intern(inst.clbits);

// Increase number of edges by the amount of incoming qubits and clbits
num_edges += qargs.len() + cargs.len();

// Extend the collection of qubits and clbits
qubit_set.extend(qargs);
clbit_set.extend(cargs);

inst
})
.collect();

// Increase the number of edges by the amount of qubits and clbits used.
num_edges += qubit_set.len() + clbit_set.len();

// Create a new DAGCircuit instance with the pre-parsed capacity.
let mut new_dag = DAGCircuit::with_capacity(
py,
qubit_set.len(),
clbit_set.len(),
Some(taken_instructions.len()),
None,
Some(num_edges),
)?;
// Set the interners to be the same as before.
new_dag.qargs_cache = cloned_qarg_interner;
new_dag.cargs_cache = cloned_carg_interner;

// Add all the valid instructions to the DAGCircuit.
new_dag.add_from_iter(py, taken_instructions)?;

Ok(new_dag)
}
}

Expand Down

0 comments on commit 36ce038

Please sign in to comment.