Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
c8331a2
qec/realtime: Relay BP (nv-qldpc) gpu_roce profile for the HSB decodi…
cketcham2333 Jul 10, 2026
0c426d0
Merge remote-tracking branch 'upstream/main' into add-relaybp-fpga
cketcham2333 Jul 10, 2026
b25778b
decoding-server-cqr: link CUDA::cuda_driver into the gpu_roce block
cketcham2333 Jul 10, 2026
d9cdf52
decoding-server-cqr: move GPU RoCE out of the core static lib
cketcham2333 Jul 10, 2026
5efaff8
Decoding server: load transports as CUDA-Q bridge providers
bmhowe23 Jul 11, 2026
332ef5d
GpuRoceTransceiver: consume the Hololink bridge provider
bmhowe23 Jul 11, 2026
d949a1c
Merge branch 'pr670-head' into bmh/decoding-server-bridge-670
bmhowe23 Jul 11, 2026
d637d66
Rename the device-dispatch path to what it is: device_graph, not gpu_…
bmhowe23 Jul 11, 2026
ac0cb40
Remove pre-release compatibility aliases from the dispatch/transport …
bmhowe23 Jul 11, 2026
21831c5
docs: transport-provider design (before/after, contracts, reproductio…
bmhowe23 Jul 12, 2026
af8db8e
One ring buffer (and one dispatcher) per decoder, device_id == decode…
bmhowe23 Jul 12, 2026
878eee3
Decoding server: one ring per decoder across two processes
bmhowe23 Jul 12, 2026
4ba17aa
Mixed-dispatch decoding server: device_graph + host rings in one process
bmhowe23 Jul 12, 2026
21d0836
Transport section is server-level and shape-keyed, not per-decoder
bmhowe23 Jul 12, 2026
2065319
sc4 caller: per-decoder ring endpoints; record device-ring validation…
bmhowe23 Jul 12, 2026
d97157f
Refine WSL2 device-graph diagnosis: cudaErrorNotSupported at kernel l…
bmhowe23 Jul 12, 2026
f3fe16b
Correct the device-graph wedge diagnosis: probe was invalid, platform…
bmhowe23 Jul 12, 2026
e0ed435
docs: re-scope the realtime design docs into contracts / topology / log
bmhowe23 Jul 12, 2026
58e40c1
docs: deployment cookbook (sample YAML + launch lines per scenario)
bmhowe23 Jul 12, 2026
ecec808
Fix decode-graph co-residency wedge; full mixed E2E now passes locally
bmhowe23 Jul 12, 2026
65f16d9
Adopt the string-keyed bridge loader; drop the one-provider-per-proce…
bmhowe23 Jul 12, 2026
f4b19d4
Address self-review findings in the decoding server and CQR components
bmhowe23 Jul 12, 2026
b94767a
--transport is a fallback, never an override; test the YAML transport…
bmhowe23 Jul 12, 2026
e64f56f
Apply clang-format
bmhowe23 Jul 12, 2026
19dd816
docs: refresh the architecture diagram
bmhowe23 Jul 12, 2026
2229b85
Pin to custom CUDA-Q version
bmhowe23 Jul 12, 2026
9014dd9
Merge origin/main (PR 670 landed + 15 commits) into decoding-server b…
bmhowe23 Jul 15, 2026
71d1e68
Validation notes: post-merge revalidation of the per-decoder-rings stack
bmhowe23 Jul 15, 2026
c8e3da3
clang-format
bmhowe23 Jul 15, 2026
49eb8e1
Generalize the standalone device-graph transceiver for non-HSB providers
bmhowe23 Jul 15, 2026
07ce040
Bump cudaq version
bmhowe23 Jul 15, 2026
44bec3b
Add realtime_decoding_demo: drive the delivered decoding server from …
cketcham2333 Jul 16, 2026
798c82d
clang format
cketcham2333 Jul 16, 2026
11108a4
Merge remote-tracking branch 'upstream/main' into decoding_server_exa…
cketcham2333 Jul 17, 2026
ae3716b
Rebase realtime_decoding_demo onto the refactored surface_code-1 app
cketcham2333 Jul 17, 2026
4d770db
Merge remote-tracking branch 'upstream/main' into decoding_server_exa…
cketcham2333 Jul 17, 2026
143fe9a
Address review comments
cketcham2333 Jul 17, 2026
bcb21a2
Merge branch 'main' into bmh/decoding-server-bridge-670
bmhowe23 Jul 17, 2026
2e68bf1
Addressed additional review comments
cketcham2333 Jul 17, 2026
379f3d2
Merge remote-tracking branch 'bmhowe23/bmh/decoding-server-bridge-670…
cketcham2333 Jul 17, 2026
51e5862
Fix swallowed --device in DeviceGraphTransceiver's provider argv
cketcham2333 Jul 17, 2026
3344a15
Adapt realtime_decoding_demo + hsb driver to the bridge-provider server
cketcham2333 Jul 17, 2026
18d0ff0
Merge branch 'main' into bmh/decoding-server-bridge-670
bmhowe23 Jul 17, 2026
0f92f55
Fix swallowed --device in DeviceGraphTransceiver's provider argv
cketcham2333 Jul 17, 2026
0d6b2d1
Merge branch 'main' into bmh/decoding-server-bridge-670
bmhowe23 Jul 17, 2026
4f2343e
Add qpu-kernel-over-cpu_roce runs to the realtime decoding example
cketcham2333 Jul 17, 2026
c2a1bf0
Merge remote-tracking branch 'bmhowe23/bmh/decoding-server-bridge-670…
cketcham2333 Jul 17, 2026
03217c7
Add the Ising decoder (trt_decoder) profile to the realtime decoding …
cketcham2333 Jul 21, 2026
e139c40
clang format
cketcham2333 Jul 21, 2026
65a6820
Fix two FPGA-run footguns: nv-qldpc auto-pacing + bridge-ip subnet guard
cketcham2333 Jul 22, 2026
4bdea49
Merge remote-tracking branch 'upstream/main' into decoding_server_exa…
cketcham2333 Jul 24, 2026
5cd9751
FPGA runs: fix the hsb endpoint scrape; auto-pace slow decoders at 100us
cketcham2333 Jul 24, 2026
dba6725
realtime_decoding_demo: adopt the prepare_ising_artifacts.py workflow
cketcham2333 Jul 24, 2026
9d846a5
Remove unneeded documents left over from early PR 682 merge
cketcham2333 Jul 24, 2026
a8ffb2e
realtime_decoding_demo: code-review fixes (precedence, subnet guard, …
cketcham2333 Jul 25, 2026
92de54b
Address more review comments
cketcham2333 Aug 3, 2026
ae1383a
Merge remote-tracking branch 'upstream/main' into decoding_server_exa…
cketcham2333 Aug 3, 2026
921e4bb
Merge remote-tracking branch 'upstream/main' into decoding_server_exa…
cketcham2333 Aug 3, 2026
5bb0ffc
Fix semantic merge leftovers from the hololink->hsb rename (PR 754)
cketcham2333 Aug 3, 2026
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
31 changes: 31 additions & 0 deletions .github/workflows/lib_qec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,37 @@ jobs:
- name: Run example tests
run: bash scripts/ci/test_examples.sh qec

# ========================================================================
# Realtime decoding demo example
#
# Build the two example binaries against the INSTALLED SDK -- this is what
# enforces the installed-headers-only rule: a build-tree-only include
# would fail to compile here. Then drive the delivered decoding_server
# over UDP loopback with a real pymatching decode (the qpu-kernel source).
# No hardware: the FPGA source needs a ConnectX NIC and is not run in CI.
# ========================================================================
- name: Build & run realtime_decoding_demo (qpu-kernel, UDP loopback)
shell: bash
run: |
export PATH=/cudaq-install/bin:$PATH
# Mirror build_qec.sh: it builds+installs cudaq-realtime to
# $CUDAQ_REALTIME_ROOT, defaulting to /tmp/cudaq-realtime when unset
# (the case for this workflow). Track the same value so this step
# stays correct if the job ever sets CUDAQ_REALTIME_ROOT.
RT="${CUDAQ_REALTIME_ROOT:-/tmp/cudaq-realtime}"
EX=docs/sphinx/examples/qec/realtime_decoding_demo
cmake -S "$EX" -B /tmp/rtdemo-build -G Ninja \
-DCUDAQ_INSTALL_DIR=/cudaq-install \
-DCUDAQX_INSTALL_DIR="$HOME/.cudaqx" \
-DCUDAQ_REALTIME_DIR="$RT"
cmake --build /tmp/rtdemo-build -j
bash "$EX/run_realtime_decoding.sh" \
--source qpu-kernel --decoder pymatching \
--install-prefix "$HOME/.cudaqx" \
--cudaq-prefix /cudaq-install \
--realtime-lib-dir "$RT" \
--example-build-dir /tmp/rtdemo-build

# ========================================================================
# Upload build artifacts for GPU tests
# ========================================================================
Expand Down
6 changes: 5 additions & 1 deletion docs/sphinx/conf.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,13 @@ master_doc = 'index'
# This pattern also affects html_static_path and html_extra_path.
# Fragment files pulled in via ``.. include::`` must not also be processed as
# standalone documents — doing so causes duplicate C++ / Python domain
# declarations in the Sphinx domain registry.
# declarations in the Sphinx domain registry. Example-directory READMEs are
# for the shipped example tree (rendered on GitHub), not standalone doc pages
# -- without the exclusion they are ingested via the '.md' source suffix and
# warn as toctree orphans.
exclude_patterns = [
'_templates',
'examples/**/README.md',
'api/qec/nv_qldpc_decoder_api.rst',
'api/qec/sliding_window_api.rst',
'api/qec/trt_decoder_api.rst',
Expand Down
220 changes: 220 additions & 0 deletions docs/sphinx/examples/qec/realtime_decoding_demo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# ============================================================================ #
# Copyright (c) 2026 NVIDIA Corporation & Affiliates. #
# All rights reserved. #
# #
# This source code and the accompanying materials are made available under #
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

# Realtime-decoding example.
#
# This builds TWO sources, each two ways, against the *installed* CUDA-Q /
# CUDA-QX SDK -- nothing here reaches into a build tree:
#
# surface_code_realtime_decoding generator: --target stim; writes
# the decoder config + syndrome
# files (pymatching /
# multi_error_lut / nv-qldpc).
# surface_code_realtime_decoding-cqr lowered kernel: adds
# -frealtime-lowering -DQEC_APP_CQR;
# the live QPU kernel that streams
# syndromes to the delivered
# decoding_server.
# surface_code_ising_realtime_decoding generator for the Ising decoder
# profile (trt_decoder: TensorRT
# predecoder + PyMatching), built
# from the surface_code-4 lineage
# the Ising artifacts are bound to.
# surface_code_ising_realtime_decoding-cqr its lowered-kernel counterpart.
#
# The decoding_server and the FPGA playback tool are DELIVERABLES (installed,
# not built here); run_realtime_decoding.sh resolves them from --install-prefix.

cmake_minimum_required(VERSION 3.23)

# The lowered-kernel binary links the realtime dispatch archive (relocatable
# CUDA device code), so the project enables CUDA and needs an architecture for
# the device-link step. Default to 80 (A100) -- an architecture the shipped
# SDK's dispatch archive includes; override to match your GPU:
# -DCMAKE_CUDA_ARCHITECTURES=90 for Hopper, 100 for Blackwell (e.g. GB200).
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 80)
endif()

project(realtime_decoding_demo LANGUAGES CXX CUDA)

# ---------------------------------------------------------------------------- #
# Locate the installed SDK.
# ---------------------------------------------------------------------------- #
# CUDA-Q: provides nvq++, cudaq/*.h, cudaq/realtime.h and the core runtime libs.
if(NOT CUDAQ_INSTALL_DIR)
if(DEFINED ENV{CUDA_QUANTUM_PATH})
set(CUDAQ_INSTALL_DIR "$ENV{CUDA_QUANTUM_PATH}")
else()
set(CUDAQ_INSTALL_DIR "/usr/local/cudaq")
endif()
endif()
if(NOT EXISTS "${CUDAQ_INSTALL_DIR}/bin/nvq++")
message(FATAL_ERROR
"nvq++ not found under CUDAQ_INSTALL_DIR=${CUDAQ_INSTALL_DIR}. "
"Pass -DCUDAQ_INSTALL_DIR=<cuda-quantum install prefix>.")
endif()

# CUDA-QX: provides cudaq/qec/*.h and the QEC + realtime-decoding libs/plugins.
if(NOT CUDAQX_INSTALL_DIR)
if(DEFINED ENV{CUDAQX_INSTALL_DIR})
set(CUDAQX_INSTALL_DIR "$ENV{CUDAQX_INSTALL_DIR}")
else()
message(FATAL_ERROR
"Set -DCUDAQX_INSTALL_DIR=<cuda-qx install prefix> (the directory that "
"holds include/cudaq/qec and lib/libcudaq-qec.so).")
endif()
endif()
if(NOT EXISTS "${CUDAQX_INSTALL_DIR}/include/cudaq/qec/code.h")
message(FATAL_ERROR
"CUDAQX_INSTALL_DIR=${CUDAQX_INSTALL_DIR} does not look like a CUDA-QX "
"install (missing include/cudaq/qec/code.h).")
endif()

set(NVQPP "${CUDAQ_INSTALL_DIR}/bin/nvq++")
find_package(CUDAToolkit REQUIRED)

# The realtime dispatch archive carries relocatable (RDC) device code, so the
# -cqr executable must be linked with a CUDA device-link step (see below).
# The explicit realtime prefix is searched FIRST: when the user passes a
# separate CUDAQ_REALTIME_DIR they mean it to win over any copy the CUDA-Q
# install carries, or the build silently mixes realtime revisions.
find_library(CUDAQ_REALTIME_DISPATCH_LIB cudaq-realtime-dispatch
PATHS "${CUDAQ_REALTIME_DIR}" "${CUDAQ_INSTALL_DIR}" PATH_SUFFIXES lib REQUIRED)

link_directories(
"${CUDAQX_INSTALL_DIR}/lib"
"${CUDAQX_INSTALL_DIR}/lib/decoder-plugins"
"${CUDAQ_INSTALL_DIR}/lib"
"${CUDAQ_INSTALL_DIR}/lib/plugins")

set(_src "${CMAKE_CURRENT_SOURCE_DIR}/surface_code_realtime_decoding.cpp")
set(_ising_src
"${CMAKE_CURRENT_SOURCE_DIR}/surface_code_ising_realtime_decoding.cpp")

# Only the CUDA-QX headers need an explicit -I; nvq++ already knows its own
# CUDA-Q include dir (cudaq/*.h, cudaq/realtime.h, common/*.h).
set(_nvqpp_includes "-I${CUDAQX_INSTALL_DIR}/include")

# CUDA-Q core libraries, listed AFTER the qec + simulation libs on purpose.
# The simulation backend's static initializer registers into a global map owned
# by libcudaq-common; ELF runs initializers in reverse DT_NEEDED (link) order,
# so the qec/simulation libs must be listed FIRST (they initialize last) and the
# cudaq core libs LAST (they initialize first) or the registration dereferences
# a not-yet-constructed map and segfaults at startup.
set(_cudaq_core_libs
cudaq-mlir-runtime nvqir nvqir-stim
cudaq-qec-realtime-decoding cudaq-qec-decoders
cudaq cudaq-platform-default cudaq-em-default
cudaq-common cudaq-operator cudaq-logger)

# ---------------------------------------------------------------------------- #
# Helper: compile the source with nvq++ into an object, in an isolated working
# directory (nvq++ drops intermediates named after the source, so two compiles
# of the same file must not share a cwd).
# ---------------------------------------------------------------------------- #
function(_add_nvqpp_object out_var obj_name src)
set(_obj "${CMAKE_CURRENT_BINARY_DIR}/${obj_name}.o")
set(_wd "${CMAKE_CURRENT_BINARY_DIR}/${obj_name}.nvqpp")
file(MAKE_DIRECTORY "${_wd}")
add_custom_command(
OUTPUT "${_obj}"
COMMAND ${NVQPP} ${ARGN} -c -fPIC "${src}" -o "${_obj}" ${_nvqpp_includes}
DEPENDS "${src}"
WORKING_DIRECTORY "${_wd}"
COMMENT "Compiling with nvq++ (${obj_name})"
VERBATIM)
set_source_files_properties("${_obj}" PROPERTIES EXTERNAL_OBJECT TRUE GENERATED TRUE)
set(${out_var} "${_obj}" PARENT_SCOPE)
endfunction()

# ---------------------------------------------------------------------------- #
# Generator (plain): writes the decoder config + syndrome files.
# ---------------------------------------------------------------------------- #
_add_nvqpp_object(_gen_obj generator "${_src}" --target stim)
add_executable(surface_code_realtime_decoding "${_gen_obj}")
set_target_properties(surface_code_realtime_decoding PROPERTIES LINKER_LANGUAGE CXX)
# --no-as-needed: nvqir-stim (the --target stim simulator) and
# cudaq-platform-default are pulled in at runtime by registration, not by a
# direct symbol reference, so the default --as-needed would drop them from
# DT_NEEDED and the process would crash at startup with no platform.
target_link_libraries(surface_code_realtime_decoding PRIVATE
-Wl,--no-as-needed
cudaq-qec cudaq-qec-realtime-decoding
cudaq-qec-realtime-decoding-simulation ${_cudaq_core_libs}
-Wl,--as-needed
"${CUDAQ_REALTIME_DISPATCH_LIB}")
target_link_options(surface_code_realtime_decoding PRIVATE
LINKER:--allow-shlib-undefined LINKER:--export-dynamic)

# ---------------------------------------------------------------------------- #
# Lowered kernel (-cqr): the live syndrome source over UDP.
# LINKER_LANGUAGE CUDA + CUDA_RESOLVE_DEVICE_SYMBOLS runs the device-link
# (nvcc -dlink) that resolves the dispatch archive's RDC registration symbols.
# ---------------------------------------------------------------------------- #
_add_nvqpp_object(_cqr_obj generator-cqr "${_src}"
--target stim -frealtime-lowering -DQEC_APP_CQR)
add_executable(surface_code_realtime_decoding-cqr "${_cqr_obj}")
set_target_properties(surface_code_realtime_decoding-cqr PROPERTIES
CUDA_SEPARABLE_COMPILATION ON
CUDA_RESOLVE_DEVICE_SYMBOLS ON
CUDA_STANDARD 17
LINKER_LANGUAGE CUDA)
target_link_libraries(surface_code_realtime_decoding-cqr PRIVATE
-Wl,--no-as-needed
cudaq-qec cudaq-qec-realtime-decoding
cudaq-qec-realtime-decoding-simulation-cqr
# The in-process decoding service; also exports
# cudaqx_qec_device_call_dispatch_count, which the app prints as evidence
# that an external server (not the in-process service) did the decoding.
cudaq-qec-realtime-decoding-server-cqr
cudaq-device-call-runtime
${_cudaq_core_libs}
-Wl,--as-needed
"${CUDAQ_REALTIME_DISPATCH_LIB}" CUDA::cudart)
target_link_options(surface_code_realtime_decoding-cqr PRIVATE
LINKER:--allow-shlib-undefined LINKER:--export-dynamic)

# ---------------------------------------------------------------------------- #
# Ising decoder profile (trt_decoder): the surface_code-4-lineage source, same
# two build variants. Requires no extra link inputs -- the TensorRT decoder is
# a runtime-loaded plugin (lib/decoder-plugins/libcudaq-qec-trt-decoder.so in
# the CUDA-QX install), discovered by the serving side, never linked here.
# ---------------------------------------------------------------------------- #
_add_nvqpp_object(_ising_gen_obj ising-generator "${_ising_src}" --target stim)
add_executable(surface_code_ising_realtime_decoding "${_ising_gen_obj}")
set_target_properties(surface_code_ising_realtime_decoding PROPERTIES
LINKER_LANGUAGE CXX)
target_link_libraries(surface_code_ising_realtime_decoding PRIVATE
-Wl,--no-as-needed
cudaq-qec cudaq-qec-realtime-decoding
cudaq-qec-realtime-decoding-simulation ${_cudaq_core_libs}
-Wl,--as-needed
"${CUDAQ_REALTIME_DISPATCH_LIB}")
target_link_options(surface_code_ising_realtime_decoding PRIVATE
LINKER:--allow-shlib-undefined LINKER:--export-dynamic)

_add_nvqpp_object(_ising_cqr_obj ising-generator-cqr "${_ising_src}"
--target stim -frealtime-lowering -DQEC_APP_CQR)
add_executable(surface_code_ising_realtime_decoding-cqr "${_ising_cqr_obj}")
set_target_properties(surface_code_ising_realtime_decoding-cqr PROPERTIES
CUDA_SEPARABLE_COMPILATION ON
CUDA_RESOLVE_DEVICE_SYMBOLS ON
CUDA_STANDARD 17
LINKER_LANGUAGE CUDA)
target_link_libraries(surface_code_ising_realtime_decoding-cqr PRIVATE
-Wl,--no-as-needed
cudaq-qec cudaq-qec-realtime-decoding
cudaq-qec-realtime-decoding-simulation-cqr
cudaq-qec-realtime-decoding-server-cqr
cudaq-device-call-runtime
${_cudaq_core_libs}
-Wl,--as-needed
"${CUDAQ_REALTIME_DISPATCH_LIB}" CUDA::cudart)
target_link_options(surface_code_ising_realtime_decoding-cqr PRIVATE
LINKER:--allow-shlib-undefined LINKER:--export-dynamic)
Loading
Loading