Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
10140ab
sketch docs realtime decoding
kvmto Nov 6, 2025
0d8f8f3
fattened up docs realtime decoding
kvmto Nov 7, 2025
a3bbf3b
updates docs realtime decoding
kvmto Nov 11, 2025
a98704c
Merge remote-tracking branch 'upstream/main' into realtime_docs
kvmto Nov 11, 2025
7facddf
further polishing docs realtime decoding, added section on compilatio…
kvmto Nov 11, 2025
1cf7616
APIs and text done. TODO: code examples
kvmto Nov 12, 2025
ddd5528
Update docs/sphinx/examples_rst/qec/realtime_decoding.rst
kvmto Nov 14, 2025
df28b92
Update docs/sphinx/examples_rst/qec/realtime_decoding.rst
kvmto Nov 14, 2025
91b951c
Update docs/sphinx/examples_rst/qec/realtime_decoding.rst
kvmto Nov 14, 2025
ec1cf60
Update docs/sphinx/examples_rst/qec/realtime_decoding.rst
kvmto Nov 14, 2025
91f8a0a
fixed tone consistency TODO: code examples
kvmto Nov 14, 2025
a280c12
comments from Ben TODO: new followup PR, code examples
kvmto Nov 14, 2025
b2e47f9
comments from Melody TODO: new followup PR, code examples
kvmto Nov 14, 2025
5f92ae5
basic code examples
kvmto Nov 14, 2025
6648209
code examples fixed and integrated
kvmto Nov 14, 2025
2766097
Merge branch 'main' into realtime_docs
bmhowe23 Nov 14, 2025
3dd0130
C++ CI updates
bmhowe23 Nov 14, 2025
b3ab3e5
clang-format
bmhowe23 Nov 14, 2025
98b72e7
Python syntax fixes
bmhowe23 Nov 14, 2025
776f032
Use cudaq.run for Python example
bmhowe23 Nov 14, 2025
adad9bc
Machine name updates
bmhowe23 Nov 14, 2025
552c600
Additional noets about the Helios machines
bmhowe23 Nov 14, 2025
80ee1b5
Add note about noise-free sample data with emulate
bmhowe23 Nov 14, 2025
50adf2f
Fix rendering
bmhowe23 Nov 14, 2025
fc4efab
Use existing Doxygen docs rather than duplicating
bmhowe23 Nov 14, 2025
61575d2
More usage of existing Doxygen docs, and fix link
bmhowe23 Nov 15, 2025
ee6cd7b
Library name corrections
bmhowe23 Nov 15, 2025
276e0ef
Remove unnecessary formatting changes that would cause merge conflict…
bmhowe23 Nov 15, 2025
361ebc6
Add some Python API and fix rendering
bmhowe23 Nov 15, 2025
c4676be
Clarify why to reset the decoder
bmhowe23 Nov 15, 2025
1694a29
Revert "Remove unnecessary formatting changes that would cause merge …
bmhowe23 Nov 15, 2025
024bef9
DCO Remediation Commit for Ben Howe <bhowe@nvidia.com>
bmhowe23 Nov 15, 2025
cdc8377
Add decoder table to pre-built decoder section
bmhowe23 Nov 15, 2025
8913fb3
Clarification
bmhowe23 Nov 15, 2025
a8a9395
Change H-Series to Helios
bmhowe23 Nov 15, 2025
abd874b
Misc cleanup
bmhowe23 Nov 15, 2025
f9535fd
Rework the Compilation and Execution Examples section
bmhowe23 Nov 15, 2025
04e395c
expanded realtime intro
justinlietz Nov 17, 2025
6200cfc
Merge branch 'main' into realtime_docs
bmhowe23 Nov 17, 2025
1cd68db
Update docs/sphinx/components/qec/introduction.rst
justinlietz Nov 17, 2025
937e5dc
Update docs/sphinx/components/qec/introduction.rst
justinlietz Nov 17, 2025
d36a293
Update docs/sphinx/components/qec/introduction.rst
justinlietz Nov 17, 2025
4d0f3ab
Update docs/sphinx/components/qec/introduction.rst
justinlietz Nov 17, 2025
5529198
updating realtime docs
justinlietz Nov 18, 2025
3105ce2
Merge branch 'main' into realtime_docs
bmhowe23 Nov 18, 2025
92ebdf3
Apply suggestion from review
bmhowe23 Nov 18, 2025
1c040d1
Merge branch 'main' into realtime_docs
bmhowe23 Nov 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ EXTRACT_STATIC = YES
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = "__qpu__="
PREDEFINED = "__qpu__=" \
"__attribute__(x)="

#---------------------------------------------------------------------------
# Configuration options related to the HTML output
Expand Down
11 changes: 11 additions & 0 deletions docs/sphinx/api/qec/cpp_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,27 @@ Sliding Window Decoder

.. include:: sliding_window_api.rst

Real-Time Decoding
==================

.. include:: cpp_realtime_decoding_api.rst

.. _parity_check_matrix_utilities:

Parity Check Matrix Utilities
=============================

.. doxygenfunction:: cudaq::qec::dense_to_sparse(const cudaqx::tensor<uint8_t> &)
.. doxygenfunction:: cudaq::qec::generate_random_pcm(std::size_t, std::size_t, std::size_t, int, std::mt19937_64 &&);
.. 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)
.. 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)
.. doxygenfunction:: cudaq::qec::get_pcm_for_rounds(const cudaqx::tensor<uint8_t> &, std::uint32_t, std::uint32_t, std::uint32_t, bool, bool);
.. doxygenfunction:: cudaq::qec::get_sorted_pcm_column_indices(const std::vector<std::vector<std::uint32_t>> &, std::uint32_t);
.. doxygenfunction:: cudaq::qec::get_sorted_pcm_column_indices(const cudaqx::tensor<uint8_t> &, std::uint32_t);
.. doxygenfunction:: cudaq::qec::pcm_extend_to_n_rounds(const cudaqx::tensor<uint8_t> &, std::size_t, std::uint32_t);
.. 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)
.. doxygenfunction:: cudaq::qec::pcm_is_sorted(const cudaqx::tensor<uint8_t> &, std::uint32_t);
.. doxygenfunction:: cudaq::qec::pcm_to_sparse_vec(const cudaqx::tensor<uint8_t>& pcm)
.. doxygenfunction:: cudaq::qec::reorder_pcm_columns(const cudaqx::tensor<uint8_t> &, const std::vector<std::uint32_t> &, uint32_t, uint32_t);
.. doxygenfunction:: cudaq::qec::shuffle_pcm_columns(const cudaqx::tensor<uint8_t> &, std::mt19937_64 &&);
.. doxygenfunction:: cudaq::qec::simplify_pcm(const cudaqx::tensor<uint8_t> &, const std::vector<double> &, std::uint32_t);
Expand Down
53 changes: 53 additions & 0 deletions docs/sphinx/api/qec/cpp_realtime_decoding_api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.. _cpp_realtime_decoding_api:


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.

The real-time decoding system supports simulation environments for local testing and hardware integration (e.g., on
`Quantinuum's Helios QPU
<https://www.quantinuum.com/products-solutions/quantinuum-systems/helios>`_).

Core Decoding Functions
------------------------

These functions can be called from within CUDA-Q quantum kernels (``__qpu__`` functions) to interact with real-time decoders.

.. doxygenfunction:: cudaq::qec::decoding::enqueue_syndromes
.. doxygenfunction:: cudaq::qec::decoding::get_corrections
.. doxygenfunction:: cudaq::qec::decoding::reset_decoder


Configuration API
-----------------

The configuration API enables setting up decoders before circuit execution. Decoders are configured using YAML files or programmatically constructed configuration objects.

.. doxygenfunction:: cudaq::qec::decoding::config::configure_decoders
.. doxygenfunction:: cudaq::qec::decoding::config::configure_decoders_from_file
.. doxygenfunction:: cudaq::qec::decoding::config::configure_decoders_from_str
.. doxygenfunction:: cudaq::qec::decoding::config::finalize_decoders

Helper Functions
----------------

Real-time decoding requires converting matrices to sparse format for efficient decoder configuration. The following utility functions are essential:

- :cpp:func:`cudaq::qec::pcm_to_sparse_vec` for converting a dense PCM to a sparse PCM.

**Usage in real-time decoding:**

.. code-block:: cpp

config.H_sparse = cudaq::qec::pcm_to_sparse_vec(dem.detector_error_matrix);
config.O_sparse = cudaq::qec::pcm_to_sparse_vec(dem.observables_flips_matrix);
- :cpp:func:`cudaq::qec::pcm_from_sparse_vec` for converting a sparse PCM to a dense PCM.
- :cpp:func:`cudaq::qec::generate_timelike_sparse_detector_matrix` for generating a sparse detector matrix.

**Usage in real-time decoding:**

.. code-block:: cpp

config.D_sparse = cudaq::qec::generate_timelike_sparse_detector_matrix(
numSyndromesPerRound, numRounds, false);

See also :ref:`parity_check_matrix_utilities` for additional PCM manipulation functions.
9 changes: 8 additions & 1 deletion docs/sphinx/api/qec/python_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ Tensor Network Decoder

.. include:: tensor_network_decoder_api.rst

Real-Time Decoding
==================

.. include:: python_realtime_decoding_api.rst


Common
=============
Expand All @@ -60,13 +65,15 @@ Common
.. autofunction:: cudaq_qec.sample_code_capacity

Parity Check Matrix Utilities
-------------
=============================

.. autofunction:: cudaq_qec.generate_random_pcm
.. autofunction:: cudaq_qec.generate_timelike_sparse_detector_matrix
.. autofunction:: cudaq_qec.get_pcm_for_rounds
.. autofunction:: cudaq_qec.get_sorted_pcm_column_indices
.. autofunction:: cudaq_qec.pcm_extend_to_n_rounds
.. autofunction:: cudaq_qec.pcm_is_sorted
.. autofunction:: cudaq_qec.pcm_to_sparse_vec
.. autofunction:: cudaq_qec.reorder_pcm_columns
.. autofunction:: cudaq_qec.shuffle_pcm_columns
.. autofunction:: cudaq_qec.simplify_pcm
Expand Down
144 changes: 144 additions & 0 deletions docs/sphinx/api/qec/python_realtime_decoding_api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
.. _python_realtime_decoding_api:


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.

The real-time decoding system supports simulation environments for local testing and hardware integration (e.g., on
`Quantinuum's Helios QPU
<https://www.quantinuum.com/products-solutions/quantinuum-systems/helios>`_).

Core Decoding Functions
------------------------

These functions can be called from within CUDA-Q quantum kernels (``@cudaq.kernel`` decorated functions) to interact with real-time decoders.

.. py:function:: cudaq_qec.qec.enqueue_syndromes(decoder_id, syndromes, tag=0)

Enqueue syndrome measurements for decoding.

:param decoder_id: Unique identifier for the decoder instance (matches configured decoder ID)
:param syndromes: List of syndrome measurement results from stabilizer measurements
:param tag: Optional tag for logging and debugging (default: 0)

**Example:**

.. code-block:: python

import cudaq
import cudaq_qec as qec
from cudaq_qec import patch

@cudaq.kernel
def measure_and_decode(logical: patch, decoder_id: int):
syndromes = measure_stabilizers(logical)
qec.enqueue_syndromes(decoder_id, syndromes, 0)

.. py:function:: cudaq_qec.qec.get_corrections(decoder_id, return_size, reset=False)

Retrieve calculated corrections from the decoder.

:param decoder_id: Unique identifier for the decoder instance
:param return_size: Number of correction bits to return (typically equals number of logical observables)
:param reset: Whether to reset accumulated corrections after retrieval (default: False)
:returns: List of boolean values indicating detected bit flips for each logical observable

**Example:**

.. code-block:: python

@cudaq.kernel
def apply_corrections(logical: patch, decoder_id: int):
corrections = qec.get_corrections(decoder_id, 1, False)
if corrections[0]:
x(logical.data) # Apply transversal X correction

.. py:function:: cudaq_qec.qec.reset_decoder(decoder_id)

Reset decoder state, clearing all queued syndromes and accumulated corrections.

:param decoder_id: Unique identifier for the decoder instance to reset

**Example:**

.. code-block:: python

@cudaq.kernel
def run_experiment(decoder_id: int):
qec.reset_decoder(decoder_id) # Reset at start of each shot
# ... perform experiment ...

Configuration API
-----------------

The configuration API enables setting up decoders before circuit execution. Decoders are configured using YAML files or programmatically constructed configuration objects.

.. py:function:: cudaq_qec.configure_decoders(config)

Configure decoders from a multi_decoder_config object.

:param config: multi_decoder_config object containing decoder specifications
:returns: 0 on success, non-zero error code on failure

.. py:function:: cudaq_qec.configure_decoders_from_file(config_file)

Configure decoders from a YAML file.

:param config_file: Path to YAML configuration file
:returns: 0 on success, non-zero error code on failure

.. py:function:: cudaq_qec.configure_decoders_from_str(config_str)

Configure decoders from a YAML string.

:param config_str: YAML configuration as a string
:returns: 0 on success, non-zero error code on failure

.. py:function:: cudaq_qec.finalize_decoders()

Finalize and clean up decoder resources. Should be called before program exit.

Helper Functions
----------------

Real-time decoding requires converting matrices to sparse format for efficient decoder configuration. The following utility functions are essential:

.. py:function:: cudaq_qec.pcm_to_sparse_vec(pcm)

Convert a parity check matrix (PCM) to sparse vector representation for decoder configuration.

:param pcm: Dense binary matrix as numpy array (e.g., ``dem.detector_error_matrix`` or ``dem.observables_flips_matrix``)
:returns: Sparse vector (list of integers) where -1 separates rows

**Usage in real-time decoding:**

.. code-block:: python

config.H_sparse = qec.pcm_to_sparse_vec(dem.detector_error_matrix)
config.O_sparse = qec.pcm_to_sparse_vec(dem.observables_flips_matrix)

.. py:function:: cudaq_qec.pcm_from_sparse_vec(sparse_vec, num_rows, num_cols)

Convert sparse vector representation back to a dense parity check matrix.

:param sparse_vec: Sparse representation (from YAML or decoder config)
:param num_rows: Number of rows in the output matrix
:param num_cols: Number of columns in the output matrix
:returns: Dense binary matrix as numpy array

.. py:function:: cudaq_qec.generate_timelike_sparse_detector_matrix(num_syndromes_per_round, num_rounds, include_first_round)

Generate the D_sparse matrix that encodes how detectors relate across syndrome measurement rounds.

:param num_syndromes_per_round: Number of syndrome measurements per round (typically code distance squared)
:param num_rounds: Total number of syndrome measurement rounds
:param include_first_round: Boolean (False for standard memory experiments) or list for custom first round
:returns: Sparse matrix encoding detector relationships

**Usage in real-time decoding:**

.. code-block:: python

config.D_sparse = qec.generate_timelike_sparse_detector_matrix(
numSyndromesPerRound, numRounds, False)

See also :ref:`Parity Check Matrix Utilities <python_api:Parity Check Matrix Utilities>` for additional PCM manipulation functions.
Loading