Qdislib — 01 · Quickstart

Qdislib runs quantum circuits that are too large for one device by cutting them into smaller subcircuits, executing those independently (optionally distributed with PyCOMPSs, or on real QPUs), and reconstructing the original expectation value from the pieces.

This is a learning path — read the notebooks in order:

  1. Quickstart (this notebook) — your first cut.

  2. The cutting workflow — generate → evaluate → reconstruct.

  3. Backends — Qibo / Qiskit / CUDA-Q, and QASM interop.

  4. Observables — Pauli strings and weighted Hamiltonians.

  5. Caching & performance — the semantic cache and logging.

  6. Distributed & QPU — PyCOMPSs and real quantum hardware.

Install: pip install Qdislib[qibo] (a Qibo-only install is enough to follow along; add qiskit, cudaq, cache as needed).

1. Build a circuit

We use Qibo here, but Qdislib is backend-agnostic (notebook 3).

[ ]:
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

2. The one-liner: estimate

qd.estimate does the whole pipeline — find a cut, run the subcircuits, reconstruct — in a single call. Here we estimate <ZZZZZ>, asking for subcircuits of at most 3 qubits.

[ ]:
value = qd.estimate(example_circuit(), "ZZZZZ", max_qubits=3, shots=8192)
print("estimate  :", value)

For a small circuit we can check against the exact (statevector) value — the two agree up to shot noise.

[ ]:
exact = qd.analytical_solution(example_circuit(), "ZZZZZ")
print("analytical:", exact)

3. Under the hood: find a cut, then cut

estimate is a convenience wrapper. The two explicit steps are find_cut (pick where to cut) and gate_cutting / wire_cutting (cut, run and reconstruct). Gate cutting splits a two-qubit gate:

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

value = qd.gate_cutting(example_circuit(), gate_cut, shots=8192)
print("reconstructed <ZZZZZ>:", value)

4. Wire cutting

Wire cutting severs a qubit wire between two gates instead of a gate. Same call shape:

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

value = qd.wire_cutting(example_circuit(), wire_cut, shots=8192)
print("reconstructed <ZZZZZ>:", value)

Next: 02 · The cutting workflow — the recommended three-step API that lets you inspect and distribute the subcircuits.