Skip to main content

Universal Node Provider System

The Node Provider System is QCOS's plugin architecture that lets you connect any number of GPUs, QPUs, or custom compute nodes to the DistributedQVM — from a local laptop to a 64-GPU LUMI supercomputer — without changing your application code.


Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│ Your Application │
│ qvm.run(VirtualCircuitSpec) → QVMResult │
└─────────────────────────────┬───────────────────────────────────────┘

┌─────────────────────────────▼───────────────────────────────────────┐
│ DistributedQVM │
│ ShardPlanner → NodeExecutor → ClassicalReconstructor │
└─────────────────────────────┬───────────────────────────────────────┘

┌─────────────────────────────▼───────────────────────────────────────┐
│ QPURegistry │
│ { node_id → QPUNodeSpec, node_id → NodeProvider } │
└──────────┬──────────────────┬──────────────────┬────────────────────┘
│ │ │
┌──────────▼──────┐ ┌────────▼────────┐ ┌──────▼──────────────────┐
│ LocalGPUMPS │ │ LUMIAMDGPU │ │ AzureQuantum │
│ (tensor-net) │ │ (MI250X ROCm) │ │ (Rigetti / Quantinuum) │
│ n_nodes=8 │ │ n_nodes=4×8 │ │ targets=[...] │
│ max_qubits=2000│ │ GCDs=32 │ │ cost=$0.0009/shot │
└─────────────────┘ └─────────────────┘ └─────────────────────────┘

The key insight: providers are interchangeable. The DistributedQVM only sees QPURegistry — it doesn't care whether the underlying hardware is a laptop, a supercomputer, or a cloud QPU.


Built-in Providers

Provider keyHardwareMax qubits/nodeCost
local_cpuQiskit Aer — CPU statevector30q (exact)Free
local_gpu_aerQiskit Aer — CUDA statevector32q (exact)Free
local_gpu_mpsQiskit Aer — MPS tensor-network2000q+ (approx.)Free
local_gpu_cuquantumNVIDIA cuQuantum via CuPy36q (A100 80GB)Free
lumi_amd_gpuLUMI MI250X — ROCm (8 GCDs/node)34q SV + 2000q MPSGPU-hours
azure_quantumRigetti Ankaa-3, Quantinuum H2-1, Estimator56–100q real QPUFrom $0.0009/shot
ibm_quantumIBM Eagle/Heron/Condor127–1121q$0.000044/shot
aws_braketIonQ Aria, Rigetti, IQM Garnet20–84qFrom $0.0009/shot
custom_restAny QPU/GPU with /run-circuit HTTP endpointConfigurable$0

Quickstart (30 seconds)

from network.node_providers import ClusterBuilder
from network.distributed_qvm import DistributedQVM, VirtualCircuitSpec, QVMMode
from qiskit import QuantumCircuit

# 1. Build your cluster — mix and match any providers
registry = (
ClusterBuilder()
.add("local_gpu_mps", n_nodes=4, max_qubits=1000)
.add("local_gpu_aer", n_nodes=8, max_qubits=28)
.build()
)

# 2. Create the QVM
qvm = DistributedQVM(registry, mode=QVMMode.EMULATED, shots=2048)

# 3. Run any circuit
qc = QuantumCircuit(10)
qc.h(range(10))
qc.measure_all()

result = qvm.run(VirtualCircuitSpec(n_logical_qubits=10, circuit_object=qc))
print(result.counts)

Key Concepts

NodeProvider

A NodeProvider is a class that knows how to describe a set of compute nodes. It answers two questions:

  1. What nodes exist?build_nodes(**kwargs) → List[QPUNodeSpec]
  2. How do I run a circuit on them?execute(circuit, shots, node_spec) → Dict[str, int] (optional)

QPURegistry

The QPURegistry holds all registered nodes. It maps node_id → QPUNodeSpec and (optionally) node_id → NodeProvider for custom execution.

ClusterBuilder

The ClusterBuilder is a fluent API that composes multiple providers into a single registry. It is order-independent — the ShardPlanner selects the best node for each shard at execution time.

ShardPlanner

Given a VirtualCircuitSpec, the ShardPlanner partitions it into shards — subcircuits each small enough to fit on one physical node. For a 200-qubit circuit across 8×25q nodes it creates ~8 shards, each running in parallel.


Next Steps

GuideDescription
QuickstartFull working example with real circuits
ClusterBuilderFluent API to compose clusters
LUMI GPU GuideLUMI MI250X supercomputer setup
Azure Quantum GuideAzure cheapest QPU targets
Custom ProvidersWrite your own provider in 10 lines
API ReferenceFull class and method reference