1
$\begingroup$

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

qreg q[2];
creg c[2];

x q[1];
h q[0];
h q[1];
cx q[0],q[1];
h q[0];
measure q[0] -> c[0];
measure q[1] -> c[1];

enter image description here

The expected output will be:

layer[0] = [H [q0], X [q1]]
layer[1] = [H [q1]]
layer[2] = [cnot [q0] [q1]]
layer[3] = [H [q0]]
layer[4] = [measure [q0]]
layer[5] = [measure [q1]]

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

Thanks!

$\endgroup$
5
  • 1
    $\begingroup$ The issue is that the decomposition is not unique. Layers 0 and 1 can be either those you mentioned or layer[0] = [X [q1]] and layer[1] = [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[1] = [I q[0], H [q1]] $\endgroup$ Oct 17, 2022 at 18:01
  • $\begingroup$ @MartinVesely Thanks! Yes that's a great point. I guess only CNOT will clearly divide different layers between a bunch of single-qubit gates. $\endgroup$
    – Mao
    Oct 18, 2022 at 5:04
  • 1
    $\begingroup$ Yes, or any controlled or multi-controlled gate. $\endgroup$ Oct 18, 2022 at 6:26
  • $\begingroup$ 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. $\endgroup$ Oct 18, 2022 at 8:54
  • 1
    $\begingroup$ That is also true, seems like I need to define some scheduling policy first... $\endgroup$
    – Mao
    Oct 19, 2022 at 1:28

1 Answer 1

2
$\begingroup$

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:

enter image description here

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
from qiskit.transpiler.passes import  ALAPScheduleAnalysis, PadDelay

# 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),
      PadDelay(),
    ]
)
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:

enter image description here

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.