Skip to content

Commit 1b3e8b6

Browse files
Propagate DAGCircuit.name in ApplyLayout (#13910) (#13920)
* Propagate `DAGCircuit.name` in `ApplyLayout` This has always been absent, but `transpile` masked the problem by assigning the output circuit names by overwriting the `output_names` input kwarg if it wasn't set. `generate_preset_pass_manager` didn't have the same logic, so it was observable that `ApplyLayout` didn't propagate the name. We could have added similar name-propagation logic to `generate_preset_pass_manager`, but really the bug is in `ApplyLayout`; passes _should_ propagate the metadata. * Fix typo Co-authored-by: John Lapeyre <[email protected]> * Remove redunant set --------- Co-authored-by: John Lapeyre <[email protected]> (cherry picked from commit 29aa2bd) Co-authored-by: Jake Lishman <[email protected]>
1 parent 8c7473d commit 1b3e8b6

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

qiskit/transpiler/passes/layout/apply_layout.py

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def run(self, dag):
5959
q = QuantumRegister(len(layout), "q")
6060

6161
new_dag = DAGCircuit()
62+
new_dag.name = dag.name
6263
new_dag.add_qreg(q)
6364
for var in dag.iter_input_vars():
6465
new_dag.add_input_var(var)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
Circuits compiled using a preset passmanager constructed by :func:`.generate_preset_pass_manager`
5+
will now correctly retain their :attr:`~.QuantumCircuit.name` attribute, as they do with
6+
:func:`.transpile`.

test/python/compiler/test_transpiler.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
CZGate,
5959
ECRGate,
6060
HGate,
61+
IGate,
62+
PhaseGate,
6163
RXGate,
6264
RYGate,
6365
RZGate,
@@ -1825,7 +1827,9 @@ def test_no_infinite_loop(self, optimization_level):
18251827
@data(0, 1, 2, 3)
18261828
def test_transpile_preserves_circuit_metadata(self, optimization_level):
18271829
"""Verify that transpile preserves circuit metadata in the output."""
1828-
circuit = QuantumCircuit(2, metadata={"experiment_id": "1234", "execution_number": 4})
1830+
metadata = {"experiment_id": "1234", "execution_number": 4}
1831+
name = "my circuit"
1832+
circuit = QuantumCircuit(2, metadata=metadata.copy(), name=name)
18291833
circuit.h(0)
18301834
circuit.cx(0, 1)
18311835

@@ -1857,7 +1861,22 @@ def test_transpile_preserves_circuit_metadata(self, optimization_level):
18571861
optimization_level=optimization_level,
18581862
seed_transpiler=42,
18591863
)
1860-
self.assertEqual(circuit.metadata, res.metadata)
1864+
self.assertEqual(res.metadata, metadata)
1865+
self.assertEqual(res.name, name)
1866+
1867+
target = Target(14)
1868+
for inst in (IGate(), PhaseGate(Parameter("t")), SXGate()):
1869+
target.add_instruction(inst, {(i,): None for i in range(14)})
1870+
target.add_instruction(CXGate(), {tuple(pair): None for pair in cmap})
1871+
1872+
res = transpile(
1873+
circuit,
1874+
target=target,
1875+
optimization_level=optimization_level,
1876+
seed_transpiler=42,
1877+
)
1878+
self.assertEqual(res.metadata, metadata)
1879+
self.assertEqual(res.name, name)
18611880

18621881
@data(0, 1, 2, 3)
18631882
def test_transpile_optional_registers(self, optimization_level):

test/python/transpiler/test_preset_passmanagers.py

+23-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import numpy as np
2222

2323
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
24-
from qiskit.circuit import Qubit, Gate, ControlFlowOp, ForLoopOp
24+
from qiskit.circuit import Qubit, Gate, ControlFlowOp, ForLoopOp, library as lib, Parameter
2525
from qiskit.circuit.library import quantum_volume
2626
from qiskit.compiler import transpile
2727
from qiskit.transpiler import CouplingMap, Layout, PassManager, TranspilerError, Target
@@ -1576,6 +1576,28 @@ def test_parse_seed_transpiler_raises_value_error(self):
15761576
):
15771577
generate_preset_pass_manager(seed_transpiler=0.1)
15781578

1579+
@data(0, 1, 2, 3)
1580+
def test_preserves_circuit_metadata(self, optimization_level):
1581+
"""Test that basic metadata is preserved."""
1582+
metadata = {"experiment_id": "1234", "execution_number": 4}
1583+
name = "my circuit"
1584+
circuit = QuantumCircuit(4, metadata=metadata.copy(), name=name)
1585+
circuit.h(0)
1586+
circuit.cx(0, 3)
1587+
1588+
num_qubits = 10
1589+
target = Target(num_qubits)
1590+
for inst in (lib.IGate(), lib.PhaseGate(Parameter("t")), lib.SXGate()):
1591+
target.add_instruction(inst, {(i,): None for i in range(num_qubits)})
1592+
target.add_instruction(CXGate(), {pair: None for pair in CouplingMap.from_line(num_qubits)})
1593+
1594+
pm = generate_preset_pass_manager(
1595+
optimization_level=optimization_level, target=target, seed_transpiler=42
1596+
)
1597+
res = pm.run(circuit)
1598+
self.assertEqual(res.metadata, metadata)
1599+
self.assertEqual(res.name, name)
1600+
15791601

15801602
@ddt
15811603
class TestIntegrationControlFlow(QiskitTestCase):

0 commit comments

Comments
 (0)