Skip to content

TL/CUDA: add support for ucc mem map - #1315

Open
wfaderhold21 wants to merge 3 commits into
openucx:masterfrom
wfaderhold21:topic/tlcuda-mem-map
Open

TL/CUDA: add support for ucc mem map#1315
wfaderhold21 wants to merge 3 commits into
openucx:masterfrom
wfaderhold21:topic/tlcuda-mem-map

Conversation

@wfaderhold21

Copy link
Copy Markdown
Collaborator

What

Adds support for ucc_mem_map with TL/CUDA by implementing ucc_tl_cuda_mem_map, ucc_tl_cuda_memh_pack, and ucc_tl_cuda_mem_unmap. Additionally, adds an alltoall and alltoallv algorithm that takes advantage of the memory handles.

@janjust

janjust commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

risk is low - only there when you call ucc_memmap() and pass memhandle, AND use this algo. so pretty minimal.

@janjust
janjust force-pushed the topic/tlcuda-mem-map branch from 6ade86f to fe6af93 Compare June 3, 2026 17:20
@wfaderhold21
wfaderhold21 force-pushed the topic/tlcuda-mem-map branch from 57db563 to 11caf1c Compare July 27, 2026 15:55
@svcnbu-swx-hpcx

Copy link
Copy Markdown
Collaborator

🤖 CI Triage AgentLint (codestyle) · commit ddd923cf

TL;DR: The codestyle "commit title" check failed because 7 of the 9 commits in PR #1315 have titles longer than the 50-character limit; the fix is to reword those commit titles to ≤50 chars (or ≤50 excluding the prefix) and force-push.

Full analysis

Summary: The Lint (codestyle) GitHub Actions job (codestyle.yamlcodestyle job) failed at the commit-title check step with exit code 1.

Root cause: The workflow's check_title bash function rejects any commit title longer than 50 characters (unless it starts with Merge). Seven commits in the branch exceed that limit, each printing Commit title is too long: <N> and setting ok=0, which makes the script exit 1. The offending titles and lengths from the log:

  • TEST/MPI: fix global memh and mem-map test lifecycle (52)
  • TEST: fix class redefinitions in test_mem_map.cc and clang-tidy unused parameters (81)
  • TEST: fix UccJob to preserve caller-provided env vars for CUDA TL push tests (76)
  • TEST/MPI: add dispatch hook for test_mem_map.cc so mem_map tests execute (72)
  • TEST/MPI: add user memh registration (local + global) for collectives (69)
  • TEST: fix tl/cuda push gtest teardown UAF and 64-bit count flags (64)
  • TL/CUDA: reject non-fully-connected topos in push; fix perftest memh alloc (74)

The two commits under 50 chars passed. This is purely a commit-message hygiene failure, not a code/test defect. (Note: the check measures the entire title including the TEST/MPI: prefix.)

Implicated commit: The failing HEAD is ddd923cf (author of PR #1315, "TEST/MPI: fix global memh and mem-map test lifecycle"), but the failure spans all 7 long-titled commits in the branch — not one specific commit.

File: .github/workflows/codestyle.yaml (the check_title step; enforces [ ${#msg} -gt 50 ])

Suggested fix: Interactively rebase the branch (git rebase -i remotes/origin/<base>) and reword each of the 7 titles to ≤50 characters, keeping a valid header prefix (e.g. TEST/MPI: fix memh + mem-map test lifecycle, TEST: fix class redefs in test_mem_map.cc, TEST: preserve caller env vars in UccJob, TL/CUDA: reject non-fully-connected topos in push), then force-push. Move the extra detail into the commit body. No source-code change is required.

Related: none found (deterministic lint rule in .github/workflows/codestyle.yaml).

@wfaderhold21
wfaderhold21 force-pushed the topic/tlcuda-mem-map branch from ddd923c to cfbfa69 Compare July 31, 2026 21:27
@svcnbu-swx-hpcx

Copy link
Copy Markdown
Collaborator

🤖 CI Triage AgentLint (codestyle) · commit cfbfa691

TL;DR: The codestyle commit-title lint failed because commit cfbfa691 uses the prefix TEST/MPI:, which isn't an allowed header token; rename it (e.g. TEST: MPI add user memh reg (local + global)) to pass.

Full analysis

Summary: The codestyle GitHub Actions job's commit-title check rejected the PR's HEAD commit title as having a "Wrong header".

Root cause: The commit-title validator (inline script in codestyle.yaml) checks each commit against ^((H1)|(H2))+: \w, where the only slash-form component prefixes allowed are CL/, TL/, MC/, EC/. The title TEST/MPI: add user memh reg. (local + global) uses TEST/MPI, and MPI (and the TEST/ slash form) is not in the allowed token set, so the regex fails to match → Wrong header → exit code 1. The other two commits (TEST: ... and TL/CUDA: ...) matched and passed.

Implicated commit: [REDACTED:Hex High Entropy String] — "TEST/MPI: add user memh reg. (local + global)" (PR #1315 author). This is a bad commit title, not a code bug.

File: .github/workflows/codestyle.yaml (the check_title script; header token lists H1/H2).

Suggested fix: Reword the offending commit title to use a valid prefix, e.g. TEST: add user memh reg (local + global) for MPI (also drop the trailing . — note the checker separately rejects titles ending in .). Amend/rebase the commit and force-push:

git rebase -i remotes/origin/master   # reword cfbfa691
git push --force-with-lease

Alternatively, if TEST/MPI-style prefixes are intended to be legal, add MPI (or a TEST/ slash form) to the H2/H1 token lists in codestyle.yaml — but the simpler, PR-scoped fix is renaming the commit.

Related: none found (didn't need issue search — the failure is fully explained by the log).

Note: the git-credentials AUTHORIZATION header appears redacted (***) in the log; no secret exposure to report.

🛡️ This comment had 1 potential secret(s) redacted (Hex High Entropy String). See request_id d324b889-32a6-4d76-b948-e04f0fce5d3f in the triage console for the audit trail.

@svcnbu-swx-hpcx

Copy link
Copy Markdown
Collaborator

🤖 CI Triage AgentLint (codestyle) · commit 75eabbce

TL;DR: The codestyle job's commit-title check rejected the commit TEST/MPI: fix mem_map test issues because MPI is not an allowed component sub-tag; fix by renaming the commit title to use a valid header (e.g. TEST: fix MPI mem_map test issues).

Full analysis

Summary: The codestyle GitHub Actions job failed at the commit-title lint step with Wrong header / Bad commit title: 'TEST/MPI: fix mem_map test issues'.

Root cause: The lint script validates each commit title against an allowed header regex built from two lists:

  • H1="CODESTYLE|REVIEW|CORE|UTIL|TEST|API|DOCS|TOOLS|BUILD|MC|EC|SCHEDULE|TOPO"
  • H2="CI|CL/|TL/|MC/|EC/|UCP|SHM|NCCL|SHARP|BASIC|HIER|DOCA_UROM|CUDA|CPU|EE|RCCL|ROCM|SELF|MLX5"

The regex ^((H1)|(H2))+: \w allows tags like TEST: or TL/CUDA: but there is no MPI token and TEST is not permitted to take a /SUBCOMPONENT suffix. The title TEST/MPI: ... therefore matches neither TEST: (because of the /MPI) nor any slash-prefixed H2 tag, so the check emits "Wrong header" and exits 1. The other three commits (TEST:, TL/CUDA:) match and pass.

Implicated commit: [REDACTED:Hex High Entropy String] — "TEST/MPI: fix mem_map test issues" (HEAD of topic/tlcuda-mem-map, PR #1315). This is not a code defect; it's a non-conforming commit message.

File: .github/workflows/codestyle.yaml (the check_title step / regex); the offending input is the commit title itself.

Suggested fix: Reword the commit title to conform to the allowed header format. Options:

  • TEST: fix MPI mem_map test issues (uses the valid TEST: tag), or
  • TEST/MPI is not valid — if an MPI sub-scope is genuinely desired, add MPI to the H2 list in codestyle.yaml and allow TEST/ prefixing. The simplest fix is to amend the commit: git rebase -i → reword to TEST: fix MPI mem_map test issues, then force-push.

Related: none found.

🛡️ This comment had 1 potential secret(s) redacted (Hex High Entropy String). See request_id a544e875-4312-40a3-b4db-05e7733267df in the triage console for the audit trail.

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds TL/CUDA memory-map support and push-based alltoall/alltoallv algorithms that consume globally exchanged CUDA memory handles.

  • Implements CUDA memory-handle export, packing, import, and unmapping.
  • Adds push algorithms with topology checks, CUDA IPC mapping, synchronized completion, and error cleanup.
  • Extends MPI tests and performance tooling to create, exchange, attach, and release mapped handles.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/components/tl/cuda/tl_cuda_context.c Implements CUDA memory-handle mapping, serialization, bounded import parsing, and unmapping; the core importer now rejects truncated and oversized records before invoking it.
src/core/ucc_context.c Adds serialized-buffer length tracking and subtraction-based record validation before dispatching imported handles to transport components.
src/components/tl/cuda/alltoallv/alltoallv_push.c Implements the shared push state machine, peer IPC mapping, completion synchronization, topology gating, and balanced setup-error cleanup.
src/components/tl/cuda/alltoall/alltoall_push.c Adapts the push state machine to uniform alltoall counts and globally mapped destination handles.
tools/perf/ucc_pt_coll_alltoallv.cc Exchanges and imports global handles while preserving identical cross-rank collective ordering and synchronizing failures before cleanup.
test/gtest/core/test_mem_map.cc Extends core coverage for memory-handle serialization and import behavior.

Reviews (4): Last reviewed commit: "TL/CUDA: a2av push: pass raw mapped addr..." | Re-trigger Greptile

Comment on lines +238 to +253
if (strncmp(tl_name, "cuda", UCC_MEM_MAP_TL_NAME_LEN) == 0 &&
*packed_size > 0) {
/* Format: [ipc_handle] [base_address] [length] [offset] */
size_t poff = 0;
memcpy(&m_data->ipc_handle,
PTR_OFFSET(packed_data, poff),
sizeof(cudaIpcMemHandle_t));
poff += sizeof(cudaIpcMemHandle_t);
memcpy(&m_data->base_address,
PTR_OFFSET(packed_data, poff), sizeof(void *));
poff += sizeof(void *);
memcpy(&m_data->length,
PTR_OFFSET(packed_data, poff), sizeof(size_t));
poff += sizeof(size_t);
memcpy(&m_data->offset,
PTR_OFFSET(packed_data, poff), sizeof(ptrdiff_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.

P1 security Imported handle bounds missing

When an imported CUDA record has a nonzero packed_size but does not contain the complete fixed payload, this code unconditionally reads the IPC handle, pointer, length, and offset beyond the record, causing an out-of-bounds host read or corrupted mapping state. Validate both the record size and aggregate buffer bounds before reading. How this was verified: The import callback receives no available-length bound and performs every fixed-size copy after checking only that packed_size is nonzero.

Comment on lines +348 to +359
status = ucc_tl_cuda_map_memhandle(
peer_mi.ptr, peer_mi.length, peer_mi.handle, &mapped, cache);
if (ucc_unlikely(status != UCC_OK)) {
return status;
}
task->alltoallv_push.peer_map_addr[i] = PTR_OFFSET(mapped, peer_mi.offset);
}

status = ucc_ec_create_event(&task->alltoallv_push.evt_completion,
UCC_EE_CUDA_STREAM);
if (ucc_unlikely(status != UCC_OK)) {
return status;

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.

P1 Partial setup leaks mappings

When mapping a later peer or creating the completion event fails after earlier peer mappings succeeded, this function returns without decrementing those mappings' cache references. Because the finalize callback is installed only after setup completes, repeated initialization failures leave IPC mappings open and eventually exhaust CUDA IPC or cache resources; unwind every previously acquired mapping on these error paths.

Knowledge Base Used: Transport-layer components

Comment on lines +114 to +117
for (int i = 0; i < comm->get_size(); i++) {
ucc_mem_map(ctx, UCC_MEM_MAP_MODE_IMPORT, &mem_map_params,
&dst_memh_size_max, &dst_memh_global[i]);
}

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.

P1 Import failures are ignored

When any global destination or source handle import fails, setup ignores the returned status and still attaches that handle array to the collective arguments. The benchmark then proceeds with unusable peer handles, causing collective initialization failure or invalid-handle access instead of reporting and cleaning up the mapping error; apply the same checked error path used for exports to every import.

Knowledge Base Used: Performance benchmarking

/* Format: [ipc_handle] [base_address] [length] [offset] */
size_t poff = 0;

if (*packed_size < UCC_TL_CUDA_MEMH_PACKED_SIZE) {

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.

P1 security Handle bounds remain unchecked

When an imported handle declares a sufficiently large CUDA payload but the aggregate serialized buffer is truncated or a preceding record advances beyond it, this check passes and the subsequent copies read outside the buffer, causing a crash or corrupted mapping state. Validate each record header and payload against the total imported blob length before reading or advancing. How this was verified: The parser derives every header and payload from an unbounded offset, while its callback input provides no available packed-buffer length.

Knowledge Base Used: Transport-layer components

Comment thread tools/perf/ucc_pt_coll_alltoallv.cc Outdated
Comment on lines +117 to +125
if (st != UCC_OK) {
/* Import failed: dst_memh_global[i] is still a raw serialized
* blob, not a valid handle. Free it and any not-yet-imported
* entries so the error path only unmaps valid handles. */
for (int j = i; j < comm->get_size(); j++) {
ucc_free(dst_memh_global[j]);
dst_memh_global[j] = NULL;
}
goto exit;

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.

P1 Import failures diverge ranks

When handle import fails on one rank but succeeds on another, this rank jumps directly to cleanup and throws without communicating the failure, while successful peers proceed to the next team barrier. The failed rank enters communicator teardown instead of that barrier, causing the benchmark to hang or terminate abnormally; synchronize import status across ranks before either teardown or timed collectives begin.

Knowledge Base Used: Performance benchmarking

TL/CUDA: add push algorithm

TL/CUDA: add alltoallv memh

TEST: MPI add user memh reg. (local + global)

TEST/MPI: add dispatch hook for test_mem_map.cc so mem_map tests execute

TEST/MPI: fix global memh and mem-map test lifecycle

TL/CUDA: unify alltoall/alltoallv push algorithms
}
}

if (!is_inplace) {

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.

P1 Import failures still diverge ranks

When destination-handle import fails on one rank in a non-in-place benchmark, that rank advances to the failure-status allreduce while successful ranks first enter the source-size allreduce and source-handle broadcasts. The mismatched collective sequence leaves successful ranks waiting in an unmatched broadcast, causing the benchmark to hang.

Knowledge Base Used:

A local dst/src handle export failure used UCCCHECK_GOTO(exit), tearing down one rank while peers advanced into the size allreduce and handle bcasts, hanging the benchmark. Route export failures through the existing map_failed flag so every rank reaches the failure-status allreduce together. Also pass a size_t temp to ucc_mem_map's memh_size out-param (matching its signature) while keeping uint64_t operands for the UCC_DT_UINT64 allreduce.
peer_map_addr stored the offset-adjusted peer rbuf base, but ucc_tl_cuda_unmap_memhandle expects the raw cudaIpcOpenMemHandle address as mapped_addr (used for cudaIpcCloseMemHandle when refcount hits 0 and force=1). Store the raw address in a new peer_map_raw field and pass it to both unmap sites.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants