Skip to content

Commit 5cc6c42

Browse files
authored
[CRL] Deprecate flagcxHandlerGroup, separate device handle/uniqueId/comm lifecycle (#480)
1 parent dd42338 commit 5cc6c42

56 files changed

Lines changed: 448 additions & 504 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

flagcx/adaptor/include/device_api/sunrise_comm_traits.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@
77
#ifndef FLAGCX_SUNRISE_COMM_TRAITS_H_
88
#define FLAGCX_SUNRISE_COMM_TRAITS_H_
99

10-
// Sunrise/PCCL inner-type stubs: never populated at runtime on the
11-
// sunrise path; only here to satisfy public type signatures.
12-
struct flagcxInnerWindow {
13-
int winFlags;
14-
};
15-
struct flagcxInnerDevComm {};
16-
1710
// Sunrise default backend: reuse Default<DefaultPlatform> (IPC barriers +
1811
// FIFO one-sided). PCCL/PTPU already provide collectives, so FlagCX needs
1912
// no SIMT kernels of its own.

flagcx/adaptor/include/sunrise_adaptor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
#include "tang.h"
88
#include "tang_runtime.h"
99
#include <map>
10+
11+
struct flagcxInnerWindow {
12+
int winFlags;
13+
};
14+
struct flagcxInnerDevComm {};
15+
1016
struct flagcxInnerComm {
1117
pcclComm_t base;
1218
};

flagcx/flagcx.cc

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -156,44 +156,61 @@ bool useHeteroComm() {
156156
return false;
157157
}
158158

159-
flagcxResult_t flagcxHandleInit(flagcxHandlerGroup_t *handler) {
159+
flagcxResult_t flagcxDeviceHandleInit(flagcxDeviceHandle_t *devHandle) {
160+
if (devHandle == NULL) {
161+
WARN("flagcxDeviceHandleInit: devHandle is NULL");
162+
return flagcxInvalidArgument;
163+
}
160164
flagcxResult_t res = flagcxSuccess;
161165
flagcxDeviceAdaptorPluginInit();
162166
flagcxCCLAdaptorPluginInit();
167+
(*devHandle) = NULL;
168+
FLAGCXCHECKGOTO(flagcxCalloc(devHandle, 1), res, fail);
169+
**devHandle = globalDeviceHandle;
170+
return flagcxSuccess;
171+
172+
fail:
173+
if (*devHandle) {
174+
free(*devHandle);
175+
*devHandle = NULL;
176+
}
177+
flagcxCCLAdaptorPluginFinalize();
178+
flagcxDeviceAdaptorPluginFinalize();
179+
return res;
180+
}
181+
182+
flagcxResult_t flagcxDeviceHandleFree(flagcxDeviceHandle_t devHandle) {
183+
if (devHandle == NULL)
184+
return flagcxSuccess;
185+
free(devHandle);
186+
flagcxCCLAdaptorPluginFinalize();
187+
flagcxDeviceAdaptorPluginFinalize();
188+
return flagcxSuccess;
189+
}
190+
191+
flagcxResult_t flagcxHandleInit(flagcxHandlerGroup_t *handler) {
192+
flagcxResult_t res = flagcxSuccess;
163193
(*handler) = NULL;
164194
FLAGCXCHECKGOTO(flagcxCalloc(handler, 1), res, fail);
165-
FLAGCXCHECKGOTO(flagcxCalloc(&(*handler)->uniqueId, 1), res, fail);
166-
// comm left NULL — allocated by flagcxCommInitRank
167-
FLAGCXCHECKGOTO(flagcxCalloc(&(*handler)->devHandle, 1), res, fail);
168-
*(*handler)->devHandle = globalDeviceHandle;
195+
FLAGCXCHECKGOTO(flagcxDeviceHandleInit(&(*handler)->devHandle), res, fail);
169196
return flagcxSuccess;
170197

171198
fail:
172199
if (*handler) {
173-
free((*handler)->uniqueId);
174-
free((*handler)->devHandle);
175200
free(*handler);
176201
*handler = NULL;
177202
}
178-
flagcxCCLAdaptorPluginFinalize();
179-
flagcxDeviceAdaptorPluginFinalize();
180203
return res;
181204
}
182205

183206
flagcxResult_t flagcxHandleFree(flagcxHandlerGroup_t handler) {
184207
if (handler != NULL) {
185-
if (handler->uniqueId)
186-
free(handler->uniqueId);
187-
if (handler->devHandle)
188-
free(handler->devHandle);
208+
flagcxDeviceHandleFree(handler->devHandle);
209+
handler->devHandle = NULL;
189210
handler->uniqueId = NULL;
190211
handler->comm = NULL;
191-
handler->devHandle = NULL;
192212
free(handler);
193-
handler = NULL;
194213
}
195-
flagcxCCLAdaptorPluginFinalize();
196-
flagcxDeviceAdaptorPluginFinalize();
197214
return flagcxSuccess;
198215
}
199216

@@ -1180,10 +1197,10 @@ flagcxResult_t flagcxGetVersion(int *version) {
11801197
return flagcxHeteroGetVersion(version);
11811198
}
11821199

1183-
flagcxResult_t flagcxGetUniqueId(flagcxUniqueId_t *uniqueId) {
1184-
// Allocate if caller passed a NULL pointer
1185-
if (*uniqueId == nullptr) {
1186-
FLAGCXCHECK(flagcxCalloc(uniqueId, 1));
1200+
flagcxResult_t flagcxGetUniqueId(flagcxUniqueId_t uniqueId) {
1201+
if (uniqueId == NULL) {
1202+
WARN("flagcxGetUniqueId: uniqueId is NULL");
1203+
return flagcxInvalidArgument;
11871204
}
11881205

11891206
// Init bootstrap net
@@ -1194,9 +1211,9 @@ flagcxResult_t flagcxGetUniqueId(flagcxUniqueId_t *uniqueId) {
11941211
FLAGCXCHECK(bootstrapGetUniqueId(&handle));
11951212
// flagcxUniqueId and bootstrapHandle don't have the same size and alignment
11961213
// reset to 0 to avoid undefined data
1197-
memset((void *)*uniqueId, 0, sizeof(**uniqueId));
1214+
memset((void *)uniqueId, 0, sizeof(*uniqueId));
11981215
// copy to avoid alignment mismatch
1199-
memcpy((void *)*uniqueId, &handle, sizeof(handle));
1216+
memcpy((void *)uniqueId, &handle, sizeof(handle));
12001217
return flagcxSuccess;
12011218
}
12021219

@@ -1523,6 +1540,14 @@ flagcxResult_t flagcxCommInitRank(flagcxComm_t *comm, int nranks,
15231540
WARN("Invalid rank requested : %d/%d", rank, nranks);
15241541
return flagcxInvalidArgument;
15251542
}
1543+
if (commId == NULL || comm == NULL) {
1544+
WARN("flagcxCommInitRank: commId or comm is NULL");
1545+
return flagcxInvalidArgument;
1546+
}
1547+
1548+
// Ensure device/CCL plugins are loaded (idempotent, ref-counted)
1549+
flagcxDeviceAdaptorPluginInit();
1550+
flagcxCCLAdaptorPluginInit();
15261551

15271552
(*comm) = NULL;
15281553
flagcxCalloc(comm, 1);
@@ -1729,7 +1754,8 @@ flagcxResult_t flagcxCommInitRank(flagcxComm_t *comm, int nranks,
17291754
INFO(FLAGCX_INIT, "Flagcx USE_TUNER flag set to %d", useTuner);
17301755
if (useTuner) {
17311756
(*comm)->tuner = &internalTuner;
1732-
(*comm)->commId = commId;
1757+
FLAGCXCHECK(flagcxCalloc(&(*comm)->commId, 1));
1758+
memcpy((*comm)->commId, commId, sizeof(flagcxUniqueId));
17331759
(*comm)->uniqueIdData = uniqueIdData;
17341760
(*comm)->tunerInnerComm = NULL;
17351761
(*comm)->isTunningComm = false;
@@ -2013,13 +2039,18 @@ flagcxResult_t flagcxCommDestroy(flagcxComm_t comm) {
20132039
// Destroy tuner
20142040
if (comm->tuner) {
20152041
comm->tuner->destroy(comm->tunerContext);
2016-
// Free uniqueIdData
2042+
// Free uniqueIdData and commId
20172043
free(comm->uniqueIdData);
2044+
free(comm->commId);
20182045
}
20192046

20202047
// Finalize net adaptor plugin (dlclose)
20212048
FLAGCXCHECK(flagcxNetAdaptorPluginFinalize());
20222049

2050+
// Finalize device/CCL adaptor plugins (ref-counted)
2051+
flagcxCCLAdaptorPluginFinalize();
2052+
flagcxDeviceAdaptorPluginFinalize();
2053+
20232054
free(comm);
20242055
return flagcxSuccess;
20252056
}

flagcx/include/flagcx.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,28 @@ struct flagcxDeviceHandle {
174174
};
175175
typedef struct flagcxDeviceHandle *flagcxDeviceHandle_t;
176176

177+
/* Initialize device handle — loads device/CCL adaptor plugins, returns a
178+
* populated device handle. Call before flagcxCommInitRank if you need device
179+
* operations (setDevice, getDeviceCount, streamCreate, etc.) early.
180+
* If not called explicitly, flagcxCommInitRank will load plugins internally. */
181+
flagcxResult_t flagcxDeviceHandleInit(flagcxDeviceHandle_t *devHandle);
182+
183+
/* Free device handle — finalizes device/CCL adaptor plugins. */
184+
flagcxResult_t flagcxDeviceHandleFree(flagcxDeviceHandle_t devHandle);
185+
186+
/* Deprecated: use flagcxDeviceHandleInit/Free and manage comm/uniqueId
187+
* separately */
177188
struct flagcxHandlerGroup {
178189
flagcxUniqueId_t uniqueId;
179190
flagcxComm_t comm;
180191
flagcxDeviceHandle_t devHandle;
181192
};
182193
typedef struct flagcxHandlerGroup *flagcxHandlerGroup_t;
183194

184-
/* Init and free FlagCX handls including flagcxComm_t, flagcxStream_t */
195+
/* Deprecated: use flagcxDeviceHandleInit instead */
185196
flagcxResult_t flagcxHandleInit(flagcxHandlerGroup_t *handler);
186197

198+
/* Deprecated: use flagcxDeviceHandleFree instead */
187199
flagcxResult_t flagcxHandleFree(flagcxHandlerGroup_t handler);
188200

189201
/* User buffer registration functions. The actual allocated size might
@@ -224,8 +236,9 @@ flagcxResult_t flagcxGetVersion(int *version);
224236

225237
/* Generates an Id to be used in flagcxCommInitRank. flagcxGetUniqueId should be
226238
* called once and the Id should be distributed to all ranks in the
227-
* communicator before calling flagcxCommInitRank. */
228-
flagcxResult_t flagcxGetUniqueId(flagcxUniqueId_t *uniqueId);
239+
* communicator before calling flagcxCommInitRank.
240+
* The caller must provide a valid pointer to a flagcxUniqueId struct. */
241+
flagcxResult_t flagcxGetUniqueId(flagcxUniqueId_t uniqueId);
229242

230243
/* Creates a new communicator (multi thread/process version).
231244
* rank must be between 0 and nranks-1 and unique within a communicator clique.

plugin/interservice/flagcx_wrapper.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
flagcxEventType_t = ctypes.c_int
2222
flagcxIpcMemHandle_t = ctypes.c_void_p
2323

24-
flagcxHandlerGroup_t = ctypes.c_void_p
2524
flagcxComm_t = ctypes.c_void_p
2625
flagcxEvent_t = ctypes.c_void_p
2726
flagcxStream_t = ctypes.c_void_p
@@ -212,15 +211,15 @@ class Function:
212211

213212
class FLAGCXLibrary:
214213
exported_functions = [
215-
Function("flagcxHandleInit", flagcxResult_t,
216-
[ctypes.POINTER(flagcxHandlerGroup_t)]),
217-
Function("flagcxHandleFree", flagcxResult_t,
218-
[flagcxHandlerGroup_t]),
214+
Function("flagcxDeviceHandleInit", flagcxResult_t,
215+
[ctypes.POINTER(flagcxDeviceHandle_t)]),
216+
Function("flagcxDeviceHandleFree", flagcxResult_t,
217+
[flagcxDeviceHandle_t]),
219218
Function("flagcxGetErrorString", ctypes.c_char_p, [flagcxResult_t]),
220219
Function("flagcxGetVersion", flagcxResult_t,
221220
[ctypes.POINTER(ctypes.c_int)]),
222221
Function("flagcxGetUniqueId", flagcxResult_t,
223-
[ctypes.POINTER(ctypes.POINTER(flagcxUniqueId))]),
222+
[ctypes.POINTER(flagcxUniqueId)]),
224223
# Note that flagcxComm_t is a pointer type, so the first argument
225224
# is a pointer to a pointer
226225
Function("flagcxCommInitRank", flagcxResult_t, [
@@ -432,13 +431,13 @@ def __init__(self, so_file: Optional[str] = None):
432431
FLAGCXLibrary.path_to_dict_mapping[so_file] = _funcs
433432
self._funcs = FLAGCXLibrary.path_to_dict_mapping[so_file]
434433

435-
# init flagcx handler to call device-related apis
436-
self.handler = flagcxHandlerGroup_t()
437-
self.FLAGCX_CHECK(self._funcs["flagcxHandleInit"](ctypes.byref(self.handler)))
438-
434+
# init flagcx device handle to call device-related apis
435+
self.devHandle = flagcxDeviceHandle_t()
436+
self.FLAGCX_CHECK(self._funcs["flagcxDeviceHandleInit"](ctypes.byref(self.devHandle)))
437+
439438
def __del__(self):
440-
# free flagcx handler
441-
self.FLAGCX_CHECK(self._funcs["flagcxHandleFree"](self.handler))
439+
# free flagcx device handle
440+
self.FLAGCX_CHECK(self._funcs["flagcxDeviceHandleFree"](self.devHandle))
442441

443442
def flagcxGetErrorString(self, result: flagcxResult_t) -> str:
444443
return self._funcs["flagcxGetErrorString"](result).decode("utf-8")
@@ -459,7 +458,7 @@ def flagcxGetVersion(self) -> str:
459458
return f"{major}.{minor}.{patch}"
460459

461460
def flagcxGetUniqueId(self) -> flagcxUniqueId:
462-
unique_id = ctypes.POINTER(flagcxUniqueId)()
461+
unique_id = flagcxUniqueId()
463462
self.FLAGCX_CHECK(self._funcs["flagcxGetUniqueId"](
464463
ctypes.byref(unique_id)))
465464
return unique_id
@@ -486,7 +485,7 @@ def flagcxCommInitRank(self, world_size: int, unique_id: flagcxUniqueId,
486485
rank: int) -> flagcxComm_t:
487486
comm = flagcxComm_t()
488487
self.FLAGCX_CHECK(self._funcs["flagcxCommInitRank"](ctypes.byref(comm),
489-
world_size, unique_id,
488+
world_size, ctypes.byref(unique_id),
490489
rank))
491490
return comm
492491

@@ -715,26 +714,26 @@ def flagcxDevMemFreeDevicePtr(self, dev_mem: flagcxDevMem_t) -> None:
715714

716715
def adaptor_stream_create(self):
717716
new_stream = flagcxStream_t()
718-
self.FLAGCX_CHECK(self.handler.contents.devHandle.contents.streamCreate(ctypes.byref(new_stream)))
717+
self.FLAGCX_CHECK(self.devHandle.contents.streamCreate(ctypes.byref(new_stream)))
719718
return new_stream
720719

721720
def adaptor_stream_copy(self, old_stream):
722721
new_stream = flagcxStream_t()
723722
raw_stream = getattr(old_stream, 'musa_stream', old_stream.cuda_stream)
724-
self.FLAGCX_CHECK(self.handler.contents.devHandle.contents.streamCopy(ctypes.byref(new_stream), ctypes.c_void_p(raw_stream)))
723+
self.FLAGCX_CHECK(self.devHandle.contents.streamCopy(ctypes.byref(new_stream), ctypes.c_void_p(raw_stream)))
725724
return new_stream
726725

727726
def adaptor_stream_free(self, stream):
728-
self.FLAGCX_CHECK(self.handler.contents.devHandle.contents.streamFree(stream))
727+
self.FLAGCX_CHECK(self.devHandle.contents.streamFree(stream))
729728

730729
def adaptor_stream_destroy(self, stream):
731-
self.FLAGCX_CHECK(self.handler.contents.devHandle.contents.streamDestroy(stream))
730+
self.FLAGCX_CHECK(self.devHandle.contents.streamDestroy(stream))
732731

733732
def sync_stream(self, stream):
734-
self.FLAGCX_CHECK(self.handler.contents.devHandle.contents.streamSynchronize(stream))
733+
self.FLAGCX_CHECK(self.devHandle.contents.streamSynchronize(stream))
735734

736735

737736
__all__ = [
738737
"FLAGCXLibrary", "flagcxDataTypeEnum", "flagcxRedOpTypeEnum", "flagcxUniqueId",
739-
"flagcxHandlerGroup_t", "flagcxComm_t", "flagcxStream_t", "flagcxEvent_t", "buffer_type"
738+
"flagcxDeviceHandle_t", "flagcxComm_t", "flagcxStream_t", "flagcxEvent_t", "buffer_type"
740739
]

0 commit comments

Comments
 (0)