Skip to content

Commit

Permalink
Add: num_edges optional argument.
Browse files Browse the repository at this point in the history
- If known, use `num_edges` argument to create a `DAGCircuit` with the exact number of edges.
- Leverage usage of new method in `copy_empty_like`.
- Use `..Default::default()` for `op_names` and `calibrations` fields in `DAGCircuit::with_capacity()`
- Other small tweaks and fixes.
  • Loading branch information
raynelfss committed Aug 20, 2024
1 parent c5152d8 commit 3fab832
Showing 1 changed file with 27 additions and 10 deletions.
37 changes: 27 additions & 10 deletions crates/circuit/src/dag_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1520,7 +1520,14 @@ def _format(operand):
/// DAGCircuit: An empty copy of self.
#[pyo3(signature = (*, vars_mode="alike"))]
fn copy_empty_like(&self, py: Python, vars_mode: &str) -> PyResult<Self> {
let mut target_dag = DAGCircuit::new(py)?;
let mut target_dag = DAGCircuit::with_capacity(
py,
self.num_qubits(),
self.num_clbits(),
Some(self.num_vars()),
None,
None,
)?;
target_dag.name = self.name.as_ref().map(|n| n.clone_ref(py));
target_dag.global_phase = self.global_phase.clone();
target_dag.duration = self.duration.as_ref().map(|d| d.clone_ref(py));
Expand Down Expand Up @@ -6114,31 +6121,41 @@ impl DAGCircuit {
}

/// Alternative constructor, builds a DAGCircuit with a fixed capacity.
///
/// # Arguments:
/// - `py`: Python GIL token
/// - `num_qubits`: Number of qubits in the circuit
/// - `num_clbits`: Number of classical bits in the circuit.
/// - `num_vars`: (Optional) number of variables in the circuit.
/// - `num_ops`: (Optional) number of operations in the circuit.
/// - `num_edges`: (Optional) If known, number of edges in the circuit.
pub fn with_capacity(
py: Python,
num_qubits: usize,
num_clbits: usize,
num_ops: Option<usize>,
num_vars: Option<usize>,
num_edges: Option<usize>,
) -> PyResult<Self> {
let num_ops = num_ops.unwrap_or_default();
let num_vars = num_vars.unwrap_or_default();
let num_edges = num_edges.unwrap_or(
num_qubits + // 1 edge between the input node and the output node or 1st op node.
num_clbits + // 1 edge between the input node and the output node or 1st op node.
num_vars + // 1 edge between the input node and the output node or 1st op node.
num_ops, // In Average there will be 3 edges (2 qubits and 1 clbit, or 3 qubits) per op_node.
);

let dag_nodes = num_qubits * 2 + // One input + One output node per qubit
let num_nodes = num_qubits * 2 + // One input + One output node per qubit
num_clbits * 2 + // One input + One output node per clbit
num_vars * 2 + // One input + output node per variable
num_ops;

let dag_edges = num_qubits + // 1 edge between the input node and the output node or 1st op node.
num_clbits + // 1 edge between the input node and the output node or 1st op node.
num_vars + // 1 edge between the input node and the output node or 1st op node.
num_ops * 3; // In Average there will be 3 edges (2 qubits and 1 clbit, or 3 qubits) per op_node.

Ok(Self {
name: None,
metadata: Some(PyDict::new_bound(py).unbind().into()),
calibrations: HashMap::with_capacity(0),
dag: StableDiGraph::with_capacity(dag_nodes, dag_edges),
calibrations: HashMap::default(),
dag: StableDiGraph::with_capacity(num_nodes, num_edges),
qregs: PyDict::new_bound(py).unbind(),
cregs: PyDict::new_bound(py).unbind(),
qargs_cache: IndexedInterner::with_capacity(num_qubits),
Expand All @@ -6154,7 +6171,7 @@ impl DAGCircuit {
clbit_io_map: IndexMap::with_capacity_and_hasher(num_clbits, RandomState::new()),
var_input_map: _VarIndexMap::new(py),
var_output_map: _VarIndexMap::new(py),
op_names: IndexMap::with_capacity_and_hasher(num_ops, RandomState::new()), // Based on worst case scenario, could be improved
op_names: IndexMap::default(),
control_flow_module: PyControlFlowModule::new(py)?,
vars_info: HashMap::with_capacity(num_vars),
vars_by_type: [
Expand Down

0 comments on commit 3fab832

Please sign in to comment.