Skip to content

Commit df2a6eb

Browse files
1ucian0Cryorisjakelishman
authored
DAGCircuit._copy_circuit_metadata is widely used and it should be public (Qiskit#7803)
* dag._copy_circuit_metadata is not internal anymore * reno * docstring * copy_empty_like * reno * Update qiskit/dagcircuit/dagcircuit.py Co-authored-by: Julien Gacon <[email protected]> * Update test/python/dagcircuit/test_dagcircuit.py Co-authored-by: Julien Gacon <[email protected]> * keeping _copy_circuit_metadata Co-authored-by: [email protected] * docstring * tests and linting * ups Co-authored-by: Julien Gacon <[email protected]> Co-authored-by: Jake Lishman <[email protected]>
1 parent 5c61d8f commit df2a6eb

File tree

8 files changed

+50
-8
lines changed

8 files changed

+50
-8
lines changed

qiskit/dagcircuit/dagcircuit.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from qiskit.dagcircuit.exceptions import DAGCircuitError
3737
from qiskit.dagcircuit.dagnode import DAGNode, DAGOpNode, DAGInNode, DAGOutNode
3838
from qiskit.utils import optionals as _optionals
39+
from qiskit.utils.deprecation import deprecate_function
3940

4041

4142
class DAGCircuit:
@@ -491,8 +492,28 @@ def _add_op_node(self, op, qargs, cargs):
491492
self._increment_op(op)
492493
return node_index
493494

495+
@deprecate_function(
496+
"""The DAGCircuit._copy_circuit_metadata method is deprecated as of 0.20.0. It will be removed
497+
no earlier than 3 months after the release date. You should use the DAGCircuit.copy_empty_like
498+
method instead, which acts identically.
499+
"""
500+
)
494501
def _copy_circuit_metadata(self):
495-
"""Return a copy of source_dag with metadata but empty."""
502+
"""DEPRECATED"""
503+
return self.copy_empty_like()
504+
505+
def copy_empty_like(self):
506+
"""Return a copy of self with the same structure but empty.
507+
508+
That structure includes:
509+
* name and other metadata
510+
* global phase
511+
* duration
512+
* all the qubits and clbits, including the registers.
513+
514+
Returns:
515+
DAGCircuit: An empty copy of self.
516+
"""
496517
target_dag = DAGCircuit()
497518
target_dag.name = self.name
498519
target_dag._global_phase = self._global_phase
@@ -1550,7 +1571,7 @@ def layers(self):
15501571
return
15511572

15521573
# Construct a shallow copy of self
1553-
new_layer = self._copy_circuit_metadata()
1574+
new_layer = self.copy_empty_like()
15541575

15551576
for node in op_nodes:
15561577
# this creates new DAGOpNodes in the new_layer
@@ -1570,7 +1591,7 @@ def serial_layers(self):
15701591
same structure as in layers().
15711592
"""
15721593
for next_node in self.topological_op_nodes():
1573-
new_layer = self._copy_circuit_metadata()
1594+
new_layer = self.copy_empty_like()
15741595

15751596
# Save the support of the operation we add to the layer
15761597
support_list = []

qiskit/transpiler/passes/routing/basic_swap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def run(self, dag):
5555
if self.fake_run:
5656
return self.fake_run(dag)
5757

58-
new_dag = dag._copy_circuit_metadata()
58+
new_dag = dag.copy_empty_like()
5959

6060
if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
6161
raise TranspilerError("Basic swap runs on physical circuits only")

qiskit/transpiler/passes/routing/lookahead_swap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def run(self, dag):
141141
return dag
142142

143143
# Preserve input DAG's name, regs, wire_map, etc. but replace the graph.
144-
mapped_dag = dag._copy_circuit_metadata()
144+
mapped_dag = dag.copy_empty_like()
145145

146146
for node in mapped_gates:
147147
mapped_dag.apply_operation_back(op=node.op, qargs=node.qargs, cargs=node.cargs)

qiskit/transpiler/passes/routing/sabre_swap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def run(self, dag):
161161
# Preserve input DAG's name, regs, wire_map, etc. but replace the graph.
162162
mapped_dag = None
163163
if not self.fake_run:
164-
mapped_dag = dag._copy_circuit_metadata()
164+
mapped_dag = dag.copy_empty_like()
165165

166166
canonical_register = dag.qregs["q"]
167167
current_layout = Layout.generate_trivial_layout(canonical_register)

qiskit/transpiler/passes/routing/stochastic_swap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ def _mapper(self, circuit_graph, coupling_graph, trials=20):
275275
# qregs and cregs as the input circuit
276276
dagcircuit_output = None
277277
if not self.fake_run:
278-
dagcircuit_output = circuit_graph._copy_circuit_metadata()
278+
dagcircuit_output = circuit_graph.copy_empty_like()
279279

280280
logger.debug("trivial_layout = %s", layout)
281281

qiskit/transpiler/passes/utils/merge_adjacent_barriers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def run(self, dag):
6969
return dag
7070

7171
# add the merged barriers to a new DAG
72-
new_dag = dag._copy_circuit_metadata()
72+
new_dag = dag.copy_empty_like()
7373

7474
# go over current nodes, and add them to the new dag
7575
for node in dag.topological_op_nodes():
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
5+
The a new method :meth:`qiskit.dagcircuit.DAGCircuit.copy_empty_like` allows to create a new
6+
:class:`qiskit.dagcircuit.DAGCircuit` with the same structure but empty.
7+
This method is the same as the previously internal method `_copy_circuit_metadata`.

test/python/dagcircuit/test_dagcircuit.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ class TestDagWireRemoval(QiskitTestCase):
254254
def setUp(self):
255255
super().setUp()
256256
self.dag = DAGCircuit()
257+
self.dag.name = "Name"
258+
self.dag.metadata = "Metadata"
257259
qreg = QuantumRegister(3, "qr")
258260
creg0 = ClassicalRegister(2, "c0")
259261
creg1 = ClassicalRegister(2, "c1")
@@ -346,6 +348,18 @@ def test_remove_idle_clbit(self):
346348
self.assert_cregs_equal(self.original_cregs)
347349
self.assert_clbits_equal(self.original_clbits, excluding={self.individual_clbit})
348350

351+
def test_copy_circuit_metadata(self):
352+
"""Copy dag circuit metadata with copy_empty_like."""
353+
result_dag = self.dag.copy_empty_like()
354+
self.assertEqual(self.dag.name, result_dag.name)
355+
self.assertEqual(self.dag.metadata, result_dag.metadata)
356+
self.assertEqual(self.dag.clbits, result_dag.clbits)
357+
self.assertEqual(self.dag.qubits, result_dag.qubits)
358+
self.assertEqual(self.dag.cregs, result_dag.cregs)
359+
self.assertEqual(self.dag.qregs, result_dag.qregs)
360+
self.assertEqual(self.dag.duration, result_dag.duration)
361+
self.assertEqual(self.dag.unit, result_dag.unit)
362+
349363
def test_remove_busy_clbit(self):
350364
"""Classical bit removal of busy classical bits raises."""
351365
self.dag.apply_operation_back(Measure(), [self.qreg[0]], [self.individual_clbit])

0 commit comments

Comments
 (0)