Skip to content

qnetbench.apps

The benchmark applications, the core/catalog split, and the registry that resolves a benchmark by name.

Narrative guide: Applications.

qnetbench.apps

qnetbench.apps — benchmark applications.

The suite has two layers (the MQT Bench / SPEC model):

  • a core of distinct protocols (available_apps()), spanning every demand class, that CI, the reference corpus, and the cross-backend equivalence suite all iterate;
  • a catalog (catalog_apps()) of 50+ parameterized instances — mostly DQC over a family of distributed circuits at a range of sizes — resolvable and runnable on demand (get_app, qnetbench run <name>), but not all baked into CI.

Every application is one file against the api and inherits characterization, a demand signature, and cross-backend equivalence for free.

AnonymousTransmission

AnonymousTransmission(
    rounds: int = 64, min_fidelity: float = 0.8
)
Source code in qnetbench/apps/anonymous.py
def __init__(self, rounds: int = 64, min_fidelity: float = 0.8) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'anonymous_transmission'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/anonymous.py
def roles(self) -> list[Role]:
    return ["charlie", "alice", "bob"]  # charlie = hub (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/anonymous.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    demand = Demand(min_fidelity=self.min_fidelity, purpose="keep")
    if role == "charlie":
        return self._hub(host, rounds, demand)
    return self._leaf(host, role, rounds, demand)

B92

B92(rounds: int = 256, qber_threshold: float = 0.11)
Source code in qnetbench/apps/b92.py
def __init__(self, rounds: int = 256, qber_threshold: float = 0.11) -> None:
    self.rounds = rounds
    self.qber_threshold = qber_threshold

name class-attribute instance-attribute

name = 'b92'

rounds instance-attribute

rounds = rounds

qber_threshold instance-attribute

qber_threshold = qber_threshold

roles

roles() -> list[Role]
Source code in qnetbench/apps/b92.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = sender, bob = receiver

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/b92.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "alice":
        return self._sender(host, rounds)
    return self._receiver(host, rounds)

BB84

BB84(rounds: int = 256, qber_threshold: float = 0.11)
Source code in qnetbench/apps/bb84.py
def __init__(self, rounds: int = 256, qber_threshold: float = 0.11) -> None:
    self.rounds = rounds
    self.qber_threshold = qber_threshold

name class-attribute instance-attribute

name = 'bb84'

rounds instance-attribute

rounds = rounds

qber_threshold instance-attribute

qber_threshold = qber_threshold

roles

roles() -> list[Role]
Source code in qnetbench/apps/bb84.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = sender, bob = receiver

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/bb84.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "alice":
        return self._sender(host, rounds)
    return self._receiver(host, rounds)

BQC

BQC(
    depth: int = 8,
    min_fidelity: float = 0.95,
    phi: float = 0.0,
)
Source code in qnetbench/apps/bqc.py
def __init__(self, depth: int = 8, min_fidelity: float = 0.95, phi: float = 0.0) -> None:
    self.depth = depth
    self.min_fidelity = min_fidelity
    self.phi = phi

name class-attribute instance-attribute

name = 'bqc'

depth instance-attribute

depth = depth

min_fidelity instance-attribute

min_fidelity = min_fidelity

phi instance-attribute

phi = phi

roles

roles() -> list[Role]
Source code in qnetbench/apps/bqc.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = client, bob = server

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/bqc.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    depth = cfg_int(cfg, "depth", self.depth)
    demand = Demand(min_fidelity=self.min_fidelity, latency_budget=0.05, purpose="keep")
    if role == "alice":
        return self._client(host, depth, demand)
    return self._server(host, depth, demand)

ByzantineAgreement

ByzantineAgreement(
    rounds: int = 64,
    min_fidelity: float = 0.8,
    honest_prob: float = 0.7,
)
Source code in qnetbench/apps/byzantine.py
def __init__(
    self, rounds: int = 64, min_fidelity: float = 0.8, honest_prob: float = 0.7
) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity
    self.honest_prob = honest_prob

name class-attribute instance-attribute

name = 'byzantine_agreement'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

honest_prob instance-attribute

honest_prob = honest_prob

roles

roles() -> list[Role]
Source code in qnetbench/apps/byzantine.py
def roles(self) -> list[Role]:
    return ["general", "lieutenant1", "lieutenant2"]  # general = hub (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/byzantine.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "general":
        return self._general(host, rounds)
    return self._lieutenant(host, role, rounds)

CHSH

CHSH(rounds: int = 256, min_fidelity: float = 0.8)
Source code in qnetbench/apps/chsh.py
def __init__(self, rounds: int = 256, min_fidelity: float = 0.8) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'chsh'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/chsh.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/chsh.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    peer = _PEER[role]
    rounds = cfg_int(cfg, "rounds", self.rounds)
    epr = host.epr_socket(peer)
    cls = host.classical_socket(peer)
    demand = Demand(min_fidelity=self.min_fidelity, purpose="keep")
    angles = _ANGLES[role]

    settings: list[int] = []
    values: list[int] = []
    for _ in range(rounds):
        handle = epr.request(1, demand)[0]
        assert handle.qubit is not None
        setting = int(host.rng.integers(0, 2))
        value = _measure_at(handle.qubit, angles[setting])
        settings.append(setting)
        values.append(1 if value == 1 else 0)  # encode ±1 as bit for transport

    cls.send(bytes(settings) + bytes(values))
    their = cls.recv()
    their_settings = list(their[:rounds])
    their_values = list(their[rounds:])

    s_value = _chsh_value(role, settings, values, their_settings, their_values)
    utility = max(0.0, min(1.0, (s_value - 2.0) / (_TSIRELSON - 2.0)))
    return AppOutcome(
        role=role,
        success=s_value > 2.0,
        utility=utility,
        payload={"S": s_value},
    )

ClockSync

ClockSync(
    rounds: int = 256,
    offset: float = pi / 3,
    min_fidelity: float = 0.8,
    tolerance: float = 0.1,
)
Source code in qnetbench/apps/clock_sync.py
def __init__(
    self,
    rounds: int = 256,
    offset: float = math.pi / 3,
    min_fidelity: float = 0.8,
    tolerance: float = 0.1,
) -> None:
    self.rounds = rounds
    self.offset = offset  # true clock phase offset φ (radians, in [0, π])
    self.min_fidelity = min_fidelity
    self.tolerance = tolerance

name class-attribute instance-attribute

name = 'clock_sync'

rounds instance-attribute

rounds = rounds

offset instance-attribute

offset = offset

min_fidelity instance-attribute

min_fidelity = min_fidelity

tolerance instance-attribute

tolerance = tolerance

roles

roles() -> list[Role]
Source code in qnetbench/apps/clock_sync.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/clock_sync.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    peer = _PEER[role]
    rounds = cfg_int(cfg, "rounds", self.rounds)
    phi = cfg_float(cfg, "offset", self.offset)
    epr = host.epr_socket(peer)
    cls = host.classical_socket(peer)
    demand = Demand(min_fidelity=self.min_fidelity, purpose="keep")

    bits: list[int] = []
    for _ in range(rounds):
        handle = epr.request(1, demand)[0]
        assert handle.qubit is not None
        if role == "bob":
            handle.qubit.apply(Gate.RZ, phi)  # Bob's local clock phase
        bits.append(handle.qubit.measure(Basis.X))

    cls.send(bytes(bits))
    their = list(cls.recv())
    agree = sum(1 for i in range(rounds) if bits[i] == their[i])
    p_agree = agree / rounds if rounds else 0.0
    correlation = 2 * p_agree - 1  # ⟨X_A X_B⟩ estimate ≈ cos(φ)
    phi_hat = math.acos(max(-1.0, min(1.0, correlation)))

    error = abs(phi_hat - phi)
    utility = max(0.0, 1.0 - error / math.pi)
    return AppOutcome(
        role=role,
        success=error < self.tolerance,
        utility=utility,
        payload={"phi": phi, "phi_hat": phi_hat, "error": error},
    )

ConferenceKey

ConferenceKey(rounds: int = 64, min_fidelity: float = 0.8)
Source code in qnetbench/apps/conference_key.py
def __init__(self, rounds: int = 64, min_fidelity: float = 0.8) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'conference_key'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/conference_key.py
def roles(self) -> list[Role]:
    return ["hub", *_LEAVES]  # hub = centre (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/conference_key.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "hub":
        return self._hub(host, rounds)
    return self._leaf(host, role, rounds)

Distillation

Distillation(
    rounds: int = 48,
    control_rounds: int = 32,
    min_fidelity: float = 0.5,
    staleness_tolerance: float = 0.002,
)
Source code in qnetbench/apps/distillation.py
def __init__(
    self,
    rounds: int = 48,
    control_rounds: int = 32,
    min_fidelity: float = 0.5,
    staleness_tolerance: float = 2e-3,
) -> None:
    self.rounds = rounds
    self.control_rounds = control_rounds
    self.min_fidelity = min_fidelity
    self.staleness_tolerance = staleness_tolerance

name class-attribute instance-attribute

name = 'distillation'

rounds instance-attribute

rounds = rounds

control_rounds instance-attribute

control_rounds = control_rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

staleness_tolerance instance-attribute

staleness_tolerance = staleness_tolerance

roles

roles() -> list[Role]
Source code in qnetbench/apps/distillation.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/distillation.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    control = cfg_int(cfg, "control_rounds", self.control_rounds)
    peer = _PEER[role]
    sign = _SIGN[role]
    epr = host.epr_socket(peer)
    cls = host.classical_socket(peer)

    # --- control sample: how good are the raw pairs? ----------------------
    # Tallied per basis, because the singlet fraction needs all three; a
    # single pooled agreement rate cannot say whether a pair is entangled.
    raw: dict[Basis, tuple[int, int]] = {}
    for i in range(control):
        handle = epr.request(1, self._demand())[0]
        assert handle.qubit is not None
        basis = test_basis(i)
        ok, n = raw.get(basis, (0, 0))
        raw[basis] = (ok + int(correlation_test(handle.qubit, cls, basis)), n + 1)

    # --- distillation: two raw pairs per attempt -------------------------
    kept = 0
    distilled: dict[Basis, tuple[int, int]] = {}
    for i in range(rounds):
        handles = epr.request(2, self._demand())
        keep, sacrifice = handles[0].qubit, handles[1].qubit
        assert keep is not None and sacrifice is not None
        if distill_step(keep, sacrifice, cls, sign=sign):
            kept += 1
            basis = test_basis(i)
            ok, n = distilled.get(basis, (0, 0))
            distilled[basis] = (ok + int(correlation_test(keep, cls, basis)), n + 1)
        else:
            keep.free()  # the step detected an error; the pair is spent

    raw_quality = singlet_fraction(raw)
    distilled_quality = singlet_fraction(distilled)
    # Yield is pairs out per pair in: the recurrence ceiling is 1/2, reached
    # only when every step is heralded successful.
    pair_yield = kept / (2 * rounds) if rounds else 0.0
    # Success means the protocol did its job: it produced pairs that are
    # entangled (singlet fraction above 1/2, the separability boundary) and
    # more so than the raw pairs it consumed. The first clause matters — a
    # recurrence step applied to separable inputs still heralds "successes"
    # and still raises same-basis agreement, because post-selection sharpens
    # classical correlation just as it sharpens quantum correlation.
    return AppOutcome(
        role=role,
        success=kept > 0 and distilled_quality > 0.5 and distilled_quality >= raw_quality,
        utility=distilled_quality,
        payload={
            "kept": kept,
            "attempts": rounds,
            "yield": pair_yield,
            "raw_quality": raw_quality,
            "distilled_quality": distilled_quality,
        },
    )

DistilledGate

DistilledGate(
    reps: int = 12,
    bulk_min_fidelity: float = 0.5,
    gate_min_fidelity: float = 0.9,
    deadline_budget: float = 0.05,
)
Source code in qnetbench/apps/distilled_gate.py
def __init__(
    self,
    reps: int = 12,
    bulk_min_fidelity: float = 0.5,
    gate_min_fidelity: float = 0.9,
    deadline_budget: float = 0.05,
) -> None:
    self.reps = reps
    self.bulk_min_fidelity = bulk_min_fidelity
    self.gate_min_fidelity = gate_min_fidelity
    self.deadline_budget = deadline_budget

name class-attribute instance-attribute

name = 'distilled_gate'

reps instance-attribute

reps = reps

bulk_min_fidelity instance-attribute

bulk_min_fidelity = bulk_min_fidelity

gate_min_fidelity instance-attribute

gate_min_fidelity = gate_min_fidelity

deadline_budget instance-attribute

deadline_budget = deadline_budget

roles

roles() -> list[Role]
Source code in qnetbench/apps/distilled_gate.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = control, bob = target

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/distilled_gate.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    reps = cfg_int(cfg, "reps", self.reps)
    peer = "bob" if role == "alice" else "alice"
    epr = host.epr_socket(peer)
    cls = host.classical_socket(peer)

    inputs: list[int] = []
    outputs: list[int] = []
    distilled = 0
    for rep in range(reps):
        # --- best-effort: two bulk pairs, distilled into one ---------------
        handles = epr.request(2, self._bulk_demand())
        keep, sacrifice = handles[0].qubit, handles[1].qubit
        assert keep is not None and sacrifice is not None
        if distill_step(keep, sacrifice, cls, sign=_SIGN[role]):
            gate_pair: Qubit = keep
            distilled += 1
        else:
            keep.free()
            # Fall back to a fresh pair under the deadline-bearing contract:
            # the gate is due whether or not distillation happened to work.
            fresh = epr.request(1, self._gate_demand(host))[0].qubit
            assert fresh is not None
            gate_pair = fresh

        # --- deadline-critical: the non-local CNOT over that pair ----------
        bit = rep % 2 if role == "alice" else (rep // 2) % 2
        inputs.append(bit)
        data = host.qalloc()
        if bit:
            data.apply(Gate.X)
        if role == "alice":
            telegate_control_with(data, gate_pair, cls)
        else:
            telegate_target_with(data, gate_pair, cls)
        outputs.append(data.measure(Basis.Z))

    # Reconciliation for scoring (not part of the protocol).
    if role == "alice":
        cls.send(bytes(inputs))
        reconciled = cls.recv()
        t_inputs, t_outputs = list(reconciled[:reps]), list(reconciled[reps:])
        c_inputs = inputs
    else:
        c_inputs = list(cls.recv())
        cls.send(bytes(inputs) + bytes(outputs))
        t_inputs, t_outputs = inputs, outputs

    correct = sum(1 for i in range(reps) if t_outputs[i] == (t_inputs[i] ^ c_inputs[i]))
    return AppOutcome(
        role=role,
        success=correct == reps,
        utility=correct / reps if reps else 0.0,
        payload={
            "reps": reps,
            "correct": correct,
            "distilled": distilled,
            "fallback_pairs": reps - distilled,
        },
    )

DistributedGate

DistributedGate(
    reps: int = 8,
    min_fidelity: float = 0.9,
    deadline_budget: float = 0.05,
)
Source code in qnetbench/apps/distributed_gate.py
def __init__(
    self,
    reps: int = 8,
    min_fidelity: float = 0.9,
    deadline_budget: float = 0.05,
) -> None:
    self.reps = reps
    self.min_fidelity = min_fidelity
    self.deadline_budget = deadline_budget

name class-attribute instance-attribute

name = 'distributed_gate'

reps instance-attribute

reps = reps

min_fidelity instance-attribute

min_fidelity = min_fidelity

deadline_budget instance-attribute

deadline_budget = deadline_budget

roles

roles() -> list[Role]
Source code in qnetbench/apps/distributed_gate.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = control, bob = target

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/distributed_gate.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    reps = cfg_int(cfg, "reps", self.reps)
    if role == "alice":
        return self._control(host, reps)
    return self._target(host, reps)

DQC

DQC(
    circuit: Circuit,
    min_fidelity: float = 0.9,
    layer_budget: float = 0.01,
)

A DQC benchmark for one (2-node) partitioned circuit.

Source code in qnetbench/apps/dqc.py
def __init__(
    self, circuit: Circuit, min_fidelity: float = 0.9, layer_budget: float = 1e-2
) -> None:
    if set(circuit.partition) - {0, 1}:
        raise ValueError("DQC currently supports 2-node (alice/bob) partitions only")
    self.circuit = circuit
    self.name = f"dqc_{circuit.name}"
    self.min_fidelity = min_fidelity
    self.layer_budget = layer_budget

circuit instance-attribute

circuit = circuit

name instance-attribute

name = f'dqc_{circuit.name}'

min_fidelity instance-attribute

min_fidelity = min_fidelity

layer_budget instance-attribute

layer_budget = layer_budget

roles

roles() -> list[Role]
Source code in qnetbench/apps/dqc.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/dqc.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    node = _NODE[role]
    circuit = self.circuit
    epr = host.epr_socket(_PEER[role])
    cls = host.classical_socket(_PEER[role])

    qubits: dict[int, Qubit] = {
        q: host.qalloc() for q in range(circuit.n_qubits) if circuit.partition[q] == node
    }
    for op, layer in zip(circuit.ops, circuit.layers(), strict=True):
        self._apply(op, layer, node, qubits, epr, cls)

    # Mirror circuit: every qubit should read 0 noiselessly.
    zeros = sum(1 for q in qubits.values() if q.measure(Basis.Z) == 0)
    total = len(qubits)

    # Reconcile the two halves for a global success measure.
    cls.send(bytes([zeros, total]))
    their_zeros, their_total = cls.recv()[:2]
    all_zeros, all_total = zeros + their_zeros, total + their_total
    return AppOutcome(
        role=role,
        success=all_zeros == all_total,
        utility=all_zeros / all_total if all_total else 0.0,
        payload={"n_nonlocal": circuit.n_nonlocal(), "depth": circuit.depth()},
    )

HeraldedTeleport

HeraldedTeleport(
    sessions: int = 24,
    herald_prob: float = 0.4,
    max_attempts: int = 12,
    mean_idle: float = 0.02,
    min_fidelity: float = 0.85,
)
Source code in qnetbench/apps/heralded_teleport.py
def __init__(
    self,
    sessions: int = 24,
    herald_prob: float = 0.4,
    max_attempts: int = 12,
    mean_idle: float = 0.02,
    min_fidelity: float = 0.85,
) -> None:
    self.sessions = sessions
    self.herald_prob = herald_prob
    self.max_attempts = max_attempts
    self.mean_idle = mean_idle
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'heralded_teleport'

sessions instance-attribute

sessions = sessions

herald_prob instance-attribute

herald_prob = herald_prob

max_attempts instance-attribute

max_attempts = max_attempts

mean_idle instance-attribute

mean_idle = mean_idle

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/heralded_teleport.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/heralded_teleport.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    sessions = cfg_int(cfg, "sessions", self.sessions)
    mean_idle = cfg_float(cfg, "mean_idle", self.mean_idle)
    if role == "alice":
        return self._sender(host, sessions, mean_idle)
    return self._receiver(host, sessions)

LeaderElection

LeaderElection(
    elections: int = 24,
    bits: int = 3,
    min_fidelity: float = 0.8,
)
Source code in qnetbench/apps/leader_election.py
def __init__(
    self, elections: int = 24, bits: int = 3, min_fidelity: float = 0.8
) -> None:
    self.elections = elections
    self.bits = bits  # GHZ rounds per election; leader = index mod 5
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'leader_election'

elections instance-attribute

elections = elections

bits instance-attribute

bits = bits

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/leader_election.py
def roles(self) -> list[Role]:
    return list(_CANDIDATES)  # node0 = coordinator/hub (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/leader_election.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    elections = cfg_int(cfg, "elections", self.elections)
    if role == "node0":
        return self._coordinator(host, elections)
    return self._candidate(host, role, elections)

MultihopQKD

MultihopQKD(
    rounds: int = 128,
    min_fidelity: float = 0.8,
    qber_threshold: float = 0.11,
)
Source code in qnetbench/apps/multihop_qkd.py
def __init__(
    self, rounds: int = 128, min_fidelity: float = 0.8, qber_threshold: float = 0.11
) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity
    self.qber_threshold = qber_threshold

name class-attribute instance-attribute

name = 'multihop_qkd'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

qber_threshold instance-attribute

qber_threshold = qber_threshold

roles

roles() -> list[Role]
Source code in qnetbench/apps/multihop_qkd.py
def roles(self) -> list[Role]:
    return ["repeater", "alice", "bob"]  # repeater = hub (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/multihop_qkd.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "repeater":
        return self._repeater(host, rounds)
    return self._endpoint(host, role, rounds)

ObliviousTransfer

ObliviousTransfer(
    transfers: int = 16, qubits: int = 32, block: int = 8
)
Source code in qnetbench/apps/oblivious_transfer.py
def __init__(self, transfers: int = 16, qubits: int = 32, block: int = 8) -> None:
    self.transfers = transfers
    self.qubits = qubits
    # Each secret is masked with the parity of a fixed-size *block* of the set
    # rather than the whole set. A parity over tens of noisy bits is a coin flip
    # (the error rate compounds), which would make the protocol a step function
    # at F = 1; a bounded block degrades smoothly with channel quality, which is
    # what the fidelity-sensitivity curve needs to resolve.
    self.block = block

name class-attribute instance-attribute

name = 'oblivious_transfer'

transfers instance-attribute

transfers = transfers

qubits instance-attribute

qubits = qubits

block instance-attribute

block = block

roles

roles() -> list[Role]
Source code in qnetbench/apps/oblivious_transfer.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = sender, bob = receiver

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/oblivious_transfer.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    transfers = cfg_int(cfg, "transfers", self.transfers)
    qubits = cfg_int(cfg, "qubits", self.qubits)
    if role == "alice":
        return self._sender(host, transfers, qubits)
    return self._receiver(host, transfers, qubits)

PositionVerification

PositionVerification(
    rounds: int = 48,
    min_fidelity: float = 0.85,
    response_budget: float = 0.01,
)
Source code in qnetbench/apps/position_verification.py
def __init__(
    self,
    rounds: int = 48,
    min_fidelity: float = 0.85,
    response_budget: float = 1e-2,
) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity
    # The round-trip light-travel bound for the claimed position. A pair that
    # arrives later than this cannot support a sound verification.
    self.response_budget = response_budget

name class-attribute instance-attribute

name = 'position_verification'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

response_budget instance-attribute

response_budget = response_budget

roles

roles() -> list[Role]
Source code in qnetbench/apps/position_verification.py
def roles(self) -> list[Role]:
    return ["verifier", "prover"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/position_verification.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    budget = cfg_float(cfg, "response_budget", self.response_budget)
    if role == "verifier":
        return self._verifier(host, rounds, budget)
    return self._prover(host, rounds, budget)

QKD

QKD(
    rounds: int = 256,
    min_fidelity: float = 0.9,
    qber_threshold: float = 0.11,
)
Source code in qnetbench/apps/qkd.py
def __init__(
    self,
    rounds: int = 256,
    min_fidelity: float = 0.9,
    qber_threshold: float = 0.11,
) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity
    self.qber_threshold = qber_threshold

name class-attribute instance-attribute

name = 'qkd'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

qber_threshold instance-attribute

qber_threshold = qber_threshold

roles

roles() -> list[Role]
Source code in qnetbench/apps/qkd.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/qkd.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    peer = _PEER[role]
    rounds = cfg_int(cfg, "rounds", self.rounds)
    epr = host.epr_socket(peer)
    cls = host.classical_socket(peer)
    demand = Demand(min_fidelity=self.min_fidelity, purpose="keep")

    bases: list[int] = []  # 0 = Z, 1 = X
    bits: list[int] = []
    for _ in range(rounds):
        handle = epr.request(1, demand)[0]
        assert handle.qubit is not None
        use_x = host.rng.random() < 0.5
        basis = Basis.X if use_x else Basis.Z
        bit = handle.qubit.measure(basis)
        host.record_measurement(basis, bit)
        bases.append(1 if use_x else 0)
        bits.append(bit)

    # Basis reconciliation (public).
    cls.send(bytes(bases))
    their_bases = list(cls.recv())
    sifted = [i for i in range(rounds) if bases[i] == their_bases[i]]

    # Public test subset (every other sifted index) for QBER estimation.
    test = [i for k, i in enumerate(sifted) if k % 2 == 0]
    keep = [i for k, i in enumerate(sifted) if k % 2 == 1]
    cls.send(bytes(bits[i] for i in test))
    their_test = list(cls.recv())
    errors = sum(1 for j, i in enumerate(test) if bits[i] != their_test[j])
    qber = errors / len(test) if test else 0.0

    key = [bits[i] for i in keep]
    success = qber <= self.qber_threshold and len(key) > 0
    # Utility is the *secure* key rate: no secure key survives above the QBER
    # threshold, so utility collapses to 0 there (fidelity-thresholded signature).
    utility = min(len(key) / rounds, 1.0) if success and rounds else 0.0
    return AppOutcome(
        role=role,
        success=success,
        utility=utility,
        payload={"qber": qber, "key_len": len(key), "sifted": len(sifted)},
    )

SecretSharing

SecretSharing(rounds: int = 64, min_fidelity: float = 0.8)
Source code in qnetbench/apps/secret_sharing.py
def __init__(self, rounds: int = 64, min_fidelity: float = 0.8) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'secret_sharing'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/secret_sharing.py
def roles(self) -> list[Role]:
    return ["dealer", "player1", "player2"]  # dealer = hub (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/secret_sharing.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "dealer":
        return self._dealer(host, rounds)
    return self._player(host, role, rounds)

SharedRandomness

SharedRandomness(
    rounds: int = 128,
    min_fidelity: float = 0.8,
    agree_threshold: float = 0.9,
)
Source code in qnetbench/apps/shared_randomness.py
def __init__(
    self, rounds: int = 128, min_fidelity: float = 0.8, agree_threshold: float = 0.9
) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity
    self.agree_threshold = agree_threshold

name class-attribute instance-attribute

name = 'shared_randomness'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

agree_threshold instance-attribute

agree_threshold = agree_threshold

roles

roles() -> list[Role]
Source code in qnetbench/apps/shared_randomness.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/shared_randomness.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    peer = _PEER[role]
    rounds = cfg_int(cfg, "rounds", self.rounds)
    epr = host.epr_socket(peer)
    cls = host.classical_socket(peer)
    demand = Demand(min_fidelity=self.min_fidelity, purpose="measure")

    bits: list[int] = []
    for _ in range(rounds):
        handle = epr.request(1, demand)[0]
        assert handle.outcome is not None  # measured on delivery (purpose="measure")
        bits.append(handle.outcome)

    # Reveal a test subset (public rule) to check the shared bits agree.
    test = [i for i in range(rounds) if i % 2 == 0]
    keep = [i for i in range(rounds) if i % 2 == 1]
    cls.send(bytes(bits[i] for i in test))
    their_test = list(cls.recv())
    agree = sum(1 for j, i in enumerate(test) if bits[i] == their_test[j])
    agreement = agree / len(test) if test else 0.0

    return AppOutcome(
        role=role,
        success=agreement >= self.agree_threshold,
        utility=agreement,
        payload={"agreement": agreement, "shared_bits": len(keep)},
    )

SixState

SixState(rounds: int = 300, qber_threshold: float = 0.126)
Source code in qnetbench/apps/six_state.py
def __init__(self, rounds: int = 300, qber_threshold: float = 0.126) -> None:
    self.rounds = rounds
    self.qber_threshold = qber_threshold  # six-state tolerates a higher QBER than BB84

name class-attribute instance-attribute

name = 'six_state'

rounds instance-attribute

rounds = rounds

qber_threshold instance-attribute

qber_threshold = qber_threshold

roles

roles() -> list[Role]
Source code in qnetbench/apps/six_state.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = sender, bob = receiver

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/six_state.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "alice":
        return self._sender(host, rounds)
    return self._receiver(host, rounds)

EntanglementSwap

EntanglementSwap(
    rounds: int = 64, min_fidelity: float = 0.8
)
Source code in qnetbench/apps/swap.py
def __init__(self, rounds: int = 64, min_fidelity: float = 0.8) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'entanglement_swap'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/swap.py
def roles(self) -> list[Role]:
    return ["repeater", "alice", "bob"]  # repeater = hub (role[0])

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/swap.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "repeater":
        return self._repeater(host, rounds)
    return self._endpoint(host, role, rounds)

Teleportation

Teleportation(rounds: int = 64, min_fidelity: float = 0.85)
Source code in qnetbench/apps/teleport.py
def __init__(self, rounds: int = 64, min_fidelity: float = 0.85) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'teleportation'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/teleport.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/teleport.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "alice":
        return self._sender(host, rounds)
    return self._receiver(host, rounds)

ThresholdSecretSharing

ThresholdSecretSharing(
    rounds: int = 64, min_fidelity: float = 0.9
)
Source code in qnetbench/apps/threshold_secret_sharing.py
def __init__(self, rounds: int = 64, min_fidelity: float = 0.9) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity

name class-attribute instance-attribute

name = 'threshold_secret_sharing'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

roles

roles() -> list[Role]
Source code in qnetbench/apps/threshold_secret_sharing.py
def roles(self) -> list[Role]:
    # dealer holds share 0 (hub); player i holds share i.
    return ["dealer", "player1", "player2", "player3", "player4"]

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/threshold_secret_sharing.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    if role == "dealer":
        return self._dealer(host, rounds)
    return self._player(host, role, rounds)

VerifiedBQC

VerifiedBQC(
    rounds: int = 16,
    min_fidelity: float = 0.95,
    trap_ratio: float = 0.5,
)
Source code in qnetbench/apps/verified_bqc.py
def __init__(
    self, rounds: int = 16, min_fidelity: float = 0.95, trap_ratio: float = 0.5
) -> None:
    self.rounds = rounds
    self.min_fidelity = min_fidelity
    self.trap_ratio = trap_ratio

name class-attribute instance-attribute

name = 'verified_bqc'

rounds instance-attribute

rounds = rounds

min_fidelity instance-attribute

min_fidelity = min_fidelity

trap_ratio instance-attribute

trap_ratio = trap_ratio

roles

roles() -> list[Role]
Source code in qnetbench/apps/verified_bqc.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]  # alice = client/verifier, bob = blind server

run

run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/verified_bqc.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    rounds = cfg_int(cfg, "rounds", self.rounds)
    demand = Demand(min_fidelity=self.min_fidelity, latency_budget=0.05, purpose="keep")
    if role == "alice":
        return self._client(host, rounds, demand)
    return self._server(host, rounds, demand)

get_app

get_app(name: str) -> Application

Resolve any benchmark by name (core or catalog).

Source code in qnetbench/apps/__init__.py
def get_app(name: str) -> Application:
    """Resolve any benchmark by name (core or catalog)."""
    try:
        return _CATALOG[name]
    except KeyError:
        raise KeyError(f"unknown app {name!r}; try `qnetbench list --all`") from None

register_app

register_app(
    app: Application, *, replace: bool = False
) -> str

Add a benchmark instance to the catalog under its own name, and return that name.

Everything name-addressed then resolves it — get_app, run_once, characterize_app, catalog_apps() — which is how a benchmark built at runtime (typically DQC(circuit) over a circuit you loaded or generated) reaches the harness without being baked into this module. The registration lives in the importing process only; to expose one on the command line, add it to _CORE.

Source code in qnetbench/apps/__init__.py
def register_app(app: Application, *, replace: bool = False) -> str:
    """Add a benchmark instance to the catalog under its own `name`, and return that name.

    Everything name-addressed then resolves it — `get_app`, `run_once`,
    `characterize_app`, `catalog_apps()` — which is how a benchmark built at runtime
    (typically `DQC(circuit)` over a circuit you loaded or generated) reaches the
    harness without being baked into this module. The registration lives in the
    importing process only; to expose one on the command line, add it to `_CORE`.
    """
    if not replace and app.name in _CATALOG:
        raise KeyError(f"app {app.name!r} is already registered; pass replace=True to override")
    _CATALOG[app.name] = app
    return app.name

available_apps

available_apps() -> list[str]

The core protocol set (CI, corpus, cross-backend equivalence).

Source code in qnetbench/apps/__init__.py
def available_apps() -> list[str]:
    """The core protocol set (CI, corpus, cross-backend equivalence)."""
    return sorted(_CORE_REGISTRY)

catalog_apps

catalog_apps() -> list[str]

The full catalog: core + parameterized instances (50+).

Source code in qnetbench/apps/__init__.py
def catalog_apps() -> list[str]:
    """The full catalog: core + parameterized instances (50+)."""
    return sorted(_CATALOG)

Distributed quantum computing

The DQC application is the one that turns a circuit into demand; it is what the generated catalog is built from.

qnetbench.apps.dqc

Distributed quantum computing (DQC): execute a partitioned circuit across nodes.

The demand comes from a real circuit, not a hand-set contract. Each node runs its slice: single-qubit and same-node two-qubit gates apply locally; every non-local two-qubit gate becomes a teleported gate — one entanglement request whose deadline is the gate's ASAP layer × a per-layer budget. So the trace's entanglement requests are the circuit's Entanglement Demand Schedule.

Demand signature: bursty and deadline-critical, with a shape set by the circuit (gate count, non-local fraction, depth). Library circuits are mirror circuits (U;U†), so a noiseless run returns every qubit to |0>; utility is the fraction of qubits measured 0, which degrades as teleported-gate fidelity drops.

DQC

DQC(
    circuit: Circuit,
    min_fidelity: float = 0.9,
    layer_budget: float = 0.01,
)

A DQC benchmark for one (2-node) partitioned circuit.

Source code in qnetbench/apps/dqc.py
def __init__(
    self, circuit: Circuit, min_fidelity: float = 0.9, layer_budget: float = 1e-2
) -> None:
    if set(circuit.partition) - {0, 1}:
        raise ValueError("DQC currently supports 2-node (alice/bob) partitions only")
    self.circuit = circuit
    self.name = f"dqc_{circuit.name}"
    self.min_fidelity = min_fidelity
    self.layer_budget = layer_budget
circuit instance-attribute
circuit = circuit
name instance-attribute
name = f'dqc_{circuit.name}'
min_fidelity instance-attribute
min_fidelity = min_fidelity
layer_budget instance-attribute
layer_budget = layer_budget
roles
roles() -> list[Role]
Source code in qnetbench/apps/dqc.py
def roles(self) -> list[Role]:
    return ["alice", "bob"]
run
run(
    host: Host, role: Role, cfg: dict[str, object]
) -> AppOutcome
Source code in qnetbench/apps/dqc.py
def run(self, host: Host, role: Role, cfg: dict[str, object]) -> AppOutcome:
    node = _NODE[role]
    circuit = self.circuit
    epr = host.epr_socket(_PEER[role])
    cls = host.classical_socket(_PEER[role])

    qubits: dict[int, Qubit] = {
        q: host.qalloc() for q in range(circuit.n_qubits) if circuit.partition[q] == node
    }
    for op, layer in zip(circuit.ops, circuit.layers(), strict=True):
        self._apply(op, layer, node, qubits, epr, cls)

    # Mirror circuit: every qubit should read 0 noiselessly.
    zeros = sum(1 for q in qubits.values() if q.measure(Basis.Z) == 0)
    total = len(qubits)

    # Reconcile the two halves for a global success measure.
    cls.send(bytes([zeros, total]))
    their_zeros, their_total = cls.recv()[:2]
    all_zeros, all_total = zeros + their_zeros, total + their_total
    return AppOutcome(
        role=role,
        success=all_zeros == all_total,
        utility=all_zeros / all_total if all_total else 0.0,
        payload={"n_nonlocal": circuit.n_nonlocal(), "depth": circuit.depth()},
    )

Configuration helpers

qnetbench.apps.util

Small typed helpers for reading loosely-typed run configuration.

cfg_int

cfg_int(
    cfg: Mapping[str, object], key: str, default: int
) -> int
Source code in qnetbench/apps/util.py
def cfg_int(cfg: Mapping[str, object], key: str, default: int) -> int:
    val = cfg.get(key, default)
    if isinstance(val, bool) or not isinstance(val, (int, float, str)):
        return default
    return int(val)

cfg_float

cfg_float(
    cfg: Mapping[str, object], key: str, default: float
) -> float
Source code in qnetbench/apps/util.py
def cfg_float(cfg: Mapping[str, object], key: str, default: float) -> float:
    val = cfg.get(key, default)
    if isinstance(val, bool) or not isinstance(val, (int, float, str)):
        return default
    return float(val)