Skip to content

[cudax] __sharded: places communicator (a places-backed model of the multi-GPU communicator concept) + the engine-bindings adapter - #5

Open
caugonnet wants to merge 20 commits into
sharded/devfrom
sharded/communicator
Open

[cudax] __sharded: places communicator (a places-backed model of the multi-GPU communicator concept) + the engine-bindings adapter#5
caugonnet wants to merge 20 commits into
sharded/devfrom
sharded/communicator

Conversation

@caugonnet

Copy link
Copy Markdown
Owner

Stacked on #4 (review this diff against sharded/dev).

This PR connects the two rungs at the top of the cooperation-scope ladder. The MGMN algorithms (__multi_gpu) program the ranks rung against a duck-typed communicator concept; this PR adds a places-backed model of that concept, so the same constructs run unmodified over in-process places (locality domains, green-context places, devices-as-places) — and the adapter that lets sharded containers drive them.

What's in the PR

  • __sharded/communicator.cuh:
    • places_communicator / basic_places_communicator: each place of a place_group is one rank (rank = place index, native_handle() = the place). Because the places of one process share a virtual address space, the verbs lower to device-to-device copies (send/recv rendezvous-matched inside a group guard, all_gather[_v], all_to_all[_v]) and all_reduce to a single fold kernel that combines every rank's partial in fixed rank order — bit-identical results run to run for a fixed place list. The basic variant omits all_reduce, so both MGMN combine paths (direct all_reduce, and all_gather + local combine) stay reachable and tested.
    • logical_device() returns a place-backed model of the {context(), underlying_device()} pair the MGMN algorithms activate and select resources through.
    • make_communicators(place_group&) (and an explicit-place-list overload): one communicator per place, one shared group state. Groups spanning devices are refused with a diagnostic — that composition belongs to a hierarchical transport tier, not to this rung.
    • Concept conformance is stated in code: static_asserts against the __multi_gpu concepts (__communicator, __has_all_reduce present/absent per variant, __has_all_gather[_v], __has_all_to_all[_v]).
    • bind_engine(group, sharded_array): the two-tier seam. The container tier owns placement and resources; the engine tier owns cross-place choreography. This adapter manufactures what an MGMN engine consumes — one communicator, environment (stream + per-place memory resource), iterator and size per shard.
  • __places/place_group.cuh: place_memory_resource gains default_queries (device_accessible) and host/device-annotated stream-ordered allocate/deallocate (terminating on device, the CUB device_memory_resource idiom), so the per-place resources travel through environments into CUB_RUNTIME_FUNCTION dispatch and cuda::buffer-based engine temporaries. Net effect: engine scratch is allocated on the place whose rank uses it.
  • Only the vendor-free __multi_gpu/concepts.h is included; the umbrella sharded.cuh stays buildable with NCCL disabled.

Tests (cudax/test/sharded/communicator/)

  • concepts.cu: the conformance static_asserts + factory contract (rank/size/order, native handle identity, empty-list refusal).
  • verbs.cu (2 locality domains): send/recv rendezvous, all_gather correctness, all_reduce correctness on random fp32 + broadcast bitwise agreement across ranks + bit-determinism over 5 repeated runs (the fixed fold order, checked).
  • bridge.cu — the conformance evidence as CI: cuda::experimental::reduce (the MGMN range API) running over communicators and environments manufactured from a sharded_array by bind_engine, on 2 locality domains with uneven shards, checked against a single-place CUB DeviceReduce reference and an fp64 host reference, through both combine paths, with bit-determinism across 5 runs per path.

All places + sharded tests green on GB300 (sm_103a, CUDA 13.4, 2 locality domains): 27/27 ctest, examples and header tests included; built with -Dcudax_ENABLE_NCCL=OFF.

Design review with Andrei.

🤖 Generated with Claude Code

…lti-GPU communicator concept + the engine-bindings adapter

Each place of a place_group becomes one rank of the __multi_gpu
communicator concept (rank = place index, native_handle = the place), so
the MGMN range algorithms run unmodified over in-process places. On this
rung the ranks share one virtual address space, so the verbs lower to
device-to-device copies and all_reduce to a single fixed-order fold
kernel (bit-identical results run to run). Two variants keep both MGMN
combine paths exercised: places_communicator (all_reduce) and
basic_places_communicator (all_gather + local combine).

bind_engine(group, sharded_array) is the two-tier seam: the container
tier manufactures what the engine tier consumes -- communicators,
environments (stream + per-place memory resource), per-shard iterators
and sizes.

place_memory_resource gains default_queries/device_accessible and
host/device-annotated stream-ordered allocate/deallocate (terminate on
device), so it can travel through environments into CUB_RUNTIME_FUNCTION
dispatch and cuda::buffer-based engine temporaries -- scratch lands on
the place that runs the work.

Tests: concept conformance static_asserts (all_reduce present/absent per
variant), verbs correctness on locality domains (send/recv rendezvous,
all_gather, all_reduce + bit-determinism over repeated runs), and the
bridge test: cuda::experimental::reduce over communicators and envs
manufactured from a sharded_array on 2 locality domains, checked against
a single-place CUB reference, through both combine paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
caugonnet and others added 19 commits August 22, 2026 06:51
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflict resolution: the stream-ordered deallocate keeps the
NV_IF_ELSE_TARGET host/device split (device terminates) with the
non-throwing host branch inside it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflict resolution: the level's place_memory_resource enrichments
(device_accessible default_queries + get_property, HD-annotated
stream-ordered allocate/deallocate) move WITH the class into the new
__places/place_memory_resource.cuh; place_group.cuh keeps no copy. The
terminate/nv-target includes travel with the class.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflict resolution: the HD-annotated allocate/deallocate keep the
NV_IF_ELSE_TARGET split with the round-3 semantics inside the host
branch (alignment validation; deallocation failure report + debug
assert).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflict resolution: the HD allocate/deallocate keep the
NV_IF_ELSE_TARGET structure with the round-5 semantics (PTRDIFF_MAX
guard, const locals) inside the host branches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…review)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.

1 participant