Skip to content

Remove inproc_rpc - #768

Open
melody-ren wants to merge 12 commits into
NVIDIA:mainfrom
melody-ren:melodyr/goodbye-inproc-rpc
Open

Remove inproc_rpc#768
melody-ren wants to merge 12 commits into
NVIDIA:mainfrom
melody-ren:melodyr/goodbye-inproc-rpc

Conversation

@melody-ren

@melody-ren melody-ren commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Removes inproc_rpc, the in-process RPC session that was an intermediary step
in the decoding-server work. The external decoding server (HOST_CALL over UDP)
and the direct-call path are the surviving decode paths.

  • Delete qec_realtime_session and rpc_producer, and the tests that existed
    only to exercise them (test_pymatching_realtime,
    test_realtime_qldpc_graph_decoding + qldpc_config_loader, the
    surface_code-1 inproc CTest).
  • Drop CUDAQ_QEC_REALTIME_MODE (now unread) and the REQUIRE_HOST_MODE
    assertions, which only proved the inproc session was in use.
  • Docs: excise the realtime_relay_bp.rst sections that documented the removed
    path; re-anchor comments naming the deleted session.
  • Stop linking cudaq-qec-realtime-decoding against
    libcudaq-realtime-host-dispatch; that link existed for
    qec_realtime_session.cpp, and neither remaining source names a
    host-dispatch symbol.

relay-BP coverage

Every surface_code-4-yaml case previously ran under
CUDAQ_QEC_REALTIME_MODE=inproc_rpc. pymatching and trt fall through to the
direct-call path; the nv-qldpc/relay-BP cases were parked behind if(FALSE).
This PR deletes them rather than restoring them.

surface_code-4-yaml-mixed-dispatch already runs nv-qldpc RelayBP through
decoding_server and asserts on its per-decoder logical_errors line, under
the same device-graph + proprietary-archive gate those cases would have
required — so restoring them adds no configuration that is not already
covered.

Testing

42/42 app_examples.surface_code-4-yaml tests pass
with the nv-qldpc plugin, proprietary cudevice archive, and python-onnx
configured. This covers the surviving direct-call and external decoding-server
paths after removing inproc_rpc, including
app_examples.surface_code-4-yaml-mixed-dispatch, where nv-qldpc RelayBP runs
on a device-graph ring alongside a host-dispatched decoder.

melody-ren and others added 10 commits July 16, 2026 23:17
inproc_rpc was a value of CUDAQ_QEC_REALTIME_MODE that routed realtime
enqueue/get/reset through an in-process shared-ring RPC session
(qec_realtime_session + rpc_producer) instead of the direct-call path.
Remove it entirely; the direct-call path becomes the sole in-process path.
The external_server (two-process decoding server) path is unaffected -- it
never keyed on inproc_rpc.

- realtime_decoding.{cpp,h}: remove the session setup, the three
  g_realtime_session RPC branches, get_realtime_session(), and the
  inproc-only cudaDeviceMapHost flag. The surviving direct-call path
  (validation, --save_syndrome capture, device pinning, decode) is unchanged.
- Delete qec_realtime_session.{cpp,h} and rpc_producer.{cpp,h} and drop them
  from the realtime-decoding library; nothing else in production used them
  (the decoding servers only mirror their memory layout).
- Disable the inproc-only tests (test_pymatching_realtime,
  test_realtime_qldpc_graph_decoding, the surface_code-1 inproc-rpc ctest,
  and the sc4-yaml REQUIRE_HOST_MODE assertion) pending removal and re-point
  in follow-up commits.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
Follow-up to removing inproc_rpc: delete the tests that existed only to exercise
the in-process RPC session, and move the app-example tests off the now-ignored
inproc_rpc env onto the surviving decode paths.

- Delete the inproc-only unit tests test_pymatching_realtime and
  test_realtime_qldpc_graph_decoding (+ qldpc_config_loader), and the
  surface_code-1 inproc-rpc CTest.
- Re-point surface_code-4-yaml / surface_code-1 to the direct-call path (drop
  CUDAQ_QEC_REALTIME_MODE, now unread). External-server / UDP coverage is
  unchanged -- the cqr variants still route through the two-process server.
- Remove the REQUIRE_HOST_MODE assertions (they only proved the inproc session
  was used).
- Disable the relay-BP DEVICE-mode cases (nv-qldpc --use-relay-bp, trio-relay-d3)
  that drove the removed device-graph scheduler; re-point them to the external
  server (HOST_CALL over UDP) as a follow-up.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
- realtime_relay_bp.rst: excise the CI unit test and Surface Code Test sections
  (both drove the removed inproc_rpc device-graph path) and the CI-test build
  scaffolding (config list, hardware table, 'CI unit test only' build). Keep the
  emulated / FPGA end-to-end content, which drives the same device-graph
  scheduler through the Hololink bridge.
- Re-anchor comments that named the deleted qec_realtime_session: the
  decoding-server ABI/layout notes (GpuRoceTransceiver, decoding_server) point at
  cudaq-realtime or describe the mechanism directly; the Hololink bridge and the
  realtime-decoding CMake drop the qec_realtime_session references.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
Conflict resolutions, all in favor of upstream's post-NVIDIA#682/NVIDIA#750 realtime
structure with the inproc_rpc path kept out:

- qec_realtime_session.cpp: deleted (upstream's touch was to removed code).
- GpuRoceTransceiver.cpp: deleted; NVIDIA#754 renamed it to
  DeviceGraphTransceiver.cpp. The stale qec_realtime_session comment
  reference the branch scrubbed moved to DeviceGraphRingConsumer.cpp and is
  scrubbed there instead.
- realtime_decoding.cpp: reset_decoder takes NVIDIA#698's pin_decode_device(),
  dropping the rpc_producer dispatch branch.
- decoding_server.cpp: upstream's per-ring rewrite; its comments no longer
  reference qec_realtime_session, so the branch's scrub is subsumed.
- app_examples/CMakeLists.txt: upstream's add_surface_code_4_yaml_test
  signature (onnx_path folded into ARGN) with an empty test environment.
- surface_code-4-yaml-test.sh: keep the num_logical echo, drop the
  CUDAQ_QEC_REALTIME_MODE echo.
- realtime_relay_bp.rst: single Building subsection renamed Hololink -> HSB,
  target list on the NVIDIA#754 names, CI-unit-test section dropped (the test is
  removed) and the Surface Code Test section kept.

Upstream added no new inproc_rpc surface: DeviceGraphTransceiver,
DeviceGraphRingConsumer, surface_code-5-per-decoder-rings and
realtime_decoding_demo are all inproc-free.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
The inproc_rpc removal parked these behind if(FALSE) on the theory that they
needed the device-graph scheduler. They did not: --use-relay-bp only sets
nv-qldpc parameters when the decoder config is generated, so the cases need
the plugin and nothing else. Re-enable them on the direct-call path, on the
same gate the dual-parse cases already use, and fold that repeated gate into
_SC4_HAVE_NV_QLDPC.

What the inproc_rpc cases did provide was relay-BP over a *dispatched* path.
Restore that against the external decoding server, which since NVIDIA#682 gives each
decoder its own ring: one all-nv-qldpc trio, and the pymatching + trt +
nv-qldpc trio when the trt plugin and python-onnx are present. Both assert
server-side decode counts, and both get a 600s timeout because relay BP
iterates.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
realtime_relay_bp.rst still compared the surface-code test against the CI unit
test section, and pointed at it for the build, but that section went away with
the test it documented. Say what the app example does on its own terms and
point the build note at the bridge.

The surface_code-4 comment naming inproc_rpc described what the external
relay-BP cases replaced rather than what they are.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
The new surface_code-4 external-server cases (cqr-relay-bp, cqr-trio-relay)
were gated on _SC4_HAVE_NV_QLDPC, i.e. on the decoder plugin alone.  That is
the right gate for the direct-call cases -- --use-relay-bp only sets nv-qldpc
parameters when the config is generated -- but not for these two: the server
constructs the decoder through DecodingSession::create(), which probes
supports_graph_dispatch() and captures a CUDA device graph even on the udp
transport.  Without decoding_server linked against the proprietary cudevice
archive that lookup fails and the server never reaches READY:

  nv_qldpc_decoder::capture_decode_graph:
  cudaqx_qec_realtime_dispatch_register_decoder_state not found via dlsym

So in any build with the plugin but no archive -- which CMake already warns
about at decoding_server link time -- the tests registered and hard-failed.
Both plugin flavors in the proprietary tree behave identically here, so this
is not a host-vs-graph build question.

Add _SC4_NV_QLDPC_IN_SERVER (plugin AND device-graph availability AND the
proprietary target, mirroring tools/decoding-server) and hang the two
external cases off it.  The direct-call cases keep the plugin-only gate.

Also warn when either nv-qldpc gate fails, per the convention the trt block
right below already follows -- a silent skip here is precisely what once
masked a dead test check for a whole release cycle.

Verified in all three configurations: plugin+archive registers and passes
(47/47 surface_code-4 cases, including cqr-trio-relay); plugin without the
archive skips the external cases with a named warning while the direct-call
cases still run; no plugin skips all of them.

Signed-off-by: Ben Howe <bhowe@nvidia.com>
No conflicts. The nine commits since the last merge touch the realtime path
again -- NVIDIA#769 serves HOST_CALL inline and retires the worker threads, queues,
and CqrTransceiver; NVIDIA#759 adds the dynamic-DEM infrastructure that reshapes
create_realtime_decoder around chunk expansion -- but none of it reaches the
inproc_rpc path this branch removes: no reference to inproc_rpc,
qec_realtime_session, or rpc_producer comes back, and none of the deleted
sources reappear.

NVIDIA#778 moves the CUDA-Q pin to 28f195f4, so verification needs a toolchain
rebuilt at that commit.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

surface_code-4-yaml-mixed-dispatch already runs nv-qldpc RelayBP through the
decoding server and asserts on its per-decoder logical_errors line, so these
five registrations duplicated coverage that already exists.

They were also unsound as written. Multi-type mode replaces the aggregate
logical-error ceiling with a per-decoder one, but that check compares a single
patch against MAX_NON_ZERO, which is the per-logical bound scaled by the patch
count -- three times too loose with three patches. At the shot counts used
here an nv-qldpc entry that decoded nothing would have stayed under it, and
REQUIRE_SERVER_DECODE_COUNTS only proves the decoder was reached. Restoring
this coverage belongs with a fix to that ceiling, not in the inproc_rpc
removal.

_SC4_NV_QLDPC_IN_SERVER and its warning branch go with them; _SC4_HAVE_NV_QLDPC
stays for the dual-parse cases.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
The library's two sources, realtime_decoding.cpp and config.cpp, name no
host-dispatch symbol; the link existed for qec_realtime_session.cpp, which this
branch removes. cudaq_host_dispatcher_loop still has a caller in
realtime_pipeline.cu, but that belongs to the separate cudaq-realtime-pipeline
target with its own link, so only this target's lookup and link go.

Signed-off-by: Melody Ren <melodyr@nvidia.com>
@melody-ren
melody-ren marked this pull request as ready for review August 15, 2026 06:09
@melody-ren

Copy link
Copy Markdown
Collaborator Author

/ok to test 8d82248

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants