Fix GB200 gpu_roce decoding-server validation issues#683
Merged
vedika-saravanan merged 6 commits intoJul 14, 2026
Conversation
vedika-saravanan
force-pushed
the
relaybp-gpuroce-gb200-fixes
branch
from
July 14, 2026 13:54
017229c to
8e5e9f7
Compare
…ge alignment, private dispatch symbols Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
vedika-saravanan
force-pushed
the
relaybp-gpuroce-gb200-fixes
branch
from
July 14, 2026 13:56
8e5e9f7 to
75780c3
Compare
Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
vedika-saravanan
force-pushed
the
relaybp-gpuroce-gb200-fixes
branch
from
July 14, 2026 14:04
75780c3 to
3de6452
Compare
vedika-saravanan
force-pushed
the
relaybp-gpuroce-gb200-fixes
branch
2 times, most recently
from
July 14, 2026 16:15
a92b03c to
fc0ceaf
Compare
vedika-saravanan
marked this pull request as ready for review
July 14, 2026 16:29
Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
vedika-saravanan
force-pushed
the
relaybp-gpuroce-gb200-fixes
branch
from
July 14, 2026 16:39
fc0ceaf to
df7d51e
Compare
bmhowe23
reviewed
Jul 14, 2026
bmhowe23
reviewed
Jul 14, 2026
Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
bmhowe23
approved these changes
Jul 14, 2026
bmhowe23
left a comment
Collaborator
There was a problem hiding this comment.
LGTM once Chuck's threads are marked as resolved.
bmhowe23
added a commit
to bmhowe23/cudaqx
that referenced
this pull request
Jul 15, 2026
…ridge branch Main landed the squashed PR 670 plus NVIDIA#656/NVIDIA#673/NVIDIA#674/NVIDIA#678/NVIDIA#680/NVIDIA#683/NVIDIA#688/ NVIDIA#690/NVIDIA#691/NVIDIA#692. Resolution keeps this branch's design and ports main's content into it: - Naming: main's GpuRoce{Transceiver,Factory,LinkCheck} map 1:1 onto this branch's DeviceGraph* files (the de-transport-ing follow-up requested in the PR 670 review). Main's post-review fixes are ported into the renamed files: ring-size overflow + host-page-size alignment validation, gpu_id resolved from the decoder's cuda_device_id instead of an env var, the factory taking pinned_cuda_device, and the linkcheck exercising the new factory signature. - Schema: per-decoder 'dispatch: host|device_graph' plus the top-level transport section stay; main's per-decoder 'transport:' key does not return. cuda_device_id is adopted as a per-decoder placement knob (config struct + YAML trait), and the hsb script now injects 'dispatch: device_graph' + cuda_device_id and drives the server with QEC_DEVICE_GRAPH_* env and the device_graph READY sentinel. - Features adopted from main: decoder CUDA-device pinning (worker-thread pin via promise, graph-capture pin, hardware_guards.h), per-session decode counters + print_session_stats + QEC_DECODING_SERVER_STATS server-side stats printing, DecodingServer ctor exception safety, virtualized realtime decoder API (NVIDIA#674), CMP0126 fix, CUDA::cudart on the core lib, and the cudevice-archive dedup in the server link. - DecodingSession combines main's set_graph_capture_device with this branch's reserved-SMs decode-graph capture (QEC_DEVICE_GRAPH_RESERVED_SMS). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Ben Howe <bhowe@nvidia.com>
anjbur
added a commit
to anjbur/cudaqx
that referenced
this pull request
Jul 16, 2026
)" This reverts commit 2cdc9df. Signed-off-by: Angela Burton <angelab@nvidia.com>
cketcham2333
added a commit
to cketcham2333/cudaqx
that referenced
this pull request
Jul 16, 2026
…an FPGA or a QPU kernel
A shipped example that compiles against the installed SDK and exercises the
delivered decoding_server from two syndrome sources, plus its docs/CI
registration and an FPGA RX-ring sizing fix in the unittests driver.
The example (docs/sphinx/examples/qec/realtime_decoding_demo/):
- surface_code_realtime_decoding.cpp (a slimmed surface_code-4-yaml: the
Ising-bundle and syndrome-replay machinery removed) is built two ways by a
standalone CMakeLists.txt using installed headers/libs only -- a generator
(writes the decoder config, and for the FPGA source the playback syndrome
file) and the lowered -cqr kernel (-frealtime-lowering).
- run_realtime_decoding.sh drives either source with pymatching / trt_decoder
/ nv-qldpc-decoder:
--source qpu-kernel the lowered kernel streams syndromes to the server
over UDP (no hardware);
--source fpga the delivered hololink_fpga_syndrome_playback streams
syndromes from a real FPGA over RoCE (cpu_roce for
CPU decoders, gpu_roce for the nv-qldpc device path).
- Pass/fail matches the existing surface-code tests. The qpu-kernel path
applies the same checks as the surface_code-4-yaml-test.sh ctest driver:
hard decoder-failure greps, the "Number of corrections decoder found:"
completion proof, a residual logical-error ceiling of num_shots/50 (min 1),
the server-owned-decoders report, and a server dispatch-count floor of
num_shots * (num_rounds + 3). The fpga path passes on the playback tool's
per-shot correction verification, same as hsb_fpga_decoding_server_test.sh.
- The gpu_roce RX ring runs at the HSB QP's 64-entry receive WQE depth (the
receiver pre-posts one WQE per ring slot; deeper rings drop frames under
load), with a preflight of DOCA's host-page alignment that fails fast with
the stride constraint on 16K/64K-page hosts. The server gets --timeout=300
(total-runtime failsafe, matching the in-tree external-server tests).
Docs + CI:
- New narrative page examples_rst/qec/realtime_decoding_demo.rst
(literalincludes the source), registered in the QEC examples toctree; the
FPGA predecoder + Relay BP pages point at the example for end-to-end runs.
- conf.py.in excludes examples/**/README.md from sphinx (example READMEs are
for the shipped tree / GitHub; the '.md' source suffix would otherwise
ingest them as toctree-orphan pages).
- lib_qec.yaml: build-and-test (CPU) builds the two example binaries against
the installed SDK (enforcing the installed-headers-only rule) and runs the
qpu-kernel pymatching decode over UDP loopback -- a real decode, no
hardware -- archiving the SDK install + example build for the GPU job.
gpu-test runs the example's trt_decoder qpu-kernel decode over UDP reusing
those artifacts (+ pip install onnx). This is the only CI coverage of
trt_decoder THROUGH the decoding server: the TRTDecoder unit tests exercise
the decoder standalone, and the app_examples happy-path trt test is
configured out because its onnx gate is evaluated before onnx is
pip-installed. Gated on TensorRT availability (skips arm64-cu12).
- unittests/utils/CMakeLists.txt installs hololink_fpga_syndrome_playback
alongside decoding_server (already hololink-gated; a no-op in the vanilla
release) so the example can resolve it from the install prefix.
hsb_fpga_decoding_server_test.sh -- fix HSB FPGA RX-ring sizing (two bugs,
both rooted in the HSB QP's fixed 64 receive WQEs; the receiver pre-posts one
WQE per ring slot, so a ring with MORE slots than WQEs drops frames):
1. cpu_roce modulus desync (regression from NVIDIA#683 / 2cdc9df): NVIDIA#683 added
PLAYBACK_NUM_PAGES=512 as the playback --num-pages to size the gpu_roce
ring, but run_playback is SHARED with cpu_roce, whose server RX ring is 64
slots. The FPGA writes frame rid to slot (rid % num-pages), so frames
rid>=64 landed outside the server's registered MR and the test starved
after ~10 shots (DISPATCHED=64). Fix: program the playback ring modulus
from the server ring depth per transport, and clamp both to the WQE depth
so the invariant is structural.
2. gpu_roce over-sized ring: the ring was 512 slots but the DOCA receiver only
pre-posts 64 WQEs, dropping frames under load. Cap it at the WQE depth
(clamp+warn on an over-sized --gpu-roce-num-pages), and preflight DOCA's
host-page alignment (64 x 384 B covers 4K/8K-page kernels; 16K/64K-page
hosts fail fast with the --page-size constraint spelled out).
The emulator does not parse --num-pages (its RDMA-write modulus is the SIF
target the playback programs), so the dead arg, the PLAYBACK_NUM_PAGES
variable, and the --playback-num-pages option are removed.
Signed-off-by: Chuck Ketcham <cketcham@nvidia.com>
melody-ren
added a commit
that referenced
this pull request
Jul 17, 2026
…698) ## Background - #690 introduced the cuda_device_id placement knob for GPU decoders. - #678 made worker threads and the inproc graph capture honor the pinned device, and pinned decoder construction. - #683 closed the remaining gap: the gpu_roce decoding-server capture path now pins too. Each fix added a device pin to one more path via its own ad-hoc helper. The "which device" decision ended up duplicated across dispatch, capture, the worker, construction, and the gpu_roce transport. And that is the motivation for this PR. ## What this PR does Basically, every path should be following a single source of truth. Consolidate all of it to: the decoder's `cuda_device_id`, resolved one way (`decode_device_for`) and applied through two sanctioned wrappers — `pin_decode_device` (dispatch/decode) and `capture_graph_pinned` (graph capture) — in `hardware_guards.h.` Every path now derives its device from that one field; none selects a device by any other means. Unpinned (< 0) keeps existing semantics: dispatch no-ops, capture defaults to device 0. Signed-off-by: Melody Ren <melodyr@nvidia.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Follow-up fixes on top of the HSB/FPGA
gpu_rocedecoding-server path, found during end-to-end GB200 validation of RelayBP /nv-qldpc-decoderwith the FPGA emulator.Validated after rebase with an 85-shot / 425-frame
gpu_roceRelayBP run against the FPGA emulator, using 512 playback windows. The emulator processed all windows successfully with 425 responses, 0 send errors, and 0 timeouts.Changes:
cuda_device_id, and reconcile it with the transitionalHOLOLINK_GPU_IDsetting.gpu_roceDOCA ring allocation against host page-size alignment, and make the HSB test harness choose an aligned server ring depth while keeping playback window capacity explicit.decoder_rpc_dispatch.cusupport intodecoding_serverwhen present; public builds remain unaffected.decoding_server.gpu_rocelink check verify symbol/link availability without constructing a transceiver or selecting GPU 0.gpu_rocering pages and FPGA/emulator playback window pages.Note: I left this local intentionally because the
HOLOLINK_GPU_IDpath is transitional and PR692 removes it. Sharing the env parser now would add churn and increase conflicts for code that is about to disappear.Runtime / performance impact
na
Self-review checklist
Please confirm each item before requesting review. Check
[x]or strikethrough and explain.
Before requesting review
Scope and size
(if so, an issue has been raised).
Tests
just when it is missing.
EXPECT_*/assertchecks areinsufficient for algorithmic correctness.
Documentation
tracked.
Code style
snake_casevscamelCase) forthe area being modified.
Dependencies
OSRB tickets filed.