QiliSim Backend

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.

Instalación

QiliSim is bundled with the core qilisdk installation, so no extra package is required.

Inicio rápido

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())

Soporte de funcionales

QiliSim soporta de forma nativa todos los funcionales primitivos mediante rutinas dedicadas en C++:

Funcional

Soporte

Notas

DigitalPropagation

Simulación basada en vector de estado, configurable mediante DigitalMethod.

AnalogEvolution

Múltiples esquemas de integración, configurables mediante AnalogMethod.

QuantumReservoir

Implementación nativa en C++; soporta tanto pasos Circuit como Schedule del reservorio.

VariationalProgram

Reutiliza los manejadores de funcionales primitivos anteriores en cada paso de optimización.

Configuración

QiliSim se configura en el momento de la construcción a través de tres secciones ortogonales, todas definidas en qilisdk.backends.backend_config:

  • AnalogMethod — elige el esquema de evolución temporal analógica y sus hiperparámetros.

  • DigitalMethod — chooses the digital simulation strategy and its hyperparameters.

  • ExecutionConfig — controles globales de ejecución (hilos, semilla aleatoria, trayectorias de Monte Carlo, comportamiento del colapso de medición).

from qilisdk.backends import (
    AnalogMethod,
    DigitalMethod,
    ExecutionConfig,
    MonteCarloConfig,
    QiliSim,
)

backend = QiliSim(
    analog_simulation_method=AnalogMethod.arnoldi(dim=16, num_substeps=2),
    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,
    ),
)

Si se omite algún argumento, QiliSim recurre a:

Métodos de simulación analógica

Utilice los métodos de clase de AnalogMethod para elegir cómo se integra el schedule:

Constructor

Esquema subyacente

Cuándo utilizarlo

AnalogMethod.integrator(matrix_free=True)

RK4

Por defecto. Runge-Kutta 4 con paso fijo; sin matriz es más rápido para Hamiltonianos dispersos.

AnalogMethod.adaptive_integrator(tol=1e-2)

Dormand-Prince RK4/5

Tamaño de paso adaptativo; tol acota el error de fidelidad entre las estimaciones RK4 y RK5.

AnalogMethod.arnoldi(dim=10, num_substeps=1)

Krylov / Arnoldi

Can offer decent scaling for large sparse Hamiltonians; tune dim for the Krylov subspace size.

AnalogMethod.direct()

Exponencial de matriz

Esquema de referencia para sistemas pequeños; el coste crece rápidamente con el número de qubits.

Ejemplo, utilizando el integrador adaptativo para un schedule más rígido:

from qilisdk.backends import AnalogMethod, QiliSim

backend = QiliSim(analog_simulation_method=AnalogMethod.adaptive_integrator(tol=1e-2))

Métodos de simulación digital

La ejecución digital se basa actualmente siempre en vector de estado; la configuración DigitalMethod ajusta sus características de rendimiento en lugar de elegir un algoritmo distinto:

Opción

Significado

matrix_free

Aplica las puertas directamente al vector de estado en lugar de construir matrices densas. Por defecto True.

max_cache_size

Número máximo de matrices de puerta precomputadas almacenadas en caché entre ejecuciones.

combine_single_qubit_gates

Merge adjacent single-qubit gates into a single operation before propagating. Disabled if gate-specific noise is used.

normalize_after_each_gate

Renormaliza el vector de estado tras cada puerta para mitigar la deriva numérica, con un coste de tiempo de ejecución.

from qilisdk.backends import DigitalMethod, QiliSim

backend = QiliSim(
    digital_simulation_method=DigitalMethod.statevector(
        matrix_free=False,
        normalize_after_each_gate=True,
    ),
)

Ejecución y Monte Carlo

ExecutionConfig controla los hilos, la aleatoriedad y el muestreo opcional de trayectorias Monte Carlo para simulaciones de sistemas abiertos.

  • num_threads=0 (por defecto) permite al simulador utilizar todos los núcleos físicos.

  • seed=None (por defecto) genera una semilla aleatoria nueva en el momento de la construcción; pase un entero para reproducibilidad.

  • monte_carlo=MonteCarloConfig(trajectories=N) activa el muestreo estocástico de trayectorias para modelos de ruido que admiten un unraveling de Monte Carlo; déjelo en None para una evolución determinista de la ecuación maestra.

  • measurement_collapse controla si las mediciones colapsan el vector de estado in situ (relevante para mediciones en mitad del circuito y computación de reservorios); por defecto False.

from qilisdk.backends import ExecutionConfig, MonteCarloConfig, QiliSim

backend = QiliSim(
    execution_config=ExecutionConfig(
        num_threads=8,
        seed=1234,
        monte_carlo=MonteCarloConfig(trajectories=500),
        measurement_collapse=True,
    ),
)

Noise model support

Cualquier NoiseModel aceptado por el SDK se puede pasar directamente al constructor; QiliSim lo aplica dentro del solver de C++, de modo que las ejecuciones digitales, analógicas y de reservorio ven todos los mismos canales de ruido:

from qilisdk.backends import QiliSim
from qilisdk.noise import NoiseModel, Depolarizing

nm = NoiseModel()
nm.add(Depolarizing(probability=1e-3))

backend = QiliSim(noise_model=nm)