CUDA-Q QEC Python API
Code
- class cudaq_qec.Code
Represents a quantum error correction code
- get_observables_x(self: cudaq_qec.Code) numpy.ndarray[numpy.uint8]
Get the Pauli X observables of the code
- get_observables_z(self: cudaq_qec.Code) numpy.ndarray[numpy.uint8]
Get the Pauli Z observables of the code
- get_parity(self: cudaq_qec.Code) numpy.ndarray[numpy.uint8]
Get the parity check matrix of the code
- get_parity_x(self: cudaq_qec.Code) numpy.ndarray[numpy.uint8]
Get the X-type parity check matrix of the code
- get_parity_z(self: cudaq_qec.Code) numpy.ndarray[numpy.uint8]
Get the Z-type parity check matrix of the code
- get_pauli_observables_matrix(self: cudaq_qec.Code) numpy.ndarray[numpy.uint8]
Get a matrix of the Pauli observables of the code
- get_stabilizers(self: cudaq_qec.Code) list[SpinOperator]
Get the stabilizer generators of the code
Decoder Interfaces
- class cudaq_qec.Decoder
Represents a decoder for quantum error correction
- decode(self: cudaq_qec.Decoder, syndrome: list[float]) cudaq_qec.DecoderResult
Decode the given syndrome to determine the error correction
- decode_async(self: cudaq_qec.Decoder, syndrome: list[float]) cudaq_qec.AsyncDecoderResult
Asynchronously decode the given syndrome
- decode_batch(self: cudaq_qec.Decoder, syndrome: list[list[float]]) list[cudaq_qec.DecoderResult]
Decode multiple syndromes and return the results
- get_block_size(self: cudaq_qec.Decoder) int
Get the size of the code block
- get_syndrome_size(self: cudaq_qec.Decoder) int
Get the size of the syndrome
- class cudaq_qec.DecoderResult
A class representing the results of a quantum error correction decoding operation.
This class encapsulates both the convergence status and the actual decoding result.
- property converged
Boolean flag indicating if the decoder converged to a solution.
True if the decoder successfully found a valid correction chain, False if the decoder failed to converge or exceeded iteration limits.
- property result
The decoded correction chain or recovery operation.
Contains the sequence of corrections that should be applied to recover the original quantum state. The format depends on the specific decoder implementation.
Built-in Decoders
NVIDIA QLDPC Decoder
- class cudaq_qec.nv_qldpc_decoder
A general purpose Quantum Low-Density Parity-Check Decoder (QLDPC) decoder based on GPU accelerated belief propagation (BP). Since belief propagation is an iterative method, decoding can be improved with a second-stage post-processing step. Optionally, ordered statistics decoding (OSD) can be chosen to perform the second stage of decoding.
An [[n,k,d]] quantum error correction (QEC) code encodes k logical qubits into an n qubit data block, with a code distance d. Quantum low-density parity-check (QLDPC) codes are characterized by sparse parity-check matrices (or Tanner graphs), corresponding to a bounded number of parity checks per data qubit.
Requires a CUDA-Q compatible GPU. See the CUDA-Q GPU Compatibility List for a list of valid GPU configurations.
References: Decoding Across the Quantum LDPC Code Landscape
Note
It is required to create decoders with the
get_decoder
API from the CUDA-QX extension points API, such asimport cudaq_qec as qec import numpy as np H = np.array([[1, 0, 0, 1, 0, 1, 1], [0, 1, 0, 1, 1, 0, 1], [0, 0, 1, 0, 1, 1, 1]], dtype=np.uint8) # sample 3x7 PCM opts = dict() # see below for options # Note: H must be in row-major order. If you use # `scipy.sparse.csr_matrix.todense()` to get the parity check # matrix, you must specify todense(order='C') to get a row-major # matrix. nvdec = qec.get_decoder('nv-qldpc-decoder', H, **opts)
std::size_t block_size = 7; std::size_t syndrome_size = 3; cudaqx::tensor<uint8_t> H; std::vector<uint8_t> H_vec = {1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1}; H.copy(H_vec.data(), {syndrome_size, block_size}); cudaqx::heterogeneous_map nv_custom_args; nv_custom_args.insert("use_osd", true); // See below for options auto nvdec = cudaq::qec::get_decoder("nv-qldpc-decoder", H, nv_custom_args);
Note
The
"nv-qldpc-decoder"
implements thecudaq_qec.Decoder
interface for Python and thecudaq::qec::decoder
interface for C++, so it supports all the methods in those respective classes.- Parameters:
H – Parity check matrix (tensor format)
params –
Heterogeneous map of parameters:
use_sparsity
(bool): Whether or not to use a sparse matrix solvererror_rate
(double): Probability of an error (in 0-1 range) on a block data bit (defaults to 0.001)error_rate_vec
(double): Vector of length “block size” containing the probability of an error (in 0-1 range) on a block data bit (defaults to 0.001). This overrideserror_rate
.max_iterations
(int): Maximum number of BP iterations to perform (defaults to 30)n_threads
(int): Number of CUDA threads to use for the GPU decoder (defaults to smart selection based on parity matrix size)use_osd
(bool): Whether or not to use an OSD post processor if the initial BP algorithm fails to converge on a solutionosd_method
(int): 1=OSD-0, 2=Exhaustive, 3=Combination Sweep (defaults to 1). Ignored unlessuse_osd
is true.osd_order
(int): OSD postprocessor order (defaults to 0). Ref: Decoding Across the Quantum LDPC Code LandscapeFor
osd_method=2
(Exhaustive), the number of possible permutations searched after OSD-0 grows by 2^osd_order.For
osd_method=3
(Combination Sweep), this is the λ parameter. All weight 1 permutations and the first λ bits worth of weight 2 permutations are searched after OSD-0. This is (syndrome_length - block_size + λ * (λ - 1) / 2) additional permutations.For other
osd_method
values, this is ignored.
bp_batch_size
(int): Number of syndromes that will be decoded in parallel for the BP decoder (defaults to 1)osd_batch_size
(int): Number of syndromes that will be decoded in parallel for OSD (defaults to the number of concurrent threads supported by the hardware)
Common
- cudaq_qec.sample_memory_circuit(*args, **kwargs)
Overloaded function.
sample_memory_circuit(code: cudaq_qec.Code, numShots: int, numRounds: int, noise: Optional[cudaq.NoiseModel] = None) -> tuple
Sample the memory circuit of the code
sample_memory_circuit(code: cudaq_qec.Code, op: cudaq_qec.operation, numShots: int, numRounds: int, noise: Optional[cudaq.NoiseModel] = None) -> tuple
Sample the memory circuit of the code with a specific initial operation
- cudaq_qec.sample_code_capacity(*args, **kwargs)
Overloaded function.
sample_code_capacity(code: cudaq_qec.Code, numShots: int, errorProb: float, seed: Optional[int] = None) -> tuple
Sample syndrome measurements with code capacity noise.
sample_code_capacity(H: numpy.ndarray[numpy.uint8], numShots: int, errorProb: float, seed: Optional[int] = None) -> tuple
Sample syndrome measurements with code capacity noise.