Skip to content

Remove inproc_rpc - #768

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

Remove inproc_rpc#768
melody-ren wants to merge 8 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.

Preserving relay-BP coverage

Every surface_code-4-yaml case previously ran with
CUDAQ_QEC_REALTIME_MODE=inproc_rpc, so removing it drops dispatched-path
coverage. pymatching and trt already have external-server (cqr) cases;
nv-qldpc/relay-BP did not, so it would have been left with none.

  • Re-enable the relay-BP direct-call cases (relay-bp-d3/d5, trio-relay-d3).
    They were parked on the theory that they needed the device-graph scheduler;
    --use-relay-bp only sets nv-qldpc parameters at config generation, so the
    plugin is the only requirement.
  • Add two external-server cases to restore dispatched relay-BP coverage:
    an all-nv-qldpc trio and a pymatching + trt + nv-qldpc trio. Both assert
    server-side decode counts, with a 600s timeout since relay BP iterates.
  • Fold the repeated nv-qldpc gate into _SC4_HAVE_NV_QLDPC, and gate the two
    external cases on _SC4_NV_QLDPC_IN_SERVER — they build the decoder inside
    decoding_server, which additionally needs the proprietary cudevice archive
    linked. Both gates now warn when they skip.

Testing

47/47 app_examples.surface_code-4-yaml cases pass with the nv-qldpc plugin,
the cudevice archive, and python-onnx configured — including both new external
cases. Without the archive the external cases skip with a named warning and the
direct-call cases still run; without the plugin all nv-qldpc cases skip.

melody-ren and others added 8 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>
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