Skip to content

Commit 231e75d

Browse files
authored
[PAL] Update DCU Adaptor (#499)
1 parent 0beba7a commit 231e75d

1 file changed

Lines changed: 177 additions & 29 deletions

File tree

flagcx/adaptor/device/ducuda_adaptor.cc

Lines changed: 177 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,22 @@ flagcxResult_t ducudaAdaptorLaunchHostFunc(flagcxStream_t stream,
293293
return flagcxSuccess;
294294
}
295295

296+
flagcxResult_t ducudaAdaptorDmaSupport(bool *dmaBufferSupport) {
297+
if (dmaBufferSupport == NULL)
298+
return flagcxInvalidArgument;
299+
300+
*dmaBufferSupport = false;
301+
return flagcxSuccess;
302+
}
303+
304+
flagcxResult_t
305+
ducudaAdaptorMemGetHandleForAddressRange(void *handleOut, void *buffer,
306+
size_t size, unsigned long long flags) {
307+
//unsupportted on dcu
308+
return flagcxNotSupported;
309+
}
310+
311+
296312
flagcxResult_t ducudaAdaptorGetDeviceProperties(struct flagcxDevProps *props,
297313
int dev) {
298314
if (props == NULL) {
@@ -331,17 +347,39 @@ flagcxResult_t ducudaAdaptorGetDeviceByPciBusId(int *dev,
331347
return flagcxSuccess;
332348
}
333349

334-
flagcxResult_t ducudaAdaptorStreamWaitValue64(flagcxStream_t, void *, uint64_t,
335-
int) {
336-
return flagcxNotSupported;
337-
}
338-
flagcxResult_t ducudaAdaptorStreamWriteValue64(flagcxStream_t, void *, uint64_t,
339-
int) {
340-
return flagcxNotSupported;
341-
}
342-
flagcxResult_t ducudaAdaptorEventElapsedTime(float *, flagcxEvent_t,
343-
flagcxEvent_t) {
344-
return flagcxNotSupported;
350+
flagcxResult_t ducudaAdaptorStreamWaitValue64(flagcxStream_t stream, void *addr,
351+
uint64_t value, int flags) {
352+
(void)flags;
353+
if (stream == NULL || addr == NULL)
354+
return flagcxInvalidArgument;
355+
CUstream cuStream = (CUstream)(stream->base);
356+
CUresult err = cuStreamWaitValue64(cuStream, (CUdeviceptr)addr, value,
357+
CU_STREAM_WAIT_VALUE_GEQ);
358+
return (err == CUDA_SUCCESS) ? flagcxSuccess : flagcxUnhandledDeviceError;
359+
}
360+
flagcxResult_t ducudaAdaptorStreamWriteValue64(flagcxStream_t stream, void *addr,
361+
uint64_t value, int flags) {
362+
(void)flags;
363+
if (stream == NULL || addr == NULL)
364+
return flagcxInvalidArgument;
365+
CUstream cuStream = (CUstream)(stream->base);
366+
CUresult err = cuStreamWriteValue64(cuStream, (CUdeviceptr)addr, value,
367+
CU_STREAM_WRITE_VALUE_DEFAULT);
368+
return (err == CUDA_SUCCESS) ? flagcxSuccess : flagcxUnhandledDeviceError;
369+
}
370+
flagcxResult_t ducudaAdaptorEventElapsedTime(float *ms, flagcxEvent_t start,
371+
flagcxEvent_t end) {
372+
if (ms == NULL || start == NULL || end == NULL) {
373+
return flagcxInvalidArgument;
374+
}
375+
cudaError_t error = cudaEventElapsedTime(ms, start->base, end->base);
376+
if (error == cudaSuccess) {
377+
return flagcxSuccess;
378+
} else if (error == cudaErrorNotReady) {
379+
return flagcxInProgress;
380+
} else {
381+
return flagcxUnhandledDeviceError;
382+
}
345383
}
346384

347385
flagcxResult_t ducudaAdaptorHostRegister(void *ptr, size_t size) {
@@ -355,36 +393,146 @@ flagcxResult_t ducudaAdaptorHostUnregister(void *ptr) {
355393
}
356394

357395
// Symmetric memory VMM stubs (not supported)
358-
flagcxResult_t ducudaAdaptorSymPhysAlloc(void *, size_t, void **, void *,
359-
size_t *, size_t *) {
360-
return flagcxNotSupported;
396+
flagcxResult_t ducudaAdaptorSymPhysAlloc(void *ptr, size_t size,
397+
void **physHandle, void *shareableHandle,
398+
size_t *handleSize, size_t *allocSize) {
399+
if (ptr == NULL || physHandle == NULL || shareableHandle == NULL ||
400+
handleSize == NULL || allocSize == NULL)
401+
return flagcxInvalidArgument;
402+
403+
CUmemGenericAllocationHandle *cuHandle =
404+
(CUmemGenericAllocationHandle *)malloc(
405+
sizeof(CUmemGenericAllocationHandle));
406+
if (cuHandle == NULL)
407+
return flagcxSystemError;
408+
409+
// Retain the physical allocation handle from the VMM-backed pointer
410+
DEVCHECK(cuMemRetainAllocationHandle(cuHandle, ptr));
411+
412+
// Discover actual physical allocation size (already granularity-aligned)
413+
size_t actualAllocSize = 0;
414+
DEVCHECK(cuMemGetAddressRange(NULL, &actualAllocSize, (CUdeviceptr)ptr));
415+
*allocSize = actualAllocSize;
416+
417+
// Export as POSIX fd for IPC sharing
418+
if (*handleSize < sizeof(int)) {
419+
free(cuHandle);
420+
return flagcxInvalidArgument;
421+
}
422+
DEVCHECK(cuMemExportToShareableHandle(
423+
shareableHandle, *cuHandle, CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR, 0));
424+
*handleSize = sizeof(int); // POSIX fd is an int
425+
*physHandle = cuHandle;
426+
return flagcxSuccess;
361427
}
362-
flagcxResult_t ducudaAdaptorSymPhysFree(void *) { return flagcxNotSupported; }
363-
flagcxResult_t ducudaAdaptorSymFlatMap(void *[], int, int, void *, size_t,
364-
void **) {
365-
return flagcxNotSupported;
428+
flagcxResult_t ducudaAdaptorSymPhysFree(void *physHandle) {
429+
if (physHandle == NULL)
430+
return flagcxSuccess;
431+
CUmemGenericAllocationHandle *cuHandle =
432+
(CUmemGenericAllocationHandle *)physHandle;
433+
cuMemRelease(*cuHandle);
434+
free(cuHandle);
435+
return flagcxSuccess;
366436
}
367-
flagcxResult_t ducudaAdaptorSymFlatUnmap(void *, size_t, int) {
368-
return flagcxNotSupported;
437+
flagcxResult_t ducudaAdaptorSymFlatMap(void *peerHandles[], int nPeers,
438+
int selfIndex, void *selfPhysHandle,
439+
size_t allocSize, void **flatBase) {
440+
if (peerHandles == NULL || selfPhysHandle == NULL || flatBase == NULL ||
441+
nPeers <= 0 || allocSize == 0)
442+
return flagcxInvalidArgument;
443+
444+
CUmemGenericAllocationHandle selfHandle =
445+
*(CUmemGenericAllocationHandle *)selfPhysHandle;
446+
447+
// allocSize is already granularity-aligned (from cuMemGetAddressRange)
448+
size_t totalSize = allocSize * nPeers;
449+
450+
// Reserve the full VA range
451+
CUdeviceptr base = 0;
452+
DEVCHECK(cuMemAddressReserve(&base, totalSize, 0, 0, 0));
453+
454+
// Import and map each peer's physical memory
455+
int cudaDev;
456+
DEVCHECK(cudaGetDevice(&cudaDev));
457+
CUmemAccessDesc accessDesc = {};
458+
accessDesc.location.type = CU_MEM_LOCATION_TYPE_DEVICE;
459+
accessDesc.location.id = cudaDev;
460+
accessDesc.flags = CU_MEM_ACCESS_FLAGS_PROT_READWRITE;
461+
462+
for (int i = 0; i < nPeers; i++) {
463+
CUmemGenericAllocationHandle peerHandle;
464+
if (i == selfIndex) {
465+
peerHandle = selfHandle;
466+
} else {
467+
int fd = *(int *)peerHandles[i];
468+
DEVCHECK(cuMemImportFromShareableHandle(
469+
&peerHandle, (void *)(uintptr_t)fd,
470+
CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR));
471+
}
472+
CUdeviceptr slot = base + (CUdeviceptr)i * allocSize;
473+
DEVCHECK(cuMemMap(slot, allocSize, 0, peerHandle, 0));
474+
DEVCHECK(cuMemSetAccess(slot, allocSize, &accessDesc, 1));
475+
if (i != selfIndex) {
476+
cuMemRelease(peerHandle);
477+
}
478+
}
479+
480+
*flatBase = (void *)base;
481+
return flagcxSuccess;
482+
}
483+
flagcxResult_t ducudaAdaptorSymFlatUnmap(void *flatBase, size_t allocSize,
484+
int nPeers) {
485+
if (flatBase == NULL)
486+
return flagcxSuccess;
487+
CUdeviceptr base = (CUdeviceptr)flatBase;
488+
size_t totalSize = allocSize * nPeers;
489+
DEVCHECK(cuMemUnmap(base, totalSize));
490+
DEVCHECK(cuMemAddressFree(base, totalSize));
491+
return flagcxSuccess;
369492
}
370493
flagcxResult_t ducudaAdaptorSymMulticastSupported(int *supported) {
494+
// not supported on dcu
495+
if (supported == NULL)
496+
return flagcxInvalidArgument;
497+
371498
if (supported)
372499
*supported = 0;
373500
return flagcxSuccess;
374501
}
375-
flagcxResult_t ducudaAdaptorSymMulticastCreate(size_t, int, const int *,
376-
void **, int *) {
502+
flagcxResult_t ducudaAdaptorSymMulticastCreate(size_t allocSize,
503+
int nLocalDevices,
504+
const int *localDeviceOrdinals,
505+
void **mcHandle,
506+
int *shareableFd) {
507+
// not supported on dcu
508+
if (mcHandle)
509+
*mcHandle = NULL;
510+
511+
if (shareableFd)
512+
*shareableFd = -1;
513+
377514
return flagcxNotSupported;
378515
}
379-
flagcxResult_t ducudaAdaptorSymMulticastBind(void *, int, void *, size_t, int,
380-
int, void **, size_t *) {
516+
flagcxResult_t ducudaAdaptorSymMulticastBind(void *mcHandle, int importFd,
517+
void *physHandle, size_t allocSize,
518+
int localRank, int nLocalDevices,
519+
void **mcBase, size_t *mcMapSize) {
520+
// not supported on dcu
521+
if (mcBase)
522+
*mcBase = NULL;
523+
524+
if (mcMapSize)
525+
*mcMapSize = 0;
526+
381527
return flagcxNotSupported;
382528
}
383-
flagcxResult_t ducudaAdaptorSymMulticastTeardown(void *, size_t) {
529+
flagcxResult_t ducudaAdaptorSymMulticastTeardown(void *mcBase, size_t mcMapSize) {
530+
// not supported on dcu
384531
return flagcxSuccess;
385532
}
386-
flagcxResult_t ducudaAdaptorSymMulticastFree(void *) {
387-
return flagcxNotSupported;
533+
flagcxResult_t ducudaAdaptorSymMulticastFree(void *mcHandle) {
534+
// not supported on dcu
535+
return flagcxSuccess;
388536
}
389537

390538
struct flagcxDeviceAdaptor ducudaAdaptor {
@@ -442,8 +590,8 @@ struct flagcxDeviceAdaptor ducudaAdaptor {
442590
// *dev, const char *pciBusId);
443591
ducudaAdaptorLaunchHostFunc,
444592
// DMA buffer
445-
NULL, // flagcxResult_t (*dmaSupport)(bool *dmaBufferSupport);
446-
NULL, // flagcxResult_t (*memGetHandleForAddressRange)(void *handleOut,
593+
ducudaAdaptorDmaSupport, // flagcxResult_t (*dmaSupport)(bool *dmaBufferSupport);
594+
ducudaAdaptorMemGetHandleForAddressRange, // flagcxResult_t (*memGetHandleForAddressRange)(void *handleOut,
447595
// void *buffer, size_t size, unsigned long long flags);
448596
ducudaAdaptorHostRegister, // flagcxResult_t (*hostRegister)(void *,
449597
// size_t);

0 commit comments

Comments
 (0)