# Is there a way to decompose a quantum circuit into layers?

For example, if take the following circuit as the input (either QASM or Qiskit):

qreg q;
creg c;

x q;
h q;
h q;
cx q,q;
h q;
measure q -> c;
measure q -> c; The expected output will be:

layer = [H [q0], X [q1]]
layer = [H [q1]]
layer = [cnot [q0] [q1]]
layer = [H [q0]]
layer = [measure [q0]]
layer = [measure [q1]]


Is there a Qiskit function to achieve this? If not, suggestions to implement this task are also welcomed.

Thanks!

• The issue is that the decomposition is not unique. Layers 0 and 1 can be either those you mentioned or layer = [X [q1]] and layer = [H [q0], H [q1]]. Also note that you should put identity operators to empty places in the circuit, i.e. your layer 1 should be layer = [I q, H [q1]] Oct 17, 2022 at 18:01
• @MartinVesely Thanks! Yes that's a great point. I guess only CNOT will clearly divide different layers between a bunch of single-qubit gates.
– Mao
Oct 18, 2022 at 5:04
• Yes, or any controlled or multi-controlled gate. Oct 18, 2022 at 6:26
• Just one note. Imagine that you have several controlled gates in row and one single-qubit gate on a qubit below the controlled gates, then it is also ambiguous under which controlled gate to place the single-qubit one. Oct 18, 2022 at 8:54
• That is also true, seems like I need to define some scheduling policy first...
– Mao
Oct 19, 2022 at 1:28

You can decompose a quantum circuit into layers using DAGCircuit.layers() method:

from qiskit.converters import circuit_to_dag, dag_to_circuit
from IPython.display import display

dag = circuit_to_dag(circ)
for layer in dag.layers():
layer_as_circuit = dag_to_circuit(layer['graph'])
display(layer_as_circuit.draw('mpl'))


where circ is a QuantumCircuit. The output will be: DAGCircuit.layers() method constructs the layers using a greedy algorithm.

You can also break down your circuit into layers based on some scheduling policy. In the following example we apply an "as late as possible" (ALAP) scheduling policy:

from qiskit.transpiler import PassManager, InstructionDurations

# Apply the scheduling policy:
instruction_durations = InstructionDurations(
[
("h", None, 160),
("x", None, 160),
("cx", None, 800),
("measure", None, 1600),
]
)

pass_manager = PassManager(
[
ALAPScheduleAnalysis(instruction_durations),
]
)
transpiled_circ = pass_manager.run(circ)

# Use DAGCircuit.layers() method with the transpiled circuit:
dag = circuit_to_dag(transpiled_circ)
for layer in dag.layers():
layer_as_circuit = dag_to_circuit(layer['graph'])
# Remove the Delay instructions:
for _inst in layer_as_circuit.data:
if _inst.operation.name == 'delay':
layer_as_circuit.data.remove(_inst)

display(layer_as_circuit.draw('mpl'))


The result: Similarly, you can apply "as soon as possible" (ASAP) scheduling policy.