@@ -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+
296312flagcxResult_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
347385flagcxResult_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}
370493flagcxResult_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
390538struct 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