Skip to content

Commit 8e15c58

Browse files
ymmyysclaude
andcommitted
p2p, net/barex: trim added comments to match FlagCX style
Shorten the comments introduced by the ACCL transport work across the barex net adaptor, the p2p ACCL engine/header, and the Makefile build block so their density matches FlagCX's existing style, keeping the load-bearing notes (CTS seq ordering, listen-handle size, write-with-imm + iflush sentinel, u2mm RTLD_LOCAL plugin requirement). Also collapse a pre-existing 3-line getSharedCq() accessor onto one line so the full-file clang-format check stays clean now that this PR touches flagcx_p2p.cc. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 9c6cae5 commit 8e15c58

5 files changed

Lines changed: 67 additions & 137 deletions

File tree

Makefile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,8 @@ ifeq ($(USE_IBUC), 1)
320320
NET_ADAPTOR_FLAG += -DUSE_IBUC
321321
endif
322322

323-
# ACCL (accl::barex) P2P transport — vendor library for PPU + vsolar
324-
# hosts where peer-mem/DMA-BUF registration is unavailable. Headers and
325-
# libaccl_barex.so ship in the accl-barex devel package (/usr/include,
326-
# /usr/lib). Runtime selection: FLAGCX_P2P_TRANSPORT=accl.
323+
# ACCL (accl::barex) transport for PPU + vsolar hosts lacking peer-mem/DMA-BUF.
324+
# Devel package installs under /usr; select at runtime with FLAGCX_P2P_TRANSPORT=accl.
327325
ifeq ($(USE_ACCL_BAREX), 1)
328326
ACCL_BAREX_HOME ?= /usr
329327
ACCL_BAREX_INCLUDE = $(ACCL_BAREX_HOME)/include

flagcx/adaptor/net/barex_adaptor.cc

Lines changed: 38 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,21 @@
11
/*************************************************************************
22
* Copyright (c) 2026 BAAI. All rights reserved.
33
*
4-
* FlagCX net adaptor "barex" — collective/C2C network transport over the
5-
* vendor ACCL library (accl::barex) for PPU + vsolar hosts.
4+
* FlagCX net adaptor "barex": collective/C2C transport over the vendor
5+
* ACCL library (accl::barex) for PPU + vsolar hosts, where GPU memory
6+
* cannot be registered via peer-mem or DMA-BUF and must go through
7+
* ACCL's RegUserMr / XChannel. Requires FLAGCX_VMM_ENABLE=0 (VMM memory
8+
* is unpinnable) so staging buffers come from cudaMalloc.
69
*
7-
* Why this exists: on PPU (810e), device memory cannot be registered
8-
* through peer-mem or DMA-BUF (the driver stack supports neither), so
9-
* the in-tree IBRC adaptor cannot move GPU buffers. The only supported
10-
* way to pin PPU memory for RDMA is ACCL's XSimpleMempool::RegUserMr;
11-
* data movement must likewise go through ACCL channels. CUDA-VMM memory
12-
* cannot be pinned at all — run with FLAGCX_VMM_ENABLE=0 so staging
13-
* buffers (deviceAdaptor->gdrMemAlloc) come from cudaMalloc.
10+
* Rendezvous (mirrors ibrc's CTS design): connect sends HELLO{commId}
11+
* over an XChannel; irecv posts CTS{slot,addr,size,rkeys,seq}; isend
12+
* answers WriteSingle(imm=slot) and OnImmRecvCall completes the recv
13+
* (write-with-imm orders payload before the imm). Shared state is mutex-
14+
* or atomic-guarded (callbacks run on ACCL IO threads).
1415
*
15-
* Wire protocol (rendezvous, mirroring the ibrc adaptor's CTS design
16-
* with ACCL primitives):
17-
* - connect/accept: the 64-byte listen handle carries the engine's
18-
* OOB IP, the shared barex data port, and a random commId. The
19-
* connector opens an XChannel to the listener and sends HELLO
20-
* {commId}; the acceptor demuxes the channel to the matching
21-
* pending accept.
22-
* - irecv posts CTS {slot, addr, size, per-NIC rkeys} to the sender
23-
* over XChannel::Send (small host message).
24-
* - isend pops a CTS and issues one WriteSingle(signal_peer=true,
25-
* imm_data=slot) straight into the receiver's buffer; the
26-
* receiver's OnImmRecvCall(imm) marks the recv request complete
27-
* (RDMA write-with-imm orders data placement before imm delivery).
28-
* - test() reads an atomic request state; iflush is a no-op (write
29-
* completion on an RC channel implies remote placement; PPU-side
30-
* ordering is the vendor stack's contract, validated by
31-
* barex_benchmark -E data checks).
32-
*
33-
* Threading: connect/accept run on the proxy service thread,
34-
* isend/irecv/test on the proxy progress thread, callbacks on ACCL IO
35-
* threads — every shared structure below is mutex- or atomic-guarded.
36-
*
37-
* Selected at build time via USE_ACCL_BAREX=1 (takes the IBRC registry
38-
* slot, like USE_UCX does); FLAGCX_BAREX_DISABLE=1 falls back to the
39-
* socket adaptor at runtime.
16+
* Built with USE_ACCL_BAREX=1 (IBRC registry slot, like USE_UCX) or
17+
* loaded as a plugin .so (preferred; see the export note below).
18+
* FLAGCX_BAREX_DISABLE=1 opts out at runtime.
4019
************************************************************************/
4120

4221
#ifdef USE_ACCL_BAREX
@@ -152,10 +131,8 @@ struct BarexCtsMsg {
152131
uint64_t size;
153132
uint32_t nKeys;
154133
uint32_t rkeys[kMaxNics];
155-
uint32_t seq; /* receiver's post-order index; sender matches in this order
156-
because CTS are delivered via a multi-threaded callback
157-
pool and may otherwise reorder — see barexIsend/OnRecvCall.
158-
Occupies the struct's former tail padding (size stays 64). */
134+
uint32_t seq; /* receiver's post-order index; sender consumes CTS in
135+
this order (callbacks may reorder). Former padding. */
159136
};
160137
static_assert(sizeof(BarexCtsMsg) == 64, "CTS wire layout must be stable");
161138

@@ -170,9 +147,8 @@ struct BarexNetHandle {
170147
uint32_t state; /* connect-side stage */
171148
uint32_t pad;
172149
void *connectState; /* connect-side heap state across retries */
173-
/* NOTE: transport.cc writes handle->stage.comm (flagcxIbHandle offset
174-
56..64) after bootstrapRecv; our fields end at 56, so that write
175-
lands in the buffer's tail padding. Keep this struct <= 56 bytes. */
150+
/* Keep <= 56 bytes: transport.cc writes stage.comm at offset 56 after
151+
bootstrapRecv, landing in this buffer's tail padding. */
176152
};
177153
static_assert(sizeof(BarexNetHandle) <= 56,
178154
"must not overlap flagcxIbHandle::stage.comm at offset 56");
@@ -232,11 +208,9 @@ struct BarexComm {
232208
std::atomic<bool> dead{false};
233209

234210
std::mutex mu; /* guards ctsPending + slot alloc + seq counters */
235-
/* Sender side: CTS from the receiver, keyed by the receiver's post-order
236-
seq. The sender consumes strictly in seq order (sendExpectedSeq) so a
237-
chunk's data always lands in the buffer the receiver posted for that
238-
same chunk, regardless of the order the callback pool delivered the
239-
CTS. Receiver side: recvSeq stamps each outgoing CTS in post order. */
211+
/* Sender: CTS keyed by the receiver's post-order seq, consumed strictly
212+
in order (sendExpectedSeq) so chunk k lands in the buffer posted for
213+
it regardless of callback delivery order. Receiver: recvSeq stamps. */
240214
std::map<uint64_t, BarexCtsMsg> ctsPending;
241215
uint64_t recvSeq = 0; /* receiver: next CTS seq to stamp */
242216
uint64_t sendExpectedSeq = 0; /* sender: next CTS seq to consume */
@@ -544,9 +518,7 @@ static flagcxResult_t barexGetProperties(int dev, void *props) {
544518
p->name = const_cast<char *>(name);
545519
p->pciPath = nullptr;
546520
p->guid = (uint64_t)dev;
547-
/* GPU staging works because RegUserMr pins cudaMalloc'd PPU memory
548-
(VMM must be off). No DMABUF: the whole point of this adaptor is
549-
that the PPU stack has no dmabuf support. */
521+
/* RegUserMr pins cudaMalloc'd PPU memory (VMM off). PPU has no dmabuf. */
550522
p->ptrSupport = FLAGCX_PTR_HOST | FLAGCX_PTR_CUDA;
551523
p->regIsGlobal = 1; /* MRs live in the engine-wide mempool */
552524
p->speed = (int)flagcxParamBarexSpeed();
@@ -592,8 +564,7 @@ static flagcxResult_t barexListen(int dev, void *opaqueHandle,
592564
}
593565

594566
/* Non-blocking, resumable: *sendComm stays NULL until the channel is up
595-
and HELLO has been delivered. State survives retries inside the
596-
handle (the proxy re-passes the same buffer each call). */
567+
and HELLO delivered; state lives in the handle across retries. */
597568
static flagcxResult_t barexConnect(int dev, void *opaqueHandle,
598569
void **sendComm) {
599570
*sendComm = nullptr;
@@ -876,9 +847,7 @@ static flagcxResult_t barexRegMr(void *comm, void *data, size_t size, int type,
876847
return flagcxSuccess;
877848
}
878849

879-
/* The recv-side proxy calls this unguarded when FLAGCX_DMABUF_ENABLE=1;
880-
the PPU stack has no dmabuf, so treat the fd as irrelevant and pin
881-
through RegUserMr like regMr does. */
850+
/* PPU has no dmabuf; ignore the fd and pin through RegUserMr like regMr. */
882851
static flagcxResult_t barexRegMrDmaBuf(void *comm, void *data, size_t size,
883852
int type, uint64_t offset, int fd,
884853
int mrFlags, void **mhandle) {
@@ -931,13 +900,9 @@ static flagcxResult_t barexIsend(void *sendComm, void *data, size_t size,
931900
BarexRequest *req = nullptr;
932901
{
933902
std::lock_guard<std::mutex> lk(comm->mu);
934-
/* Consume CTS strictly in the receiver's post order. The proxy calls
935-
isend once per chunk in increasing chunk index, so chunk k must pair
936-
with the CTS the receiver posted for its k-th irecv (seq == k). If
937-
that CTS has not arrived yet (the callback pool may deliver a later
938-
seq first), leave sendExpectedSeq untouched and let the proxy retry —
939-
do NOT pair this chunk with a different CTS or the data lands in the
940-
wrong buffer. */
903+
/* Consume CTS in receiver post order (seq == chunk index). If the
904+
expected seq hasn't arrived, leave sendExpectedSeq and let the proxy
905+
retry — never pair a chunk with a different CTS. */
941906
auto it = comm->ctsPending.find(comm->sendExpectedSeq);
942907
if (it == comm->ctsPending.end())
943908
return flagcxSuccess; /* CTS for this chunk not here yet — retry */
@@ -949,9 +914,7 @@ static flagcxResult_t barexIsend(void *sendComm, void *data, size_t size,
949914
comm->sendExpectedSeq++;
950915
}
951916

952-
/* Receiver posted cts.size; both sides run the same chunk schedule so
953-
sizes agree, but clamp for safety (ibrc semantics: send truncates
954-
to the posted recv size). */
917+
/* Clamp to the posted recv size (ibrc semantics: send truncates). */
955918
const size_t wsize = size < cts.size ? size : (size_t)cts.size;
956919
req->size = wsize;
957920

@@ -1057,13 +1020,9 @@ static flagcxResult_t barexIrecv(void *recvComm, int n, void **data,
10571020
return flagcxSuccess;
10581021
}
10591022

1060-
/* Write completion on an RC channel implies remote placement, and
1061-
write-with-imm orders payload before the imm that completes the recv
1062-
request; the vendor stack owns NIC->PPU visibility (validated by
1063-
barex_benchmark -E). Nothing to flush — but the IBRC-slot consumer
1064-
(net.cc flagcxProxyRecv) only advances its flush stage when a request
1065-
is returned, so hand back the shared (void*)0x1 sentinel the caller
1066-
already special-cases as "instantly done" before calling test(). */
1023+
/* Nothing to flush: write-with-imm orders payload before the completing
1024+
imm. Return the (void*)0x1 sentinel because the IBRC-slot consumer
1025+
(net.cc flagcxProxyRecv) only advances its flush stage on a request. */
10671026
static flagcxResult_t barexIflush(void *recvComm, int n, void **data,
10681027
int *sizes, void **mhandles, void **request) {
10691028
(void)recvComm;
@@ -1086,9 +1045,8 @@ static flagcxResult_t barexTest(void *request, int *done, int *sizes) {
10861045
if (st == BAREX_REQ_PENDING)
10871046
return flagcxSuccess;
10881047
if (st == BAREX_REQ_ERROR) {
1089-
/* Sticky: the proxy ignores test()'s return code and would re-test
1090-
the same pointer, so the slot must not be recycled. The comm is
1091-
broken; surface the error every call. */
1048+
/* Sticky: proxy re-tests the same pointer, so don't recycle the slot;
1049+
surface the error every call. */
10921050
return flagcxInternalError;
10931051
}
10941052
*done = 1;
@@ -1121,8 +1079,8 @@ static flagcxResult_t barexGetDevFromName(char *name, int *dev) {
11211079

11221080
} // namespace barexnet
11231081

1124-
/* One-sided iput/iget/iputSignal serve the P2P/one-sided engine, not
1125-
the proxy collective path — left NULL like the UCX adaptor. */
1082+
/* One-sided iput/iget/iputSignal serve the P2P engine, not the proxy
1083+
collective path — left NULL like the UCX adaptor. */
11261084
struct flagcxNetAdaptor flagcxNetBarex = {
11271085
// Basic functions
11281086
"BAREX", barexnet::barexInit, barexnet::barexDevices,
@@ -1154,13 +1112,10 @@ struct flagcxNetAdaptor flagcxNetBarex = {
11541112
NULL, // igetBatch
11551113
};
11561114

1157-
/* Plugin export (FLAGCX_NET_ADAPTOR_PLUGIN mechanism, v1 vtable).
1158-
IMPORTANT deployment note: prefer loading barex as a plugin .so rather
1159-
than linking libaccl_barex into libflagcx. The plugin loader dlopens
1160-
with RTLD_LOCAL, which keeps libaccl_barex's dependency libu2mm.so out
1161-
of the global symbol table — libpccl's internal u2mm implementation
1162-
resolves against a globally visible libu2mm and crashes in
1163-
wrap_u2mm_symbols during pcclCommInitRank otherwise. */
1115+
/* Plugin export (FLAGCX_NET_ADAPTOR_PLUGIN, v1 vtable). Prefer this over
1116+
linking libaccl_barex into libflagcx: the loader uses RTLD_LOCAL, keeping
1117+
libu2mm.so out of the global symbol table — otherwise libpccl's own u2mm
1118+
crashes in wrap_u2mm_symbols during pcclCommInitRank. */
11641119
extern "C" __attribute__((visibility(
11651120
"default"))) struct flagcxNetAdaptor_v1 flagcxNetAdaptorPlugin_v1 = {
11661121
"BAREX",

flagcx/core/flagcx_p2p.cc

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -524,9 +524,7 @@ class FlagcxWorkerPool {
524524
FlagcxWorkerPool(const FlagcxWorkerPool &) = delete;
525525
FlagcxWorkerPool &operator=(const FlagcxWorkerPool &) = delete;
526526

527-
struct ibv_cq *getSharedCq() const {
528-
return shared_cq_;
529-
}
527+
struct ibv_cq *getSharedCq() const { return shared_cq_; }
530528
int workerCount() const { return numWorkers_; }
531529
void registerQp(void *sendComm, struct ibv_qp *qp);
532530
void unregisterQp(struct ibv_qp *qp);
@@ -2040,10 +2038,8 @@ static int bootstrapExchangeDescTable(struct bootstrapState *bsState,
20402038
}
20412039

20422040
FlagcxP2pEngine *flagcxP2pEngineCreate() {
2043-
/* FLAGCX_P2P_TRANSPORT=accl routes the whole engine to the ACCL
2044-
(accl::barex) transport — required on PPU+vsolar hosts. Default is
2045-
the existing ibrc path; every entry point below checks the engine/
2046-
conn kind tag and forwards, so callers see one unchanged API. */
2041+
/* FLAGCX_P2P_TRANSPORT=accl routes the engine to the ACCL transport
2042+
(PPU+vsolar); default is ibrc. Entry points forward by kind tag. */
20472043
const char *transport = flagcxGetEnv("FLAGCX_P2P_TRANSPORT");
20482044
if (transport != NULL && strcasecmp(transport, "accl") == 0) {
20492045
#ifdef USE_ACCL_BAREX

flagcx/core/flagcx_p2p_accl.cc

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,21 @@
11
/*************************************************************************
22
* Copyright (c) 2026 BAAI. All rights reserved.
33
*
4-
* FlagCX P2P engine — ACCL (accl::barex) transport implementation.
4+
* FlagCX P2P engine: ACCL (accl::barex) transport for PPU + vsolar
5+
* hosts, where GPU memory can only be registered and moved through
6+
* ACCL (no peer-mem/DMA-BUF; VMM unpinnable — run FLAGCX_VMM_ENABLE=0).
57
*
6-
* On PPU (810e) + vsolar RDMA hosts, device memory can only be
7-
* registered and moved through the vendor ACCL library: peer-mem and
8-
* DMA-BUF registration are not supported by the driver stack, and
9-
* CUDA-VMM memory cannot be pinned at all (run with
10-
* FLAGCX_VMM_ENABLE=0 so buffers come from cudaMalloc).
8+
* Shape mirrors Mooncake's barex_transport: one XSimpleMempool over the
9+
* selected NICs (RegUserMr returns one MR/rkey per NIC); one server +
10+
* client XContext per NIC; XListener/XConnector own setup (no QP here);
11+
* transfers post via XChannel::WriteBatch/ReadBatch with callback
12+
* completion (no CQ poll); the per-slice remote key comes from the
13+
* region's per-NIC rkey vector via channel->GetPeerNicId().
1114
*
12-
* Shape mirrors Mooncake's barex_transport:
13-
* - one XSimpleMempool over the selected NICs; RegUserMr returns one
14-
* MR (lkey/rkey) per NIC,
15-
* - one server + one client XContext per NIC; XListener/XConnector
16-
* own connection setup (no QP handling here),
17-
* - transfers post through XChannel::WriteBatch/ReadBatch; completion
18-
* arrives on ACCL threads via callbacks (no CQ polling),
19-
* - the remote key for a slice is picked at post time by
20-
* channel->GetPeerNicId() from the region's per-NIC rkey vector.
21-
*
22-
* Peer rendezvous reuses FlagCX's bootstrap sockets with an
23-
* ACCL-specific hello (barex data port + notif port); the desc table
24-
* carries rkey VECTORS. Both ends of a connection must run this
25-
* transport — the hello magic rejects an ibrc peer explicitly.
26-
*
27-
* The 64-byte FlagcxP2pRdmaDesc is kept: rkeys[0] sits in .rkey (same
28-
* offset ibrc uses), the key count in .nmsgs, rkeys[1..7] in .padding.
29-
* Serialize/Deserialize/UpdateDesc work unchanged.
30-
*
31-
* v1 limits: transfers are initiated by the connecting side only (the
32-
* NIXL/PD-disaggregation pattern); no IPC fast path; two-sided
33-
* send/recv unsupported.
15+
* Rendezvous reuses FlagCX bootstrap with an ACCL hello (magic rejects
16+
* ibrc peers). The 64-byte FlagcxP2pRdmaDesc is kept: rkeys[0] at ibrc's
17+
* .rkey offset, count in .nmsgs, rkeys[1..7] in .padding. v1: transfers
18+
* initiated by the connecting side only; no IPC path; no two-sided.
3419
************************************************************************/
3520

3621
#ifdef USE_ACCL_BAREX
@@ -934,10 +919,9 @@ FlagcxP2pConn *flagcxAcclEngineConnect(FlagcxP2pEngine *e, const char *ipAddr,
934919
(void)remoteGpuIdx;
935920
(void)sameProcess; /* v1: no IPC fast path */
936921

937-
/* data-plane channels: qpsPerCtx per client context. The control
938-
block is shared with the callbacks; if we time out and move on, a
939-
late callback sees `abandoned` and destroys its channel instead of
940-
touching freed state. */
922+
/* data-plane channels: qpsPerCtx per client ctx. Control block shared
923+
with callbacks; on timeout a late callback sees `abandoned` and
924+
destroys its own channel instead of touching freed state. */
941925
const int qps = (int)flagcxParamP2pAcclQpsPerCtx();
942926
const int total = qps * (int)engine->clientCtxs.size();
943927
auto ctl = std::make_shared<AcclConnectCtl>(total);

flagcx/core/include/flagcx_p2p_accl.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
/*************************************************************************
22
* Copyright (c) 2026 BAAI. All rights reserved.
33
*
4-
* FlagCX P2P engine — ACCL (accl::barex) transport.
4+
* FlagCX P2P engine — ACCL (accl::barex) transport (internal header).
55
*
6-
* Internal header. The public flagcx_p2p.h API stays unchanged; the
7-
* entry points in flagcx_p2p.cc route to this transport when the engine
8-
* was created with FLAGCX_P2P_TRANSPORT=accl. Every internal engine /
9-
* connection struct starts with a uint32_t kind tag so the shared entry
10-
* points can tell the transports apart without knowing their layouts.
6+
* The public flagcx_p2p.h API stays unchanged; flagcx_p2p.cc routes to
7+
* this transport when the engine is created with FLAGCX_P2P_TRANSPORT=accl.
8+
* Every internal engine/conn struct starts with a uint32_t kind tag so the
9+
* shared entry points can tell the transports apart.
1110
*
12-
* Built only when USE_ACCL_BAREX=1 (links against libaccl_barex, the
13-
* vendor library required for memory registration and RDMA on PPU +
14-
* vsolar hosts, where standard peer-mem / DMA-BUF registration is not
15-
* available). Without it the stubs below keep the dispatch sites
16-
* compiling and FLAGCX_P2P_TRANSPORT=accl fails engine creation.
11+
* Built only when USE_ACCL_BAREX=1 (links libaccl_barex, required for
12+
* memory registration and RDMA on PPU + vsolar). Otherwise the stubs
13+
* below keep the dispatch sites compiling and accl engine creation fails.
1714
************************************************************************/
1815

1916
#ifndef FLAGCX_P2P_ACCL_H_

0 commit comments

Comments
 (0)