Skip to content

UCP/CORE: Ignore DPU in topology assignments - #11990

Merged
tvegas1 merged 15 commits into
openucx:masterfrom
guy-ealey-morag:topo-assign-ignore-dpu
Oct 1, 2026
Merged

tvegas1 merged 15 commits into
openucx:masterfrom
guy-ealey-morag:topo-assign-ignore-dpu

Conversation

@guy-ealey-morag

@guy-ealey-morag guy-ealey-morag commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

What?

Exclude DPUs (e.g. BlueField) from the GPU-NIC assignment, moving the filtering from UCS topology to UCT/UCP:

  • UCT IB reports UCT_MD_FLAG_DPU for BlueField 1-4 (adds the BlueField-4 0xa2df spec entry).
  • UCP marks a network sys_dev as a candidate if a non-DPU MD that registers memory reports it. The assignment skips NICs with no candidate function, without advancing the assignment order.
  • The CX9 PCI-id and firmware-version filter is removed from topo_groups.c.

Why?

  • Move device specific logic from UCS to UCT/UCP.
  • Change the approach to device filtering in Vera-Rubin: Instead of keeping only CX9s, filter out all BF4s.

@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/ucp/core/ucp_context.c Resolved
Comment thread src/ucp/core/ucp_gpu_nic_assignment.c Resolved
Comment thread src/ucp/core/ucp_context.c Outdated
return 0;
}

static void ucp_gpu_nic_candidates_add(ucp_context_h context,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: pls update the GPU_NIC_ASSIGNMENT_MODE help text too — it says all NICs of a group are assigned, but DPU NICs and NICs without memory registration (UCT_MD_FLAG_REG) are now skipped.

@svc-nvidia-pr-review

Copy link
Copy Markdown

Coverage gap: ucp_gpu_nic_candidates_add() (the DPU / no-REG / NET-only MD filtering) has no unit test; only the candidate_nics consumer is covered by gtest. Testing it needs a fake MD, so relying on the new test_ucp_gpu_nic_assignment cases plus manual verification is probably fine.

UCT_MD_FLAG_DPU on real BlueField hardware and the BlueField-4 device id 0xa2df cannot be validated in CI (no HW, contrib/ibmock does not cover these PCI ids). The TODO about DPU VFs sharing the generic mlx5 VF id (0x101e) means the old FW-version-based VF detection is intentionally dropped — worth confirming that is acceptable for the target platforms.

@svc-ucx

svc-ucx commented Sep 28, 2026

Copy link
Copy Markdown

🤖 CI Triage Agent — UCX PR (AddressSanitizer gpu on worker 0) · commit 8f18f05f

TL;DR: The ASAN GPU gtest run failed on a single protocol-selection assertion, shm_ib/test_ucp_proto_am_rndv.am_explicit_scheme_disables_force_provenance/0 (test/gtest/ucp/test_ucp_proto.cc:805) — a topology/MD-dependent expectation introduced by PR #11685, not by anything this PR changes; re-run to confirm flakiness and harden the test's device prerequisites (use require_cuda_net_md() / skip when am/rndv isn't selectable) instead of hard-asserting.

Full analysis

Summary: make test in the "AddressSanitizer gpu on worker 0" job exited 1 because exactly 1 of 10220 gtests failed: shm_ib/test_ucp_proto_am_rndv.am_explicit_scheme_disables_force_provenance/0, GetParam() = shm,ib,cuda_copy,rocm_copy (log lines [ FAILED ] 1 test, make: *** [Makefile:4809: test] Error 1). No sanitizer report, no crash, no hang — continuous log activity to the end.

Root cause: That test (test/gtest/ucp/test_ucp_proto.cc:805-813) runs with RNDV_PIPELINE_SHM_CUDA_STAGING_FORCE=y + RNDV_SCHEME=get_zcopy and calls check_am_rndv_remote_proto_config(0, 0), which hard-asserts that (a) the protocol selected for a 1 MB CUDA AM send is exactly "am/rndv" (line 438), (b) remote_proto_config->select_param.op_id_flags == UCP_OP_ID_RNDV_RECV (line 455) and (c) no rkey config carries UCP_RKEY_CONFIG_FLAG_PROTO_ESTIMATION (line 457). These expectations depend on the node's GPU/NIC topology and on which MDs can register CUDA memory, and only require_cuda_rndv_support() guards them (unlike the sibling force-cuda tests which use require_cuda_net_md()). This assertion set came with commit 0311ed7 (PR #11685) and has a history of environment-dependent failures — three throwaway PRs (#11858, #11861, #11864) were opened specifically to diagnose/isolate this exact test name.
The change under test cannot plausibly produce this: 8f18f05 adds UCT_MD_FLAG_DPU (src/uct/api/v2/uct_v2.h:1149, a fresh bit 14, no collision) and consumes it only in ucp_gpu_nic_candidates_add() (src/ucp/core/ucp_context.c:1431) to drop DPU MDs from context->gpu_nic_candidates; that bitmap is used solely by ucp_context_gpu_nic_assignment_init() (src/ucp/core/ucp_context.c:2840), which bails out before building any assignment when the mode is AUTO and the CPU is not UCS_CPU_MODEL_NVIDIA_VERA (lines 2851-2864) — the case on this x86 CentOS8/CUDA11 ASAN container. So the DPU filter is a no-op on this worker and does not alter protocol selection.
Caveat: the per-assertion failure text was printed earlier in the run and is not present in the retained log tail, so the exact failing EXPECT could not be read.

Implicated commit: 0311ed7 — "UCP/PROTO/RNDV: Isolate remote system device namespace (#11685)", jeffnvidia (test author). The PR head commit 8f18f05 (Guy Ealey Morag) is not implicated.

File: test/gtest/ucp/test_ucp_proto.cc:805 (test body), test/gtest/ucp/test_ucp_proto.cc:438-458 (failing expectations)

Suggested fix:

  1. Re-run the ASAN gpu job on the same commit to confirm the failure is not reproducible (expected, given it is unrelated to the diff).
  2. Harden the test rather than the product: replace require_cuda_rndv_support() with require_cuda_net_md() in test_ucp_proto_am_rndv.am_* tests, and make select_am_rndv_remote_proto_config() UCS_TEST_SKIP_R (instead of EXPECT_STREQ/ADD_FAILURE) when the selected protocol for 1 MB CUDA is not am/rndv or when the info string reports a stub protocol — mirroring what rndv_force_cuda_send_child_uses_tag_provenance already does at lines 700-702.
  3. Ask the UCP/PROTO/RNDV: Isolate remote system device namespace #11685 author to review this assertion's device assumptions on swx-rdmz-ucx-gpu-* nodes; if it stays strict, pin the test to the mock-topology fixture (test_ucp_proto_mock.cc) so it does not depend on real GPU/NIC layout.

Related: PR #11990 (build under test); PR #11685 / commit 0311ed7 (introduced the test); prior diagnostic PRs for the same test: #11858, #11861, #11864.

Comment thread src/ucp/core/ucp_gpu_nic_assignment.c Resolved
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/ucp/core/ucp_types.h Resolved
Comment thread src/ucp/core/ucp_context.c Resolved
Comment thread src/ucp/core/ucp_gpu_nic_assignment.h Resolved
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/uct/api/v2/uct_v2.h Resolved
Comment thread src/uct/ib/base/ib_md.c Outdated

/* TODO: Detect DPU VFs, which share the generic mlx5 VF PCI id, by the
* board PSID (board_id) */
if (uct_ib_device_spec(&md->dev)->flags & UCT_IB_DEVICE_FLAG_DPU) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: why not set this once in md->cap_flags inside uct_ib_md_open_common(), like the other IB MD flags? dev->pci_id and the custom specs are already parsed by then, and md_query would not repeat the spec-table lookup.

Comment thread src/ucp/core/ucp_context.c Resolved
@svc-nvidia-pr-review

Copy link
Copy Markdown

Residual coverage gaps: the flip/round_robin index compaction is now sensitive to which MDs open successfully, so a per-process MD open failure would shift the assignment for that process only; this is untestable in CI and has no consumer yet, since ucp_gpu_nic_assignment_lookup() is still only called from within ucp_gpu_nic_assignment.c. The new {"BlueField 4", {0x15b3, 0xa2df}, ... DC_V2 ...} entry also newly enables MLX5_PRM/DC for BF4 in uct_ib_device_port_check() (previously it fell through to "Generic HCA"), which is a functional change no CI job can exercise.

@svc-ucx

svc-ucx commented Sep 28, 2026

Copy link
Copy Markdown

🤖 CI Triage Agent — UCX PR (AddressSanitizer roce on worker 1) · commit 0ee51e0e

TL;DR: The ASan roce shard aborted because UMR mkey registration on mlx5_1 timed out (30 s busy-poll, then ibv_post_send for invalidation failed with EFAULT), making ucp_rkey_pack return Input/output error; the gtest ASSERT_UCS_OK then left the memh mapped, so ucp_cleanup hit the fatal region->refcount == 0 rcache assert and core-dumped the whole shard. This is a device/UMR-path failure on worker swx-rain04, not something PR #11990 (ucp/core topology only) touches — retest, and harden the UMR timeout recovery + test cleanup.

Full analysis

Summary: shm_ib/test_ucp_rma_reg.get_blocking/3 and put_blocking/1 failed with mlx5_1: ibv_poll_cq(UMR CQ, registration, UMR mkey ... index 0x4e0) timed out, and the subsequent ucp_cleanup fatal rcache assertion (destroying inuse region) aborted make -C test/gtest test (make: *** [Makefile:4809: test] Aborted (core dumped)).

Root cause: Two chained issues visible in the log:

  1. Primary: the synchronous UMR post/poll in uct_ib_mlx5_devx_umr_post_sync() never got a completion on mlx5_1 — it burned the full 30 s timeout (test duration 30630 ms) and returned UCS_ERR_TIMED_OUT; the follow-up invalidation ibv_post_send(UMR QP, invalidation, ...) returned 12 then failed too, i.e. the UMR QP was left in an unusable state (confirmed by the repeat failure on the next non-GVA param and the four ibv_dealloc_pd() failed: Device or resource busy warnings from leaked mkeys). GVA params on the same device passed, so this is the non-GVA/indirect-mkey UMR path on that specific HCA/worker, not a code change in this PR — PR UCP/CORE: Ignore DPU in topology assignments #11990 only changes UCP topology assignment (UCP/CORE: Ignore DPU in topology assignments) and touches no IB MD/UMR or rcache code.
  2. Secondary (why the whole shard died instead of one test): ASSERT_UCS_OK(status) at test/gtest/ucp/test_ucp_memheap.cc:68 returns from the test body with memheap_memh still mapped and rcache-referenced; at ucp_cleanup() the rcache hits ucs_assertv(region->refcount == 0, ...) (src/ucs/memory/rcache.c:394, preceded by the rcache.c:670 "destroying inuse region ... ref 1 md[3]=mlx5_1" warning) and calls ucs_fatal_error, aborting the process.

Implicated commit: unknown — no commit in the PR's diff range touches the failing path; the UMR sync code is pre-existing (most recent change to ib_mlx5dv_md.c is [REDACTED:Hex High Entropy String] "UCT/IB: Allow ODP with DDP for FW >= 49.1014 (#11914)", Thomas Vegas, unrelated to this path).

File: src/uct/ib/mlx5/dv/ib_mlx5dv_md.c:1447 (30 s UMR CQ poll timeout, no QP recovery) and test/gtest/ucp/test_ucp_memheap.cc:68 (memh leaked on assert)

Suggested fix:

  • Re-run the AddressSanitizer roce job (preferably on a different worker than swx-rain04, and check mlx5_1 port/FW health there) to confirm the PR is clean; this failure is not attributable to the topology-assignment change.
  • Harden the UMR path: on UCS_ERR_TIMED_OUT in uct_ib_mlx5_devx_umr_post_sync(), mark the UMR QP as broken and skip further posts (avoids the cascading ibv_post_send ... returned 12 and leaked mkeys/PD-busy warnings), and log the WQ/CQ state to aid diagnosis; also consider yielding in the poll loop instead of a tight 30 s busy spin under ASan.
  • Make the gtest failure non-catastrophic: wrap memheap_memh in a scope guard (or use EXPECT_UCS_OK + explicit ucp_mem_unmap cleanup) in test_ucp_memheap.cc so a failed ucp_rkey_pack doesn't leave an in-use rcache region and abort the entire shard.

Related: PR #11990 (#11990); no existing issue found for the UMR CQ ... timed out signature — worth opening one.

🛡️ This comment had 1 potential secret(s) redacted (Hex High Entropy String). See request_id eaf3da53-1be0-4999-89af-7d9e25f73004 in the triage console for the audit trail.

Comment thread src/ucp/core/ucp_context.h Resolved
Comment thread src/uct/ib/base/ib_md.c Outdated
md_attr->reg_cost = md->reg_cost;
md_attr->exported_mkey_packed_size = sizeof(uct_ib_md_packed_mkey_t);

/* TODO: Detect DPU VFs, which share the generic mlx5 VF PCI id, by the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a custom UCX_IB_DEVICE_SPECS entry overrides the builtin one and its flags string has no letter for DPU, so overriding a BlueField id silently disables this filter - can we add a letter for it, next to '4'/'5'/'d'/'D'/'a'?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that UCX_IB_DEVICE_SPECS is relevant only for ib verbs, and it is not used with mlx5 DV/DEVX MDs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not the common case but easy to address: the case is running without the mlx5 md, e.g. UCX_IB_MLX5_DEVX=n UCX_IB_MLX5_DV=n or a host where mlx5dv_is_supported() is false: there the verbs md parses UCX_IB_DEVICE_SPECS, and UCX_IB_DEVICE_SPECS=0x15b3:0xa2dc:BlueField3:D:61 shadows the builtin BlueField 3 entry, so UCT_IB_DEVICE_FLAG_DPU is lost and the DPU becomes a gpu-nic assignment candidate. Can we add a letter so it stays expressible, as 0x15b3:0xa2dc:BlueField3:5Db:61? Regarding other MD we can leave them out for now.

--- a/src/uct/ib/base/ib_md.c
+++ b/src/uct/ib/base/ib_md.c
@@ -91,6 +91,7 @@ static ucs_config_field_t uct_ib_md_config_table[] = {
      "                             'd' - DC version 1 (Connect-IB, ConnectX-4)\n"
      "                             'D' - DC version 2 (ConnectX-5 and above)\n"
      "                             'a' - Compact address vector support\n"
+     "                             'b' - DPU device (e.g. BlueField)\n"
      "  <priority>  - (optional) device priority, integer.\n"
      "\n"
@@ -1022,6 +1023,8 @@ uct_ib_md_parse_device_config(uct_ib_md_t *md,
                 } else if (*p == 'a') {
                     spec->flags |= UCT_IB_DEVICE_FLAG_AV;
+                } else if (*p == 'b') {
+                    spec->flags |= UCT_IB_DEVICE_FLAG_DPU;
                 } else {
                     ucs_error("invalid device flag: '%c'", *p);

Note a custom spec replaces the builtin flags instead of merging, so the other letters have to be respelled - that is pre-existing, just easy to get wrong here.

Comment thread src/uct/api/v2/uct_v2.h Resolved
Comment thread src/ucp/core/ucp_context.c Resolved
Comment thread src/ucp/core/ucp_context.c Resolved
Add a network device filter to ucs_topo_build_groups(), so callers can
leave NICs out of the groups before they are assigned to GPUs. A NIC
with some filtered ports keeps its other ports. NULL keeps all network
devices.

Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/uct/ib/base/ib_md.c Resolved
Comment thread src/ucs/sys/topo/base/topo_groups.h Outdated
* @ingroup UCS_RESOURCE
* Bitmap of system devices.
*/
typedef ucs_static_bitmap_s(UCS_SYS_DEVICE_ID_COUNT) ucs_sys_device_bitmap_t;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use this type in ucp_gpu_nic_assignment.h as well? ucp_gpu_nic_sys_dev_bitmap_t is now an identical duplicate of it.

Comment thread src/ucs/sys/topo/base/topo_groups.h Resolved
Comment thread test/gtest/ucs/test_topo.cc Resolved
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/uct/ib/base/ib_md.c Resolved
Comment thread test/gtest/ucs/test_topo.cc Resolved
Comment thread src/ucs/sys/topo/base/topo_groups.h Resolved
Comment thread src/ucp/core/ucp_context.c Resolved
@svc-nvidia-pr-review

Copy link
Copy Markdown

Dropping the CX9 filter widens the NIC set on Vera hardware (e.g. a CX7 used for storage now participates in the flip mapping). Intentional per the updated GPU_NIC_ASSIGNMENT_MODE help text, and unobservable today since ucp_gpu_nic_assignment_lookup() still has no external consumer.

@svc-ucx

svc-ucx commented Sep 29, 2026

Copy link
Copy Markdown

🤖 CI Triage Agent — UCX PR (AddressSanitizer gpu on worker 0) · commit bab4a09d

TL;DR: The ASAN GPU gtest run failed on a single protocol‑selection test, shm_ib/test_ucp_proto_am_rndv.am_explicit_scheme_disables_force_provenance/0; the check requires am/rndv to be the selected AM protocol at 1 MB for CUDA memory while RNDV_SCHEME=get_zcopy is forced, but the test only guards with require_cuda_rndv_support() (no network‑MD/CUDA‑registration guard), so on this worker no rndv candidate survives and the assertion fires — it is not caused by the topology/DPU changes in this PR.

Full analysis

Summary: make test in build-test/test/gtest exited with error 1 because 1 of 10220 tests failed: shm_ib/test_ucp_proto_am_rndv.am_explicit_scheme_disables_force_provenance/0 <shm,ib,cuda_copy,rocm_copy> (all other tests passed, run completed normally — no hang, no ASAN report, no crash).

Root cause: The failing case is one of three sibling tests that call the identical helper check_am_rndv_remote_proto_config(0, 0); the other two (am_default_remote_model_preserves_legacy_key, am_force_remote_model_remains_untagged) passed. The only difference is the extra config RNDV_SCHEME=get_zcopy (plus RNDV_PIPELINE_SHM_CUDA_STAGING_FORCE=y). With the scheme pinned to get_zcopy, an am/rndv protocol is only probed if some network MD can register/serve the CUDA source buffer; the helper unconditionally asserts EXPECT_STREQ("am/rndv", thresh->proto_config.proto->name) and then ASSERT_NE(nullptr, remote_proto_config) (test/gtest/ucp/test_ucp_proto.cc:438‑446, 448‑459). Unlike the CUDA force‑path tests, which guard with require_cuda_net_md() (line 632/693), the explicit‑scheme tests only call require_cuda_rndv_support() (line 810), which merely checks CUDA memory + generic RNDV support. In this ASAN/CUDA11 container many CUDA registration paths are disabled (note the many [ SKIP ] (Address sanitizer) lines in test_ucp_mmap/test_ucp_rkey_compare), so the selection at 1 MB falls back to a non‑rndv AM protocol and the assertion fails. The branch's changes (topology groups / DPU filtering, ucs_topo_build_groups*, ucp_gpu_nic_assignment_*) are infrastructure only — nothing under src/ucp/proto/ consumes ucp_gpu_nic_assignment_lookup() (proto_common.c's last change is still #11685) — so they cannot alter this protocol selection. Note: the exact assertion line is earlier in the gtest output than the 500‑line tail the API returns; the above is inferred from which sibling variants passed/failed.

Implicated commit: Not this PR. Tests introduced by 0311ed7 "UCP/PROTO/RNDV: Isolate remote system device namespace (#11685)" (jeffnvidia); selection behaviour also recently changed by fe0ea85 "UCP/RMA: Make put/rndv and get/rndv a fallback of zcopy (#11940)" (Thomas Vegas). Branch HEAD bab4a09 (Guy Ealey Morag) is unrelated to the failing code path.

File: test/gtest/ucp/test_ucp_proto.cc:805-813 (test body) and test/gtest/ucp/test_ucp_proto.cc:438-459 (select_am_rndv_remote_proto_config / check_am_rndv_remote_proto_config)

Suggested fix: Harden the explicit‑scheme tests instead of the topology code:

  1. Add require_cuda_net_md(); (and, for determinism, "RNDV_THRESH=0") to am_explicit_scheme_disables_force_provenance and rma_explicit_scheme_disables_force_provenance, matching the guard already used by rndv_force_cuda_pipeline_selects_attached_path.
  2. In select_am_rndv_remote_proto_config, replace the hard EXPECT_STREQ("am/rndv", …) with a UCS_TEST_SKIP_R("am/rndv is not selected with the configured RNDV_SCHEME") when the scheme restricts candidates, so the intent of the test (no UCP_RKEY_CONFIG_FLAG_PROTO_ESTIMATION rkey configs when a scheme is explicit) is still verified without depending on device registrability.
  3. Re-trigger the PR build to confirm it is environment/flakiness related; the PR's topology changes need no modification. For faster triage next time, capture the gtest failure block (the Failure/Expected lines around the [ RUN ] of that test) as a build artifact, since the Azure tail truncates it.

Related: #11685 (added these tests), #11858 / #11861 / #11864 (temporary PRs explicitly created to diagnose these same Azure protocol-selection test failures), #11902 (UCP/PROTO: Fix buffer copy estimation for CPU-accessible memory), #11940 (rndv-as-fallback change), PR under test: #11990.

Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/ucs/sys/topo/base/topo_int.h Outdated
/**
* Bitmap of system devices.
*/
typedef ucs_static_bitmap_s(UCS_SYS_DEVICE_ID_COUNT) ucs_sys_device_bitmap_t;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: ucs_sys_device_bitmap_t is part of the ucs_topo_build_groups() signature and is now used from UCP (ucp_gpu_nic_assignment.h, ucp_context.c), while topo_int.h is UCS-internal. Can we declare it in topo.h next to ucs_sys_device_t, like the new flags API in this PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems it could be moved to topo.h

Comment thread src/ucp/core/ucp_context.c Outdated
}

static int
ucp_groups_is_net_device_allowed(const ucp_tl_md_t *md,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: the ucp_groups_ prefix does not match any UCP module; maybe ucp_context_is_net_device_allowed() to follow <layer>_<object>_<verb>.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see code suggestion above

@svc-nvidia-pr-review

Copy link
Copy Markdown

Residual gaps: ucp_groups_is_net_device_allowed() (DPU / no-REG / non-NET filtering) still has no unit test because it needs a fake MD, and UCT_IB_DEVICE_FLAG_DPU on real BlueField plus the BF4 id 0xa2df cannot be exercised in CI.

@svc-ucx

svc-ucx commented Sep 29, 2026

Copy link
Copy Markdown

🤖 CI Triage Agent — UCX PR (AddressSanitizer gpu on worker 0) · commit 399fcd97

TL;DR: The ASAN-GPU gtest run failed on a single assertion in shm_ib/test_ucp_proto_am_rndv.am_explicit_scheme_disables_force_provenance/0, a strict RNDV protocol-selection expectation (EXPECT_STREQ("am/rndv", …) / ASSERT_NE(nullptr, remote_proto_config)) that this PR's new NIC/DPU topology filtering perturbs; fix by keeping the gpu-nic-assignment device filtering out of the paths that decide CUDA registration/protocol selection (and/or guard the test with require_cuda_net_md()).

Full analysis

Summary: Azure job "AddressSanitizer gpu on worker 0" (build 137512) — gtest ran 10220 tests, 10219 passed, and make test exited with error 1 because of [ FAILED ] shm_ib/test_ucp_proto_am_rndv.am_explicit_scheme_disables_force_provenance/0, where GetParam() = shm,ib,cuda_copy,rocm_copy. No ASAN report, no timeout, no hang (log timestamps are continuous, the run ends normally at 17:19:26).

Root cause: The failing test (test/gtest/ucp/test_ucp_proto.cc:805-813) runs with RNDV_PIPELINE_SHM_CUDA_STAGING_FORCE=y + RNDV_SCHEME=get_zcopy and then calls check_am_rndv_remote_proto_config(0, 0), which requires that a 1 MB CUDA AM send over shm,ib selects exactly the am/rndv protocol and that no rkey config carries UCP_RKEY_CONFIG_FLAG_PROTO_ESTIMATION (test_ucp_proto.cc:403-459). That expectation depends on an IB/net MD being chosen for CUDA registration, which is computed from the global topology through ucp_context_select_reg_mds() (ucs_topo_is_reachable() / distance + MAX_HCA_PER_GPU, src/ucp/core/ucp_context.c:2018-2119). This PR branch changes exactly that global topology/device-filtering layer: ucp_groups_is_net_device_allowed() now drops aux-only NICs, non-REG MDs and devices flagged UCS_TOPO_DEVICE_FLAG_DPU (src/ucp/core/ucp_context.c:1403-1439, fed into allowed_net_devices at line 1526), and UCS/TOPO: Publish DPU devices in the topology adds new entries/flags to the process-global device inventory (src/ucs/sys/topo/base/topo.c:70-96, topo.h:113-115). With the net device excluded/re-classified, the CUDA 1 MB AM send no longer resolves to am/rndv, so select_am_rndv_remote_proto_config() fails its EXPECT_STREQ and returns nullptr, tripping ASSERT_NE(nullptr, remote_proto_config). Note the test only guards on require_cuda_rndv_support() (RNDV supported) and not on require_cuda_net_md() like its sibling tests, so losing the CUDA-capable network MD turns into a hard failure instead of a skip. (Caveat: the Azure tail only exposes the summary lines; the per-assertion text scrolled out of the retrievable window, so the specific EXPECT that fired is inferred from the test code path.)

Implicated commit: PR #11990 branch topo-assign-ignore-dpu by Guy Ealey Morag — 06b673fa (UCS/TOPO: Publish DPU devices in the topology), 7bf730ac (UCP/CORE: Filter NICs when building topology groups), 526583f5 (Skip aux-only NICs in gpu-nic assignment), head 399fcd9795ae (UCS/TOPO: Use ucs_sys_device_bitmap_t for gpu-nic assignment)

File: src/ucp/core/ucp_context.c:1403-1439 (filtering) and src/ucp/core/ucp_context.c:2018-2119 (ucp_context_select_reg_mds); failing assertions at test/gtest/ucp/test_ucp_proto.cc:438 / :454 reached from test/gtest/ucp/test_ucp_proto.cc:805-813

Suggested fix:

  1. Reproduce in isolation on the GPU node: UCX_LOG_LEVEL=debug ./gtest --gtest_filter='shm_ib/test_ucp_proto_am_rndv.*force_provenance*' and grep for is not allowed for gpu-nic assignment: — this shows which mlx5 device the new filter drops.
  2. Make sure the new allowed_net_devices / DPU filtering is used only for building topology groups and the gpu-nic assignment object, and never narrows context->reg_md_map[UCS_MEMORY_TYPE_CUDA] / device reachability used by protocol selection (i.e. keep ucp_groups_is_net_device_allowed() results local to ucs_topo_build_groups(), do not let the DPU flag change ucs_topo_is_reachable()/distance results for regular ConnectX ports).
  3. Harden the test independently of this PR: add require_cuda_net_md() to test_ucp_proto_am_rndv/test_ucp_proto_rma_rndv provenance tests so a host without a CUDA-registering net MD skips instead of failing.

Related: PR #11990 (this PR); test introduced by #11685; earlier diagnostics of the same test name: #11858, #11861, #11864

Comment thread src/ucs/sys/topo/base/topo_int.h Outdated
/**
* Bitmap of system devices.
*/
typedef ucs_static_bitmap_s(UCS_SYS_DEVICE_ID_COUNT) ucs_sys_device_bitmap_t;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems it could be moved to topo.h

Comment thread src/ucp/core/ucp_context.c Resolved
Comment thread src/ucp/core/ucp_context.c Outdated
}

static int
ucp_groups_is_net_device_allowed(const ucp_tl_md_t *md,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see code suggestion above

}

ucs_status_t
ucs_topo_sys_device_add_flags(ucs_sys_device_t sys_dev, unsigned flags)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor/later PR: seems we have a lot of setter/getter in this file, maybe some macro would help deduplicating eventually

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea

"All ports of a NIC are assigned together, and all GPUs with the same PCI\n"
"address are assigned together (e.g. MLOPart partitions of a GPU).\n"
"NICs without memory registration and DPUs are skipped during assignment.\n"
"NICs excluded by UCX_NET_DEVICES or UCX_TLS are ignored.\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIU tcp lanes are keyed by sys_dev like any other net lane, so they are subject to the gpu/nic assignment. With UCX_TLS=tcp the allowed set is empty and every tcp lane is restricted, and in a mixed run a tcp lane over an mlx5 port resolves to the same sys_dev as the ib device (both go through ucs_topo_get_sysfs_dev() on the same PCI function), so it inherits that NIC's assignment.

Since nothing consumes the assignment yet, maybe fix it on the proto selection side when the restriction lands, either:

  • allow the lane when the restriction would otherwise leave none, or
  • skip the restriction for lanes whose md cannot register the memory, e.g. context->reg_md_map[mem_type]. TCP ranks far behind mlx5 anyway, the actual GPU/NIC assignment use-case.

The second looks simpler and also covers the empty case, so no fallback would be needed, patch can be added to PR #11985 as it is small

Comment thread src/ucp/core/ucp_context.c Outdated
ucs_string_set_t *avail_tls, uint64_t dev_cfg_masks[],
uint64_t *tl_cfg_mask, ucp_tl_info_array_t *all_rscs)
uint64_t *tl_cfg_mask, ucp_tl_info_array_t *all_rscs,
ucs_sys_device_bitmap_t *allowed_net_devices)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: maybe something like assignable_net_device or better in UCP. in build_group() we can keep generic unchanged.

Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/ucp/core/ucp_context.c Resolved
Comment thread src/ucp/core/ucp_context.c Resolved
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

Comment thread src/ucp/core/ucp_context.c Outdated
ucp_context_gpu_nic_assignment_net_device_filter_init(context,
&net_device_filter);
if (UCS_STATIC_BITMAP_IS_ZERO(net_device_filter)) {
ucs_error("no network devices can be used for gpu-nic assignment");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An empty filter is reachable for valid configs — UCX_TLS=shm or UCX_TLS=tcp (TCP md has no UCT_MD_FLAG_REG) leaves no assignable NIC, and then ucp_init() fails. Can we just keep the assignment disabled instead of failing init?

Suggested change
ucs_error("no network devices can be used for gpu-nic assignment");
if (UCS_STATIC_BITMAP_IS_ZERO(net_device_filter)) {
ucs_debug("gpu-nic assignment is disabled: no eligible network devices");
return UCS_OK;
}

(context->gpu_nic_assignment stays NULL, same as the off/non-Vera paths, since the context is ucs_calloc'd.)

typedef ucs_topo_group_array_t ucs_topo_groups_t;


/**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: ucs_sys_device_bitmap_t is a general sys_dev bitmap (UCP uses it for its own NIC bitmaps, unrelated to groups) — maybe define it in topo.h next to ucs_sys_device_t/UCS_SYS_DEVICE_ID_COUNT.

@svc-nvidia-pr-review

Copy link
Copy Markdown

Residual coverage gaps: ucp_context_is_net_device_assignable() (DPU / no-REG / non-NET / aux filtering) has no unit test because it needs a fake MD, and UCT_IB_DEVICE_FLAG_DPU on real BlueField plus the BF4 id 0xa2df cannot be exercised in CI. The empty-filter branch is likewise untested — if it stays as an error, a gtest that sets UCX_GPU_NIC_ASSIGNMENT_MODE=shared with UCX_TLS=shm would pin the intended behavior.

@tvegas1 tvegas1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread src/ucp/core/ucp_context.c Resolved
"All ports of a NIC are assigned together, and all GPUs with the same PCI\n"
"address are assigned together (e.g. MLOPart partitions of a GPU).\n"
"NICs without memory registration and DPUs are skipped during assignment.\n"
"NICs excluded by UCX_NET_DEVICES or UCX_TLS are ignored.\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you would fix it in #11985 right?

Comment thread src/ucp/core/ucp_context.c Resolved
Comment thread src/ucp/core/ucp_context.c Resolved
Signed-off-by: Guy Ealey Morag <gealeymorag@nvidia.com>
@svc-nvidia-pr-review

Copy link
Copy Markdown

🤖 Starting review — findings will be posted here when done.

ucp_context_gpu_nic_assignment_net_device_filter_init(context,
&net_device_filter);
if (UCS_STATIC_BITMAP_IS_ZERO(net_device_filter)) {
if (context->config.ext.gpu_nic_assignment_mode ==

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: mode was already rewritten from auto to flip above, so this has to re-read the config. pls keep an is_auto flag with the other locals and test it here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok as it's reading the ask from user, not its resolution

* @ingroup UCS_RESOURCE
* Bitmap of system devices.
*/
typedef ucs_static_bitmap_s(UCS_SYS_DEVICE_ID_COUNT) ucs_sys_device_bitmap_t;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe move ucs_sys_device_bitmap_t to topo.h next to ucs_sys_device_t? it is not groups-specific and ucp uses it for resource filtering.

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.

4 participants