Skip to content

Commit

Permalink
Add option to skip deepcopy on dag_to_circuit (Qiskit#9825)
Browse files Browse the repository at this point in the history
* Add option to skip deepcopy on dag_to_circuit

This commit adds a new option, copy_operations, which allows to disable
the deepcopy on dag_to_circuit(). Previously the dag to circuit
converter would always deep copy the operations, however in the
transpiler we don't need this extra overhead because the DAGCircuits are
temporary internal artifacts and will not be resused outside of the
transpiler. So we can avoid the copy overhead in these situations,
however in general the converter needs to default to copying. This
new argument enables this workflow by keeping the current behavior by
default but enabling the transpiler to skip copying operations in the
output conversion.

* Fix docs typo

* Fix docs typo again

* Use copy_operations=False in more locations
  • Loading branch information
mtreinish authored Mar 24, 2023
1 parent dfcfa4a commit 0bd4cfd
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 9 deletions.
2 changes: 1 addition & 1 deletion qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4808,7 +4808,7 @@ def _circuit_from_qasm(qasm: Qasm) -> "QuantumCircuit":

ast = qasm.parse()
dag = ast_to_dag(ast)
return dag_to_circuit(dag)
return dag_to_circuit(dag, copy_operations=False)


def _standard_compare(value1, value2):
Expand Down
2 changes: 1 addition & 1 deletion qiskit/compiler/transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ def _remap_circuit_faulty_backend(circuit, num_qubits, backend_prop, faulty_qubi
dag_circuit = circuit_to_dag(circuit)
apply_layout_pass = ApplyLayout()
apply_layout_pass.property_set["layout"] = Layout(physical_layout_dict)
circuit = dag_to_circuit(apply_layout_pass.run(dag_circuit))
circuit = dag_to_circuit(apply_layout_pass.run(dag_circuit), copy_operations=False)
circuit._layout = new_layout
return circuit

Expand Down
14 changes: 12 additions & 2 deletions qiskit/converters/dag_to_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@
from qiskit.circuit import QuantumCircuit, CircuitInstruction


def dag_to_circuit(dag):
def dag_to_circuit(dag, copy_operations=True):
"""Build a ``QuantumCircuit`` object from a ``DAGCircuit``.
Args:
dag (DAGCircuit): the input dag.
copy_operations (bool): Deep copy the operation objects
in the :class:`~.DAGCircuit` for the output :class:`~.QuantumCircuit`.
This should only be set to ``False`` if the input :class:`~.DAGCircuit`
will not be used anymore as the operations in the output
:class:`~.QuantumCircuit` will be shared instances and
modifications to operations in the :class:`~.DAGCircuit` will
be reflected in the :class:`~.QuantumCircuit` (and vice versa).
Return:
QuantumCircuit: the circuit representing the input dag.
Expand Down Expand Up @@ -60,7 +67,10 @@ def dag_to_circuit(dag):
circuit.calibrations = dag.calibrations

for node in dag.topological_op_nodes():
circuit._append(CircuitInstruction(copy.deepcopy(node.op), node.qargs, node.cargs))
op = node.op
if copy_operations:
op = copy.deepcopy(op)
circuit._append(CircuitInstruction(op, node.qargs, node.cargs))

circuit.duration = dag.duration
circuit.unit = dag.unit
Expand Down
2 changes: 1 addition & 1 deletion qiskit/transpiler/basepasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def __call__(self, circuit, property_set=None):
property_set.update(self.property_set)

if isinstance(result, DAGCircuit):
result_circuit = dag_to_circuit(result)
result_circuit = dag_to_circuit(result, copy_operations=False)
elif result is None:
result_circuit = circuit.copy()

Expand Down
4 changes: 2 additions & 2 deletions qiskit/transpiler/passes/basis/basis_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ def _compose_transforms(basis_transforms, source_basis, source_dag):
"Updating transform for mapped instr %s %s from \n%s",
mapped_instr_name,
dag_params,
dag_to_circuit(dag),
dag_to_circuit(dag, copy_operations=False),
)

for node in doomed_nodes:
Expand All @@ -588,7 +588,7 @@ def _compose_transforms(basis_transforms, source_basis, source_dag):
"Updated transform for mapped instr %s %s to\n%s",
mapped_instr_name,
dag_params,
dag_to_circuit(dag),
dag_to_circuit(dag, copy_operations=False),
)

return mapped_instrs
Expand Down
5 changes: 4 additions & 1 deletion qiskit/transpiler/passes/utils/control_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ def map_blocks(dag_mapping: Callable[[DAGCircuit], DAGCircuit], op: ControlFlowO
ones. Each block will be automatically converted to a :class:`.DAGCircuit` and then returned
to a :class:`.QuantumCircuit`."""
return op.replace_blocks(
[dag_to_circuit(dag_mapping(circuit_to_dag(block))) for block in op.blocks]
[
dag_to_circuit(dag_mapping(circuit_to_dag(block)), copy_operations=False)
for block in op.blocks
]
)


Expand Down
2 changes: 1 addition & 1 deletion qiskit/transpiler/runningpassmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def run(self, circuit, output_name=None, callback=None):
for pass_ in passset:
dag = self._do_pass(pass_, dag, passset.options)

circuit = dag_to_circuit(dag)
circuit = dag_to_circuit(dag, copy_operations=False)
if output_name:
circuit.name = output_name
else:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
features:
- |
Added a new option, ``copy_operations``, to :func:`~.dag_to_circuit` to
enable optionally disabling deep copying the operations from the input
:class`~.DAGCircuit` to the output :class:`~.QuantumCircuit`. In cases
where the input :class`~.DAGCircuit` is not used anymore after conversion
this deep copying is unnecessary overhead as any shared references wouldn't
have any potential unwanted side effects if the input :class`~.DAGCircuit`
is discarded.

0 comments on commit 0bd4cfd

Please sign in to comment.