Qdislib — 02 · The cutting workflow¶
gate_cutting / wire_cutting do everything in one call. The recommended workflow breaks that into three steps you control:
generate the subcircuits,
evaluate each one (locally, distributed, or on a QPU),
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.