NetQMPI is a Python library that brings the classical MPI (Message Passing
Interface) programming model to Distributed Quantum Computing (DQC). Following
a Single-Program, Multiple-Data (SPMD) paradigm, the developer writes a single
script that runs across N quantum nodes and coordinates them through
message-passing primitives — including quantum-aware ones such as qsend,
qrecv and quantum collectives — without manually orchestrating low-level
entanglement, teleportation or classical messaging.
Crucially, NetQMPI is now backend-agnostic: the same, unmodified application runs on several execution engines (a quantum-network simulator, an HPC emulator, a circuit simulator, …) simply by selecting a backend on the command line.
- Architecture: a decoupled design
- Available backends
- Installation
- Quick start
- Backend hardware configuration (
--config) - Writing a new backend
- Examples
- Cite this work
Earlier versions of NetQMPI were implemented directly on top of the NetQASM SDK, which tied programs to a single execution stack. NetQMPI has since been restructured into a decoupled architecture that strictly separates what a distributed quantum program does from how and where it runs (see Vázquez-Pérez et al.):
- SDK (user-facing). Backend-agnostic abstractions:
Environment(the local node context and a factory for circuits),Circuit(a fluent gate +qsend/qrecvAPI that records operations into anOperationContainer), and theQMPICommunicator(rank/size and communication primitives). Application code depends only on these. - Runtime (execution-facing). Selects and drives a concrete backend through
the Adapter pattern + dependency injection: an
Executorbootstraps the processes and injects a backend-specific communicator into theEnvironment; aCircuitAdaptertranslates the recorded operations into native backend instructions; a concreteCommunicatormaps ranks and communication onto the platform's resources.
Because the boundary between the two layers is strict, the same app.py runs
on any backend by switching a flag — no changes to application logic.
| Backend | CLI flag | What it targets | Key dependencies |
|---|---|---|---|
| NetQASM / SquidASM | --netqasm |
Low-level quantum-network simulation (EPR sockets, NetQASM routines) | squidasm, netsquid, netqasm 1.x |
| CUNQA | --cunqa |
HPC emulation of DQC through virtual QPUs (vQPUs) | cunqa (HPC / Slurm environment) |
| Qiskit Aer | --aer |
Shot-based circuit simulation (swap- or teleportation-based transfer) | qiskit, qiskit-aer |
| Qoala | --qoala |
Quantum-internet node execution environment with task scheduling & multitasking — simulation only | qoala, netsquid, netqasm 2.x, Python 3.10–3.12 |
NetSquid account. The NetQASM and Qoala backends depend on NetSquid, which requires a (free) account and is installed from its private index:
pip install netsquid --extra-index-url https://<user>:<pwd>@pypi.netsquid.org.NetQASM 1.x vs 2.x. The NetQASM/SquidASM backend uses
netqasm1.x, while Qoala usesnetqasm2.x. These are mutually incompatible, so the--netqasmand--qoalabackends must live in separate environments (e.g. two conda envs). CUNQA and Aer have no such constraint.Qoala is simulation-only. It models the software/hardware architecture of a quantum-internet node on NetSquid; it is not a path to real-hardware execution.
Install the core package with pip:
pip install netqmpiThen install the backend(s) you intend to use. Each backend lives behind a lazy import, so you only need the dependencies of the backend you actually run.
NetQASM / SquidASM backend
pip install squidasm --extra-index-url https://<user>:<pwd>@pypi.netsquid.org
# pulls in netsquid and netqasm 1.xSee the NetQASM installation docs.
Qoala backend (separate environment, simulation only)
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 # netqasm 2.x
pip install netqmpiCUNQA backend (HPC)
Install and configure CUNQA on your HPC
cluster (it provisions vQPUs via the job scheduler), then install netqmpi in
the same environment.
Qiskit Aer backend
pip install qiskit qiskit-aerNetQMPI is launched with an MPI-like command that selects the number of nodes and the backend:
netqmpi -n <NUM_NODES> app.py --netqasm # quantum-network simulation
netqmpi -n <NUM_NODES> app.py --cunqa --shots 1024 # HPC vQPU emulation
netqmpi -n <NUM_NODES> app.py --aer --shots 1024 # circuit simulation
netqmpi -n <NUM_NODES> app.py --qoala --shots 100 # Qoala node exec. environmentThe example below (examples/netqmpi/send_recv.py) prepares a qubit in
superposition on one node and teleports it to a neighbour with qsend/qrecv.
It uses only SDK abstractions, so the very same file runs on every backend:
from netqmpi.sdk.environment import Environment
def main(env: Environment = None):
comm = env.comm
rank = comm.rank
next_rank = comm.get_next_rank(rank)
previous_rank = comm.get_prev_rank(rank)
with comm: # everything inside this block is executed on the backend
if rank == 0:
circuit = env.create_circuit(num_qubits=1, num_clbits=1)
circuit.h(0) # prepare |+>
comm.qsend(circuit, [0], next_rank) # teleport the qubit
else:
circuit = env.create_circuit(num_qubits=1, num_clbits=1)
comm.qrecv(circuit, [0], previous_rank)
circuit.measure(0, 0)
results = comm.results
if rank != 0:
print(f"measure: {results}")
else:
print("teleportation complete")netqmpi -n 2 examples/netqmpi/send_recv.py --netqasm
netqmpi -n 2 examples/netqmpi/send_recv.py --qoala --shots 100The programmer only invokes comm.qsend() / comm.qrecv(); entanglement
generation, teleportation and classical corrections are handled by the selected
backend adapter.
Backend-specific parameters are passed through a single YAML file with --config
(instead of a proliferation of per-backend flags). The file has generic settings
at the top level plus an optional block named after the backend; only the block
for the selected backend is read. For example, configuring the Qoala qdevice and
its entanglement link:
# config.yaml
shots: 1000
seed: 7
qoala:
link_fidelity: 0.8 # EPR-pair fidelity in [0.25, 1.0]
hardware: # qdevice noise model (omit for a perfect device)
t1: 0
t2: 0
single_qubit_gate_depolar_prob: 0.1
two_qubit_gate_depolar_prob: 0.0netqmpi -n 2 app.py --qoala --config config.yamlAdding a backend never requires touching the SDK. Following the architecture
above, you provide three Runtime components under
netqmpi/runtime/adapters/<backend>/ (mirroring the existing netqasm/,
cunqa/, aer/, qoala/ packages):
Executor(subclass ofnetqmpi.runtime.executor.Executor) — bootstraps the execution environment, discovers resources, and injects a backend-specific communicator into each node'sEnvironment(build_apps+run).CircuitAdapter(subclass ofnetqmpi.sdk.circuit.Circuit) — implements the_translate_*hooks that map the abstract operations recorded in theOperationContainer(local gates,measure,qsend/qrecv, …) to the backend's native instructions.QMPICommunicator(subclass of the abstract communicator) — maps rank / size and the communication primitives onto the backend's real resources, and triggers execution on context exit.
Finally, register a --<backend> flag in netqmpi/runtime/cli.py (with a lazy
import so users without that backend's dependencies are unaffected). The
integration workflow is identical for every backend; only the realization of
these three components differs.
Ready-to-run scripts live in examples/netqmpi/:
send_recv.py (distributed superposition / teleportation), scatter.py,
gather.py, roundrobin.py, qft_expose.py.
Validation experiments for the Qoala backend (hardware-parameter propagation, EPR
fidelity sweep, and scheduling/multitasking) are documented in
scripts/experiments/.
If you use NetQMPI in your research, please cite the following works:
F. Javier Cardama, Tomás F. Pena Proceedings of the IEEE International Conference on Cluster Computing (IEEE Cluster 2025) DOI: 10.1109/CLUSTERWorkshops65972.2025.11164201
Jorge Vázquez-Pérez, F. Javier Cardama, Tomás F. Pena, Andrés Gómez Proceedings of the IEEE International Conference on Distributed Computer Systems (ICDCS 2026). PDF: PDF Paper
F. Javier Cardama, Jorge Vázquez-Pérez, C. Piñeiro, T. F. Pena, J. C. Pichel, Andrés Gómez Future Generation Computer Systems, Vol. 174, 2026, Article 107989 DOI: 10.1016/j.future.2025.107989
