From 5da0be5f05a8e2290a58329ac70d36b14b1d6568 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 29 Jul 2024 15:56:19 -0400 Subject: [PATCH] Make interface public --- qiskit/converters/circuit_to_dag.py | 2 +- qiskit/dagcircuit/dagcircuit.py | 21 ++++++++++++++----- .../one_qubit/one_qubit_decompose.py | 4 ++-- .../two_qubit/two_qubit_decompose.py | 4 ++-- .../passes/basis/basis_translator.py | 4 ++-- .../transpiler/passes/layout/apply_layout.py | 4 ++-- .../passes/layout/disjoint_utils.py | 4 ++-- .../transpiler/passes/layout/sabre_layout.py | 4 ++-- ...size-hint-dagcircuit-0202303345633806.yaml | 10 +++++++++ 9 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 releasenotes/notes/add-size-hint-dagcircuit-0202303345633806.yaml diff --git a/qiskit/converters/circuit_to_dag.py b/qiskit/converters/circuit_to_dag.py index 2d4703e72956..fc40b32f2c30 100644 --- a/qiskit/converters/circuit_to_dag.py +++ b/qiskit/converters/circuit_to_dag.py @@ -59,7 +59,7 @@ def circuit_to_dag(circuit, copy_operations=True, *, qubit_order=None, clbit_ord num_ops = len(circuit.data) node_count = 2 * num_bits + num_ops edge_count = num_bits + num_ops - dagcircuit = DAGCircuit(_node_count_hint=node_count, _edge_count_hint=edge_count) + dagcircuit = DAGCircuit(node_count_hint=node_count, edge_count_hint=edge_count) dagcircuit.name = circuit.name dagcircuit.global_phase = circuit.global_phase dagcircuit.calibrations = circuit.calibrations diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py index d2a97843a722..a70f60d77eb6 100644 --- a/qiskit/dagcircuit/dagcircuit.py +++ b/qiskit/dagcircuit/dagcircuit.py @@ -73,8 +73,19 @@ class DAGCircuit: # pylint: disable=invalid-name - def __init__(self, _node_count_hint=0, _edge_count_hint=0): - """Create an empty circuit.""" + def __init__(self, node_count_hint=0, edge_count_hint=0): + """Create an empty circuit. + + Args: + node_count_hint (int): An optional hint that will allocate with enough capacity to + store this many nodes before needing to grow. This does not prepopulate any nodes + with data, it is only a potential performance optimization if the complete size of + the graph is known in advance. + edge_count_hint (int): An optional hint that will allocate enough capacity to store + this many edges before needing to grow. This does not prepopulate any edges with + data, it is only a potential performance optimization if the complete size of the + graph is known in advance. + """ # Circuit name. Generally, this corresponds to the name # of the QuantumCircuit from which the DAG was generated. @@ -114,7 +125,7 @@ def __init__(self, _node_count_hint=0, _edge_count_hint=0): # Edges carry wire labels and each operation has # corresponding in- and out-edges with the same wire labels. self._multi_graph = rx.PyDAG( - node_count_hint=_node_count_hint, edge_count_hint=_edge_count_hint + node_count_hint=node_count_hint, edge_count_hint=edge_count_hint ) # Map of qreg/creg name to Register object. @@ -689,8 +700,8 @@ def copy_empty_like(self, *, vars_mode: _VarsMode = "alike"): DAGCircuit: An empty copy of self. """ target_dag = DAGCircuit( - _node_count_hint=self._multi_graph.num_nodes(), - _edge_count_hint=self._multi_graph.num_edges(), + node_count_hint=self._multi_graph.num_nodes(), + edge_count_hint=self._multi_graph.num_edges(), ) target_dag.name = self.name target_dag._global_phase = self._global_phase diff --git a/qiskit/synthesis/one_qubit/one_qubit_decompose.py b/qiskit/synthesis/one_qubit/one_qubit_decompose.py index cd20a108ca18..79f65c903cff 100644 --- a/qiskit/synthesis/one_qubit/one_qubit_decompose.py +++ b/qiskit/synthesis/one_qubit/one_qubit_decompose.py @@ -164,8 +164,8 @@ def build_circuit(self, gates, global_phase) -> QuantumCircuit | DAGCircuit: from qiskit.dagcircuit import dagcircuit dag = dagcircuit.DAGCircuit( - _node_count_hint=len(gates) + 2, - _edge_count_hint=len(gates) + 1, + node_count_hint=len(gates) + 2, + edge_count_hint=len(gates) + 1, ) dag.global_phase = global_phase dag.add_qubits(qr) diff --git a/qiskit/synthesis/two_qubit/two_qubit_decompose.py b/qiskit/synthesis/two_qubit/two_qubit_decompose.py index 083fae844bb8..1933e161d3ed 100644 --- a/qiskit/synthesis/two_qubit/two_qubit_decompose.py +++ b/qiskit/synthesis/two_qubit/two_qubit_decompose.py @@ -650,8 +650,8 @@ def __call__( q = QuantumRegister(2) dag = DAGCircuit( - _node_count_hint=4 + len(sequence), - _edge_count_hint=2 + len(sequence), + node_count_hint=4 + len(sequence), + edge_count_hint=2 + len(sequence), ) dag.global_phase = sequence.global_phase dag.add_qreg(q) diff --git a/qiskit/transpiler/passes/basis/basis_translator.py b/qiskit/transpiler/passes/basis/basis_translator.py index cb6c7d53c230..4d09773330e7 100644 --- a/qiskit/transpiler/passes/basis/basis_translator.py +++ b/qiskit/transpiler/passes/basis/basis_translator.py @@ -616,8 +616,8 @@ def _compose_transforms(basis_transforms, source_basis, source_dag): placeholder_gate.params = list(placeholder_params) dag = DAGCircuit( - _node_count_hint=gate_num_qubits * 2, - _edge_count_hint=gate_num_qubits, + node_count_hint=gate_num_qubits * 2, + edge_count_hint=gate_num_qubits, ) qr = QuantumRegister(gate_num_qubits) dag.add_qreg(qr) diff --git a/qiskit/transpiler/passes/layout/apply_layout.py b/qiskit/transpiler/passes/layout/apply_layout.py index 70190875a827..5a4e0af70077 100644 --- a/qiskit/transpiler/passes/layout/apply_layout.py +++ b/qiskit/transpiler/passes/layout/apply_layout.py @@ -63,8 +63,8 @@ def run(self, dag): node_count = dag._multi_graph.num_nodes() + 2 * (layout_qubits - dag_qubits) edge_count = dag._multi_graph.num_edges() + layout_qubits - dag_qubits new_dag = DAGCircuit( - _node_count_hint=node_count, - _edge_count_hint=edge_count, + node_count_hint=node_count, + edge_count_hint=edge_count, ) new_dag.add_qreg(q) for var in dag.iter_input_vars(): diff --git a/qiskit/transpiler/passes/layout/disjoint_utils.py b/qiskit/transpiler/passes/layout/disjoint_utils.py index ef5457c67351..c86ebfb1611e 100644 --- a/qiskit/transpiler/passes/layout/disjoint_utils.py +++ b/qiskit/transpiler/passes/layout/disjoint_utils.py @@ -112,8 +112,8 @@ def split_barriers(dag: DAGCircuit): else: barrier_uuid = f"_none_uuid={uuid.uuid4()}" split_dag = DAGCircuit( - _node_count_hint=3 * num_qubits, - _edge_count_hint=2 * num_qubits, + node_count_hint=3 * num_qubits, + edge_count_hint=2 * num_qubits, ) split_dag.add_qubits([Qubit() for _ in range(num_qubits)]) for i in range(num_qubits): diff --git a/qiskit/transpiler/passes/layout/sabre_layout.py b/qiskit/transpiler/passes/layout/sabre_layout.py index f0b0d0554a89..4eb3f2e3c0b5 100644 --- a/qiskit/transpiler/passes/layout/sabre_layout.py +++ b/qiskit/transpiler/passes/layout/sabre_layout.py @@ -312,8 +312,8 @@ def run(self, dag): num_edges += component_dag._multi_graph.num_edges() mapped_dag = DAGCircuit( - _node_count_hint=num_nodes, - _edge_count_hint=num_edges, + node_count_hint=num_nodes, + edge_count_hint=num_edges, ) mapped_dag.add_qreg(physical_qubits) mapped_dag.add_clbits(dag.clbits) diff --git a/releasenotes/notes/add-size-hint-dagcircuit-0202303345633806.yaml b/releasenotes/notes/add-size-hint-dagcircuit-0202303345633806.yaml new file mode 100644 index 000000000000..ba76f6016143 --- /dev/null +++ b/releasenotes/notes/add-size-hint-dagcircuit-0202303345633806.yaml @@ -0,0 +1,10 @@ +--- + +features_transpiler: + - | + Added two new keyword arguments, ``node_count_hint`` and ``edge_count_hint`` to the constructor + of the :class:`.DAGCircuit` class. These new arguments are used to provide size hints when + building a new :class:`.DAGCircuit`. These hints are used to reduce the number of memory + allocations when working with a :class:`.DAGCircuit` and will be used to pre-allocate the + memory which will result in a runtime improvement. When set these arguments are used there + is no difference in behavior except the underyling memory is allocated up front.