Qoala backend¶
netqmpi -n <N> app.py --qoala [--shots N] [--config qoala.yaml]
Qoala models the software/hardware architecture of a quantum-internet node: task scheduling, multitasking between programs, and a configurable qdevice, all on top of NetSquid. Where NetQASM simulates the network, Qoala simulates what happens inside a node while the network runs.
Simulation only
Qoala is a NetSquid-based simulator. This backend has no real-hardware execution path and must not be considered on par with a physical deployment.
Packages:
qoala,netsquid,netqasm2.xPython: 3.10 – 3.12
Adapter:
netqmpi.runtime.adapters.qoala
Installation¶
Qoala needs its own environment, because its netqasm 2.x is incompatible
with the 1.x used by the NetQASM backend:
conda create -n qoala python=3.11 -y
conda activate qoala
pip install netsquid --extra-index-url https://<user>:<pwd>@pypi.netsquid.org
pip install qoala --extra-index-url https://<user>:<pwd>@pypi.netsquid.org
pip install netqmpi
What it supports¶
Primitive |
Status |
|---|---|
|
✅ full teleportation (EPR + BSM + corrections) |
|
❌ |
|
❌ |
|
❌ |
|
❌ |
Classically controlled gates |
❌ |
Several circuits per rank |
❌ exactly one circuit per rank |
Gates: H X Y Z directly; S SDG T TDG as fixed rot_z rotations;
RX RY RZ discretised to multiples of π/16; SWAP as three CNOTs; and
controlled X (cnot) and Z (cphase).
What was fixed
The controlled-gate table was written against names the SDK never emits, and three things followed from that:
cxandczwere unreachable. The table compared the target gate’s name against"RX"and"RZ", but the SDK records a CNOT as a controlledGate('X')and a CZ as a controlledGate('Z'). Both of the gates the table meant to support raisedNotImplementedError.crz(theta)came out as a plain CZ. Acrzdoes record a controlledGate('RZ'), so it fell into the"RZ"branch and was emitted ascphase— a controlled-Z — with the angle silently discarded. It is now refused explaining why: NetQASM has no controlled-rotation instruction.SWAPreached no table at all. The SDK records it as a two-qubitGate, so it was dispatched down the single-qubit path and died as an unknown name.
Shots are simulated one at a time
Up to 0.3.1 every shot went into one batch, and Qoala runs the instances of a
batch concurrently on nodes whose physical qubits they share. A program
that keeps a qubit allocated across a round trip — apps/ghz.py holds its
control while the tour is away — could then have two shots each holding part of
a node’s memory and waiting for the rest. Qoala’s scheduler waits for memory
rather than failing, NetSquid stops when no event is left, and the run came back
with programs unfinished: KeyError: 'm_8' (m_16 at three ranks, m_24 at
four — rank 0’s final measurement). The compiled program was correct all along.
Each shot is now its own simulation by default, which is also what a shot means
(the program alone on its nodes: with memory noise, sharing the device would
stretch its timeline and add decoherence it would not otherwise suffer). The
price is one network built per shot. concurrent_shots: k puts k shots in each
simulation and gives every node k times the qubits a shot needs, so they cannot
starve each other; use it for noiseless runs where speed matters.
A program that does not finish is now reported as a deadlock, naming the rank
and the missing variable, instead of as a bare KeyError.
Validated scale
cascade runs up to 128 ranks and 6 qubits per rank. ghz failed in every
configuration before the change above and needs re-validating at scale. qft
needs controlled-P and qft_telegate needs expose, neither of which this
adapter implements. The default qdevice and links are perfect.
More than one circuit per rank is rejected explicitly:
NotImplementedError: The Qoala backend currently supports exactly one circuit
per rank (rank 0 created 2).
Configuration¶
This is the backend with the richest noise model — it is the reason to choose it.
# qoala.yaml
shots: 1000
seed: 7
qoala:
link_fidelity: 0.8 # EPR-pair fidelity in [0.25, 1.0]
link_duration: 1000.0 # EPR generation time (ns)
qnos_instr_time: 1000.0 # one quantum-processor instruction (ns)
hardware: # qdevice noise model; omit for a perfect device
t1: 0
t2: 0
single_qubit_gate_time: 5e3
two_qubit_gate_time: 200e3
single_qubit_gate_depolar_prob: 0.1
two_qubit_gate_depolar_prob: 0.0
link_fidelity below 1.0 uses a depolarising link with
prob_max_mixed = (4/3)(1 - link_fidelity); a value outside [0.25, 1.0] is
rejected when the config is built. t1 == t2 == 0 means “no memory noise”, so
the defaults describe a perfect qdevice.
The full field list is in the qoala block.
Note
Depolarising noise applies to the gates only. INSTR_INIT and
INSTR_MEASURE carry their own duration but no depolarising error, so there is
no separate readout-flip model.
Execution model¶
The adapter compiles each rank’s circuit to .iqoala program text rather
than driving an API. Local gates and measurements are buffered and flushed into
QL blocks; a qsend or qrecv closes the current block and emits the
teleportation blocks around it.
All ranks run in the same process, and the joint NetSquid simulation is deferred
until every rank has left its with comm: block. Each rank compiles and
registers its program on __exit__; when the last rank registers, the executor
builds the Qoala network and runs one simulation for all ranks at once.
The communicator module imports no qoala package: program text is produced
by QoalaCircuitAdapter and the simulation is driven by QoalaExecutorAdapter,
which imports qoala and netsquid lazily inside its own methods.
Results¶
comm.results is a {bitstring: count} histogram for this rank alone,
ordered by ascending classical-bit index. A rank that returns no measurements
gets an empty dict.
Validation experiments¶
The repository ships three experiments validating this backend, under
scripts/experiments/:
- Hardware-parameter propagation
Checks that qdevice noise (T1/T2, gate times, depolarisation) is propagated faithfully through NetQMPI’s translation, by comparing against a hand-written native Qoala control program with the same qdevice and a perfect link.
- EPR fidelity sweep
With a perfect qdevice, sweeps the EPR-pair fidelity of
qsend/qrecvand compares against the perfect link.- Scheduling / multitasking
Two NetQMPI programs sharing a node. Qoala’s scheduler reduces the makespan by 18.9% without degrading fidelity, with a CPS/QPS Gantt chart of the interleaving.
The fidelity probe used throughout is a distributed superposition teleported and
read out in the X basis: measuring |+⟩ directly in Z gives 50/50 even
without noise, so it is useless as a fidelity measure. Measuring in the state’s
own basis makes fidelity run from 1.0 (noiseless) to 0.5 (fully depolarised),
sensitive to T1, T2 and depolarisation.