Backend CUDA-Q

El backend CUDA-Q aprovecha las GPU de NVIDIA a través del framework cuda-quantum. Cuando no se detecta ninguna GPU compatible recae de forma transparente en un destino de CPU, de modo que el mismo código creado en un portátil también funcionará en una máquina con aceleración.

Instalación

CUDA-Q no se distribuye con QiliSDK; instale usted mismo la versión que corresponda a su toolkit de CUDA y el backend quedará disponible:

pip install "cuda-quantum-cu12>=0.14.0"   # or cuda-quantum-cu13

Nota

CudaqBackend requiere CUDA-Q 0.14.0 o posterior. CUDA-Q no publica wheels para Python 3.14, por lo que el backend no está disponible ahí hasta que lo haga.

Inicio rápido

import numpy as np
from qilisdk.digital import Circuit, H, RX, CNOT
from qilisdk.backends import CudaqBackend, CudaqSamplingMethod
from qilisdk.functionals import DigitalPropagation
from qilisdk.readout import Readout

circuit = Circuit(2)
circuit.add(RX(0, theta=np.pi / 4))
circuit.add(H(0))
circuit.add(CNOT(0, 1))

backend = CudaqBackend(sampling_method=CudaqSamplingMethod.STATE_VECTOR)
result = backend.execute(DigitalPropagation(circuit), Readout().with_sampling(nshots=500))
print(result.get_samples())

Soporte de funcionales

Funcional

Soporte

Notas

DigitalPropagation

Kernel CUDA-Q nativo. El método de muestreo se selecciona mediante CudaqSamplingMethod. Las mediciones intermedias lanzan NotImplementedError.

AnalogEvolution

Impulsada por cudaq.evolve sobre el target dynamics (siempre acelerada por GPU cuando está disponible, con independencia del método de muestreo digital).

QuantumReservoir

🟡

CudaqBackend no implementa Backend._execute_quantum_reservoir. Los pasos Circuit dentro de la capa del reservorio recaen en una multiplicación unitaria QTensor densa en CPU; los pasos Schedule siguen utilizando evolve de CUDA-Q. Cualquier modelo de ruido adjunto se ignora.

VariationalProgram

Reutiliza los manejadores digital/analógico anteriores en cada paso de optimización.

Configuración

El backend CUDA expone un único parámetro de configuración — CudaqSamplingMethod — que selecciona el target subyacente de CUDA-Q utilizado para los circuitos digitales. Si no se especifica ningún método, se utiliza STATE_VECTOR. La evolución analógica siempre se ejecuta sobre el target dynamics e ignora esta opción.

Método

Target de CUDA-Q

Admite muestreo

Admite valores esperados

Admite tomografía de estado

STATE_VECTOR

nvidia cuando hay una GPU disponible, en caso contrario qpp-cpu. La precisión coincide con Precision.

STATE_VECTOR_MGPU

nvidia-mgpu cuando hay varias GPUs disponibles, en caso contrario recurre a nvidia.

TENSOR_NETWORK

tensornet. Adecuado para circuitos poco profundos pero anchos.

MATRIX_PRODUCT_STATE

tensornet-mps. Adecuado para circuitos largos con bajo entrelazamiento.

CPU

cpu. Fuerza la ejecución en CPU. Útil principalmente para benchmarking.

Defina el método en el momento de la construcción:

from qilisdk.backends import CudaqBackend, CudaqSamplingMethod

backend = CudaqBackend(sampling_method=CudaqSamplingMethod.MATRIX_PRODUCT_STATE)

Algunos métodos de simulación de CUDA admiten configurar parámetros mediante variables de entorno, en particular los métodos MATRIX_PRODUCT_STATE y TENSOR_NETWORK. Consulte la documentación de CUDA-Q para más detalles.

Para establecer la precisión de la simulación, utilice el objeto Settings:

from qilisdk.settings import get_settings, Precision

settings = get_settings()
settings.complex_precision = Precision.COMPLEX_64  # or COMPLEX_32

Soporte de modelos de ruido

Puede pasarse un NoiseModel a CudaqBackend(noise_model=…):

  • Para DigitalPropagation, los canales de ruido de qilisdk se traducen a un cudaq.NoiseModel (canales de Kraus para ruido estático o derivado del tiempo, perturbaciones de parámetros aplicadas al circuito). Con ruido activado, solo se admite una única SamplingReadout.

  • Para AnalogEvolution, los canales de ruido compatibles con Lindblad se convierten en operadores de salto de CUDA-Q y en deltas del Hamiltoniano que se pasan a cudaq.evolve.

  • Para QuantumReservoir, la implementación de fallback descarta el modelo de ruido (se emite un aviso en el log).

Ejemplo: un canal despolarizador aplicado a cada puerta de un circuito digital:

from qilisdk.backends import CudaqBackend, CudaqSamplingMethod
from qilisdk.noise import NoiseModel, Depolarizing

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

backend = CudaqBackend(
    sampling_method=CudaqSamplingMethod.STATE_VECTOR,
    noise_model=nm,
)