Skip to content

Commit c34e6ae

Browse files
authored
Merge branch 'main' into train_trt_decoder_docs
2 parents 5f2e4b1 + ceb2923 commit c34e6ae

File tree

14 files changed

+1204
-12
lines changed

14 files changed

+1204
-12
lines changed

docs/Doxyfile.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ EXTRACT_STATIC = YES
2727
ENABLE_PREPROCESSING = YES
2828
MACRO_EXPANSION = YES
2929
EXPAND_ONLY_PREDEF = YES
30-
PREDEFINED = "__qpu__="
30+
PREDEFINED = "__qpu__=" \
31+
"__attribute__(x)="
3132

3233
#---------------------------------------------------------------------------
3334
# Configuration options related to the HTML output

docs/sphinx/api/qec/cpp_api.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,27 @@ Sliding Window Decoder
5656

5757
.. include:: sliding_window_api.rst
5858

59+
Real-Time Decoding
60+
==================
61+
62+
.. include:: cpp_realtime_decoding_api.rst
63+
64+
.. _parity_check_matrix_utilities:
65+
5966
Parity Check Matrix Utilities
6067
=============================
6168

6269
.. doxygenfunction:: cudaq::qec::dense_to_sparse(const cudaqx::tensor<uint8_t> &)
6370
.. doxygenfunction:: cudaq::qec::generate_random_pcm(std::size_t, std::size_t, std::size_t, int, std::mt19937_64 &&);
71+
.. doxygenfunction:: cudaq::qec::generate_timelike_sparse_detector_matrix(std::uint32_t num_syndromes_per_round, std::uint32_t num_rounds, bool include_first_round = false)
72+
.. doxygenfunction:: cudaq::qec::generate_timelike_sparse_detector_matrix(std::uint32_t num_syndromes_per_round, std::uint32_t num_rounds, std::vector<std::int64_t> first_round_matrix)
6473
.. doxygenfunction:: cudaq::qec::get_pcm_for_rounds(const cudaqx::tensor<uint8_t> &, std::uint32_t, std::uint32_t, std::uint32_t, bool, bool);
6574
.. doxygenfunction:: cudaq::qec::get_sorted_pcm_column_indices(const std::vector<std::vector<std::uint32_t>> &, std::uint32_t);
6675
.. doxygenfunction:: cudaq::qec::get_sorted_pcm_column_indices(const cudaqx::tensor<uint8_t> &, std::uint32_t);
6776
.. doxygenfunction:: cudaq::qec::pcm_extend_to_n_rounds(const cudaqx::tensor<uint8_t> &, std::size_t, std::uint32_t);
77+
.. doxygenfunction:: cudaq::qec::pcm_from_sparse_vec(const std::vector<std::int64_t>& sparse_vec, std::size_t num_rows, std::size_t num_cols)
6878
.. doxygenfunction:: cudaq::qec::pcm_is_sorted(const cudaqx::tensor<uint8_t> &, std::uint32_t);
79+
.. doxygenfunction:: cudaq::qec::pcm_to_sparse_vec(const cudaqx::tensor<uint8_t>& pcm)
6980
.. doxygenfunction:: cudaq::qec::reorder_pcm_columns(const cudaqx::tensor<uint8_t> &, const std::vector<std::uint32_t> &, uint32_t, uint32_t);
7081
.. doxygenfunction:: cudaq::qec::shuffle_pcm_columns(const cudaqx::tensor<uint8_t> &, std::mt19937_64 &&);
7182
.. doxygenfunction:: cudaq::qec::simplify_pcm(const cudaqx::tensor<uint8_t> &, const std::vector<double> &, std::uint32_t);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
.. _cpp_realtime_decoding_api:
2+
3+
4+
The Real-Time Decoding API enables low-latency error correction on quantum hardware by allowing CUDA-Q quantum kernels to interact with decoders during circuit execution. This API is designed for use cases where corrections must be calculated and applied within qubit coherence times.
5+
6+
The real-time decoding system supports simulation environments for local testing and hardware integration (e.g., on
7+
`Quantinuum's Helios QPU
8+
<https://www.quantinuum.com/products-solutions/quantinuum-systems/helios>`_).
9+
10+
Core Decoding Functions
11+
------------------------
12+
13+
These functions can be called from within CUDA-Q quantum kernels (``__qpu__`` functions) to interact with real-time decoders.
14+
15+
.. doxygenfunction:: cudaq::qec::decoding::enqueue_syndromes
16+
.. doxygenfunction:: cudaq::qec::decoding::get_corrections
17+
.. doxygenfunction:: cudaq::qec::decoding::reset_decoder
18+
19+
20+
Configuration API
21+
-----------------
22+
23+
The configuration API enables setting up decoders before circuit execution. Decoders are configured using YAML files or programmatically constructed configuration objects.
24+
25+
.. doxygenfunction:: cudaq::qec::decoding::config::configure_decoders
26+
.. doxygenfunction:: cudaq::qec::decoding::config::configure_decoders_from_file
27+
.. doxygenfunction:: cudaq::qec::decoding::config::configure_decoders_from_str
28+
.. doxygenfunction:: cudaq::qec::decoding::config::finalize_decoders
29+
30+
Helper Functions
31+
----------------
32+
33+
Real-time decoding requires converting matrices to sparse format for efficient decoder configuration. The following utility functions are essential:
34+
35+
- :cpp:func:`cudaq::qec::pcm_to_sparse_vec` for converting a dense PCM to a sparse PCM.
36+
37+
**Usage in real-time decoding:**
38+
39+
.. code-block:: cpp
40+
41+
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(dem.detector_error_matrix);
42+
config.O_sparse = cudaq::qec::pcm_to_sparse_vec(dem.observables_flips_matrix);
43+
- :cpp:func:`cudaq::qec::pcm_from_sparse_vec` for converting a sparse PCM to a dense PCM.
44+
- :cpp:func:`cudaq::qec::generate_timelike_sparse_detector_matrix` for generating a sparse detector matrix.
45+
46+
**Usage in real-time decoding:**
47+
48+
.. code-block:: cpp
49+
50+
config.D_sparse = cudaq::qec::generate_timelike_sparse_detector_matrix(
51+
numSyndromesPerRound, numRounds, false);
52+
53+
See also :ref:`parity_check_matrix_utilities` for additional PCM manipulation functions.

docs/sphinx/api/qec/python_api.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ Tensor Network Decoder
5151

5252
.. include:: tensor_network_decoder_api.rst
5353

54+
Real-Time Decoding
55+
==================
56+
57+
.. include:: python_realtime_decoding_api.rst
58+
5459

5560
Common
5661
=============
@@ -60,13 +65,15 @@ Common
6065
.. autofunction:: cudaq_qec.sample_code_capacity
6166

6267
Parity Check Matrix Utilities
63-
-------------
68+
=============================
6469

6570
.. autofunction:: cudaq_qec.generate_random_pcm
71+
.. autofunction:: cudaq_qec.generate_timelike_sparse_detector_matrix
6672
.. autofunction:: cudaq_qec.get_pcm_for_rounds
6773
.. autofunction:: cudaq_qec.get_sorted_pcm_column_indices
6874
.. autofunction:: cudaq_qec.pcm_extend_to_n_rounds
6975
.. autofunction:: cudaq_qec.pcm_is_sorted
76+
.. autofunction:: cudaq_qec.pcm_to_sparse_vec
7077
.. autofunction:: cudaq_qec.reorder_pcm_columns
7178
.. autofunction:: cudaq_qec.shuffle_pcm_columns
7279
.. autofunction:: cudaq_qec.simplify_pcm
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
.. _python_realtime_decoding_api:
2+
3+
4+
The Real-Time Decoding API enables low-latency error correction on quantum hardware by allowing CUDA-Q quantum kernels to interact with decoders during circuit execution. This API is designed for use cases where corrections must be calculated and applied within qubit coherence times.
5+
6+
The real-time decoding system supports simulation environments for local testing and hardware integration (e.g., on
7+
`Quantinuum's Helios QPU
8+
<https://www.quantinuum.com/products-solutions/quantinuum-systems/helios>`_).
9+
10+
Core Decoding Functions
11+
------------------------
12+
13+
These functions can be called from within CUDA-Q quantum kernels (``@cudaq.kernel`` decorated functions) to interact with real-time decoders.
14+
15+
.. py:function:: cudaq_qec.qec.enqueue_syndromes(decoder_id, syndromes, tag=0)
16+
17+
Enqueue syndrome measurements for decoding.
18+
19+
:param decoder_id: Unique identifier for the decoder instance (matches configured decoder ID)
20+
:param syndromes: List of syndrome measurement results from stabilizer measurements
21+
:param tag: Optional tag for logging and debugging (default: 0)
22+
23+
**Example:**
24+
25+
.. code-block:: python
26+
27+
import cudaq
28+
import cudaq_qec as qec
29+
from cudaq_qec import patch
30+
31+
@cudaq.kernel
32+
def measure_and_decode(logical: patch, decoder_id: int):
33+
syndromes = measure_stabilizers(logical)
34+
qec.enqueue_syndromes(decoder_id, syndromes, 0)
35+
36+
.. py:function:: cudaq_qec.qec.get_corrections(decoder_id, return_size, reset=False)
37+
38+
Retrieve calculated corrections from the decoder.
39+
40+
:param decoder_id: Unique identifier for the decoder instance
41+
:param return_size: Number of correction bits to return (typically equals number of logical observables)
42+
:param reset: Whether to reset accumulated corrections after retrieval (default: False)
43+
:returns: List of boolean values indicating detected bit flips for each logical observable
44+
45+
**Example:**
46+
47+
.. code-block:: python
48+
49+
@cudaq.kernel
50+
def apply_corrections(logical: patch, decoder_id: int):
51+
corrections = qec.get_corrections(decoder_id, 1, False)
52+
if corrections[0]:
53+
x(logical.data) # Apply transversal X correction
54+
55+
.. py:function:: cudaq_qec.qec.reset_decoder(decoder_id)
56+
57+
Reset decoder state, clearing all queued syndromes and accumulated corrections.
58+
59+
:param decoder_id: Unique identifier for the decoder instance to reset
60+
61+
**Example:**
62+
63+
.. code-block:: python
64+
65+
@cudaq.kernel
66+
def run_experiment(decoder_id: int):
67+
qec.reset_decoder(decoder_id) # Reset at start of each shot
68+
# ... perform experiment ...
69+
70+
Configuration API
71+
-----------------
72+
73+
The configuration API enables setting up decoders before circuit execution. Decoders are configured using YAML files or programmatically constructed configuration objects.
74+
75+
.. py:function:: cudaq_qec.configure_decoders(config)
76+
77+
Configure decoders from a multi_decoder_config object.
78+
79+
:param config: multi_decoder_config object containing decoder specifications
80+
:returns: 0 on success, non-zero error code on failure
81+
82+
.. py:function:: cudaq_qec.configure_decoders_from_file(config_file)
83+
84+
Configure decoders from a YAML file.
85+
86+
:param config_file: Path to YAML configuration file
87+
:returns: 0 on success, non-zero error code on failure
88+
89+
.. py:function:: cudaq_qec.configure_decoders_from_str(config_str)
90+
91+
Configure decoders from a YAML string.
92+
93+
:param config_str: YAML configuration as a string
94+
:returns: 0 on success, non-zero error code on failure
95+
96+
.. py:function:: cudaq_qec.finalize_decoders()
97+
98+
Finalize and clean up decoder resources. Should be called before program exit.
99+
100+
Helper Functions
101+
----------------
102+
103+
Real-time decoding requires converting matrices to sparse format for efficient decoder configuration. The following utility functions are essential:
104+
105+
.. py:function:: cudaq_qec.pcm_to_sparse_vec(pcm)
106+
107+
Convert a parity check matrix (PCM) to sparse vector representation for decoder configuration.
108+
109+
:param pcm: Dense binary matrix as numpy array (e.g., ``dem.detector_error_matrix`` or ``dem.observables_flips_matrix``)
110+
:returns: Sparse vector (list of integers) where -1 separates rows
111+
112+
**Usage in real-time decoding:**
113+
114+
.. code-block:: python
115+
116+
config.H_sparse = qec.pcm_to_sparse_vec(dem.detector_error_matrix)
117+
config.O_sparse = qec.pcm_to_sparse_vec(dem.observables_flips_matrix)
118+
119+
.. py:function:: cudaq_qec.pcm_from_sparse_vec(sparse_vec, num_rows, num_cols)
120+
121+
Convert sparse vector representation back to a dense parity check matrix.
122+
123+
:param sparse_vec: Sparse representation (from YAML or decoder config)
124+
:param num_rows: Number of rows in the output matrix
125+
:param num_cols: Number of columns in the output matrix
126+
:returns: Dense binary matrix as numpy array
127+
128+
.. py:function:: cudaq_qec.generate_timelike_sparse_detector_matrix(num_syndromes_per_round, num_rounds, include_first_round)
129+
130+
Generate the D_sparse matrix that encodes how detectors relate across syndrome measurement rounds.
131+
132+
:param num_syndromes_per_round: Number of syndrome measurements per round (typically code distance squared)
133+
:param num_rounds: Total number of syndrome measurement rounds
134+
:param include_first_round: Boolean (False for standard memory experiments) or list for custom first round
135+
:returns: Sparse matrix encoding detector relationships
136+
137+
**Usage in real-time decoding:**
138+
139+
.. code-block:: python
140+
141+
config.D_sparse = qec.generate_timelike_sparse_detector_matrix(
142+
numSyndromesPerRound, numRounds, False)
143+
144+
See also :ref:`Parity Check Matrix Utilities <python_api:Parity Check Matrix Utilities>` for additional PCM manipulation functions.

0 commit comments

Comments
 (0)