QiliSim
The QiliSim backend is the default CPU simulator developed by Qilimanjaro and written in C++.
It implements every primitive functional natively, supports a noise model on all execution paths,
and is included with the core qilisdk installation — no extra dependency or hardware is required.
Installation
QiliSim is bundled with the core qilisdk installation, so no extra package is required.
Quick start
import numpy as np
from qilisdk.digital import Circuit, H, CNOT
from qilisdk.backends import QiliSim
from qilisdk.functionals import DigitalPropagation
from qilisdk.readout import Readout
# Build a simple circuit
circuit = Circuit(5)
circuit.add(H(0))
circuit.add(CNOT(0, 1))
# Create DigitalPropagation functional
functional = DigitalPropagation(circuit)
# Execute with the QiliSim backend
backend = QiliSim()
result = backend.execute(functional, Readout().with_sampling(nshots=500))
print(result.get_samples())
Functional support
QiliSim natively supports all primitive functionals through dedicated C++ routines:
Functional |
Support |
Notes |
|---|---|---|
✅ |
Statevector-based simulation, configurable via |
|
✅ |
Multiple integration schemes, configurable via |
|
✅ |
Native C++ implementation; supports both Circuit and Schedule reservoir steps. |
|
✅ |
Reuses the primitive functional handlers above for each optimization step. |
Configuration
QiliSim is configured at construction time through three orthogonal sections, all defined in
qilisdk.backends.backend_config:
AnalogMethod— chooses the analog time-evolution scheme and its hyperparameters.DigitalMethod— chooses the digital simulation strategy and its hyperparameters.ExecutionConfig— global execution controls (threads, random seed, Monte Carlo trajectories, measurement-collapse behaviour).
from qilisdk.backends import (
AnalogMethod,
DigitalMethod,
ExecutionConfig,
MonteCarloConfig,
QiliSim,
)
backend = QiliSim(
analog_simulation_method=AnalogMethod.arnoldi(dim=16, num_substeps=2, matrix_free=True),
digital_simulation_method=DigitalMethod.statevector(
matrix_free=True,
max_cache_size=2_000,
combine_single_qubit_gates=True,
),
execution_config=ExecutionConfig(
num_threads=4,
seed=42,
monte_carlo=MonteCarloConfig(trajectories=200),
measurement_collapse=False,
),
)
If any argument is omitted, QiliSim falls back to:
AnalogMethod.integrator()(matrix-free RK4),a default
ExecutionConfig(all cores, random seed, Monte Carlo disabled).
Analog simulation methods
Use the classmethods of AnalogMethod to choose how the
schedule is integrated:
Constructor |
Underlying scheme |
When to use it |
|---|---|---|
RK4 |
Default. Fixed-step Runge-Kutta 4. matrix-free is faster for sparse Hamiltonians. |
|
Variational annealing |
Only available for X to Z annealing schedules. Can be used to simulate large (i.e. 60+ qubits) systems at the cost of accuracy. Set order=1 for a quicker but less accurate simulation. Increasing warmups can also improve accuracy at the cost of time. |
|
Dormand-Prince RK4/5 |
Adaptive step size; |
|
|
Krylov / Arnoldi |
Can offer decent scaling for large sparse Hamiltonians; tune |
Matrix exponential |
Reference scheme for small systems; cost grows quickly with qubit count. |
Example, using the adaptive integrator:
from qilisdk.backends import AnalogMethod, QiliSim
backend = QiliSim(analog_simulation_method=AnalogMethod.adaptive_integrator(tol=1e-2))
Digital simulation methods
There are currently two digital simulation methods available. The first is a statevector simulator, which can be configured through the options:
Option |
Meaning |
|---|---|
|
Apply gates directly to the statevector instead of building dense matrices. Default |
|
Maximum number of precomputed gate matrices cached between executions. |
|
Merge adjacent single-qubit gates into a single operation before propagating. Disabled if gate-specific noise is used. |
|
Renormalize the statevector after each gate to mitigate numerical drift, at a runtime cost. |
from qilisdk.backends import DigitalMethod, QiliSim
backend = QiliSim(
digital_simulation_method=DigitalMethod.statevector(
matrix_free=False,
normalize_after_each_gate=True,
),
)
The second is a stabilizer simulator, which can efficiently simulate circuits composed of Clifford gates and Pauli measurements, at the cost of being slower if the circuit contains many non-Clifford gates. It has the following options:
Option |
Meaning |
|---|---|
|
Maximum number of terms in the stabilizer sum. Increasing this can improve accuracy at the cost of memory and runtime. |
from qilisdk.backends import DigitalMethod, QiliSim
backend = QiliSim(
digital_simulation_method=DigitalMethod.stabilizer(max_states=100),
)
Execution and Monte Carlo
ExecutionConfig controls threading, randomness, and
optional Monte Carlo trajectory sampling for open-system simulations.
num_threadscontrols the number of threads used for parallelization, defaults to using all available cores.seedcontrols the random number generator seed, defaults to a random seed. Subsequent runs will increment the seed automatically.monte_carlo=MonteCarloConfig(trajectories=N)enabled Monte Carlo sampling withNtrajectories, if omitted, Monte Carlo is disabled.measurement_collapsecontrols whether measurements collapse the statevector in place (relevant for mid-circuit measurement and reservoirs) - defaults toFalse.normalize_statecontrols whether the state should be renormalized - defaults toTrue.gpucontrols whether to use GPU acceleration if available - defaults toFalse.
from qilisdk.backends import ExecutionConfig, MonteCarloConfig, QiliSim
backend = QiliSim(
execution_config=ExecutionConfig(
num_threads=8,
seed=42,
monte_carlo=MonteCarloConfig(trajectories=500),
measurement_collapse=True,
normalize_state=False,
gpu=True,
),
)
Noise model support
Any NoiseModel accepted by the SDK can be passed directly to the constructor;
QiliSim applies it inside the C++ solver, so digital, analog, and reservoir runs all see the same
noise channels:
from qilisdk.backends import QiliSim
from qilisdk.noise import NoiseModel, Depolarizing
nm = NoiseModel()
nm.add(Depolarizing(probability=1e-3))
backend = QiliSim(noise_model=nm)
GPU acceleration
Some simulation methods in QiliSim support GPU acceleration if a CUDA-capable device is available.
These require the cuda extra to be installed:
pip install qilisdk[cuda13]
pip install "qilisdk[cuda13]"
pip install qilisdk[cuda13]
Method |
GPU support |
|---|---|
❌ |
|
❌ |
|
❌ |
|
❌ |
|
✅ |
|
❌ |
|
❌ |