Qdislib — 02 · The cutting workflow

gate_cutting / wire_cutting do everything in one call. The recommended workflow breaks that into three steps you control:

  1. generate the subcircuits,

  2. evaluate each one (locally, distributed, or on a QPU),

  3. reconstruct the original expectation value.

This is what you want for distributed runs and for inspecting the pieces.

[ ]:
from qibo import models, gates


def example_circuit():
    """A small 5-qubit circuit: cuttable (CZ chain), non-trivial <ZZZZZ> ~= 0.44."""
    circuit = models.Circuit(5)
    circuit.add(gates.RY(0, 0.8))
    circuit.add(gates.CZ(0, 1))
    circuit.add(gates.RY(1, 0.5))
    circuit.add(gates.CZ(1, 2))
    circuit.add(gates.RY(2, 0.6))
    circuit.add(gates.CZ(2, 3))
    circuit.add(gates.RY(3, 0.4))
    circuit.add(gates.CZ(3, 4))
    circuit.add(gates.RX(4, 0.3))
    return circuit


circuit = example_circuit()
print(circuit.draw())
[ ]:
import Qdislib as qd

1. Generate the subcircuits

find_cut picks the cut; gate_cutting_subcircuits produces the pieces.

[ ]:
circuit = example_circuit()
cut = qd.find_cut(circuit, gate_cut=True, wire_cut=False)
print("cut:", cut)

subcircuits = qd.gate_cutting_subcircuits(example_circuit(), cut, software="qibo")
print("number of subcircuits:", len(subcircuits))

2. Evaluate each subcircuit

expectation_value runs one subcircuit and returns its expectation. This is the loop you’d replace to dispatch to a cluster or a QPU.

[ ]:
values = [qd.expectation_value(s, shots=8192) for s in subcircuits]

3. Reconstruct

The object returned by *_subcircuits remembers the cut bookkeeping, so reconstruct needs nothing else.

[ ]:
result = subcircuits.reconstruct(values)
print("reconstructed:", result)
print("analytical   :", qd.analytical_solution(example_circuit(), "ZZZZZ"))

Visualise the cut

draw_cut shows the circuit DAG with the cut highlighted.

[ ]:
qd.draw_cut(example_circuit(), cut)  # needs matplotlib; opens a figure

Wire cutting — same three steps

Only the generator function changes.

[ ]:
circuit = example_circuit()
wire_cut = qd.find_cut(circuit, gate_cut=False, wire_cut=True)
subcircuits = qd.wire_cutting_subcircuits(example_circuit(), wire_cut, software="qibo")
values = [qd.expectation_value(s, shots=8192) for s in subcircuits]
print("wire reconstruction:", subcircuits.reconstruct(values))

Gate vs wire. Gate cutting splits a two-qubit gate (cost grows fast with the number of cuts); wire cutting severs a qubit wire. find_cut can weigh both — see notebook 3 onwards and the docs for guidance.


Next: 03 · Finding cuts — let Qdislib choose where to cut.