Circuit cutting, in depth
Cutting splits a circuit that is too wide (or too deep) for a device into smaller subcircuits and reconstructs expectation values classically, at the price of more shots. This chapter covers gate cuts, wire cuts, qubit reuse, the quasi-probability math and what the numbers in the Estimate card mean.
Why cut at all
Three reasons. (1) Width: a 6-qubit circuit cannot run on a 3-qubit device, or on a 127-qubit device whose good qubits form small islands. (2) Depth and SWAPs: splitting a circuit into pieces removes the long-range entangling gates that routing would turn into SWAP chains, so each piece is shallower and less noisy. (3) Parallelism: pieces run on several devices or several calibrated regions at once. The cost is sampling overhead: the total number of shots grows exponentially with the number of cuts.
Gate cut: replace a two-qubit gate by local operations
Wire cut: cut a qubit's time line
Qubit reuse: run a wide circuit on a narrow device
After a wire cut, the first half's qubit is measured and no longer needed. Reset it (|0⟩) and reuse the same physical qubit for the second half's prepared state. With enough wire cuts, a circuit of n logical qubits can run on far fewer physical qubits, trading width for depth and shots. Mid-circuit measurement and reset (the `reset` gate in the palette) are the hardware features that make this possible; IBM devices support both. qiskit-addon-cutting handles the bookkeeping: `cut_wires` inserts the move operations and `partition_problem` groups qubits that stay together.
The full workflow (what Submit cutting runs)
find_cuts(circuit, OptimizationParameters(seed), DeviceConstraints(qubits_per_subcircuit=w))
-> cut circuit + {cuts: [('Gate Cut', idx), ...], sampling_overhead}
cut_wires(cut_circuit) # turn wire cuts into move ops
expand_observables(paulis, circuit, cut) # observables follow the moved qubits
partition_problem(circuit, observables) # subcircuits + subobservables
generate_cutting_experiments(..., num_samples=inf) # all QPD terms, with coefficients
run each subexperiment with SamplerV2 # ideal Aer or a noisy fake backend
reconstruct_expectation_values(results, coefficients, subobservables)| Estimate card field | Meaning | Good value |
|---|---|---|
| Cuts | number of gate + wire cuts found | 1–2 |
| Sampling overhead | Π γᵢ² (9 per CNOT, 16 per wire) | < 100× is practical |
| Depth before → subcircuits | each piece should be shallower than the original | pieces ≤ original |
| Shots suggested | 4096 × overhead | fits your budget |
| minimum reached | optimizer proved no cheaper cut exists for this width | yes |
Beyond the baseline
Research directions you can plug in through the CuttingStrategy interface (README): choosing cut locations with a cost model that includes device noise, not just γ; LO vs LOCC decompositions (classical communication between halves lowers γ for some gates); cutting for privacy or obfuscation, where the pieces reveal less about the whole circuit than the full one would (the idea behind Q-MaskCut); and combining cutting with error mitigation per subcircuit.